每天开心一点

Java 反射(reflection)/注释(Annotation)/监听器(Listener)/装饰器(wrapper)/过滤器(Filter)(四)

2018-01-10 09:01:00    六月    1226    来源: https://www.2cto.com/kf/201708/665618.html

四 装饰器(wrapper)

4.1 作用

Wrapper在Java中指八个和基本数据类型对应的类(Wrapper Class),有些地方也翻译为外覆类或数据类型类。

对于包装类说,这些类的用途主要包含两种:

a、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。

b、包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法

Wrapper在Java中也指设计模式——装饰器,装饰模式(Decorator)也叫包装器模式(Wrapper)。GOF在《设计模式》一书中给出的定义为:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。装饰模式以对客户端透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。

4.2 实现原理

对于装饰模式作如下解释:

装饰模式的角色

抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。

具体构件角色(Concrete Component):定义将要接收附加责任的类。

装饰角色(Decorator):持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。

具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任。

对于一个接口Component的定义如下:

?
1
2
3
4
5
publicinterfaceComponent
{
    publicvoiddoSomething();
  
}

接口的具体实现如下:

?
1
2
3
4
5
6
7
8
9
10
publicclassConcreteComponentimplementsComponent
{
  
    @Override
    publicvoiddoSomething()
    {
        System.out.println("功能A");
    }
  
}

装饰角色:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
publicclassDecoratorimplementsComponent
{
    privateComponent component;
  
    publicDecorator(Component component)
    {
        this.component = component;
    }
  
    @Override
    publicvoiddoSomething()
    {
  
        component.doSomething();
    }
  
}

其中包含了构件角色的引用,方法调用中利用构件角色的方法。

具体装饰角色(两个):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
publicclassConcreteDecorator1extendsDecorator
{
    publicConcreteDecorator1(Component component)
    {
        super(component);
    }
     
    @Override
    publicvoiddoSomething()
    {
        super.doSomething();
         
        this.doAnotherThing();
    }
     
    privatevoiddoAnotherThing()
    {
        System.out.println("功能B");
    }
  
}
publicclassConcreteDecorator2extendsDecorator
{
    publicConcreteDecorator2(Component component)
    {
        super(component);
    }
    @Override
    publicvoiddoSomething()
    {
        super.doSomething();
         
        this.doAnotherThing();
    }
     
    privatevoiddoAnotherThing()
    {
        System.out.println("功能C");
    }
  
}

使用测试如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
publicclassClient
{
    publicstaticvoidmain(String[] args)
    {
        Component component =newConcreteComponent();
         
        Component component1 =newConcreteDecorator1(component);
         
        component1.doSomething();
        System.out.println("-----------");
         
        Component component2 =newConcreteDecorator2(component1);
         
        component2.doSomething();
    }
  
}

4.3 应用场景

Java I/O

4.4 示例

Java的IO操作也是装饰模式的集中体现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
packagecn.gacl.test;
  
importjava.io.*;
  
publicclassTestBufferStream {
    publicstaticvoidmain(String args[]) {
        FileInputStream fis =null;
        try{
            fis =newFileInputStream("D:/java/TestFileInputStream.java");
            // 在FileInputStream节点流的外面套接一层处理流BufferedInputStream
            BufferedInputStream bis =newBufferedInputStream(fis);
            intc =0;
            System.out.println((char) bis.read());
            System.out.println((char) bis.read());
            bis.mark(100);// 在第100个字符处做一个标记
            for(inti =0; i <=10&& (c = bis.read()) != -1; i++) {
                System.out.print((char) c);
            }
            System.out.println();
            bis.reset();// 重新回到原来标记的地方
            for(inti =0; i <=10&& (c = bis.read()) != -1; i++) {
                System.out.print((char) c);
            }
            bis.close();
        }catch(FileNotFoundException e) {
            e.printStackTrace();
        }catch(Exception e1) {
            e1.printStackTrace();
        }
    }
}
packagecn.galc.test;
  
importjava.io.*;
  
publicclassTestFileOutputStream {
    publicstaticvoidmain(String args[]) {
        intb =0;
        FileInputStream in =null;
        FileOutputStream out =null;
        try{
            in =newFileInputStream("D:JavaMyEclipse 10WorkspacesAnnotationTestsrccngalctestMyMouseAdapter.java");
            out =newFileOutputStream("D:/java/TestFileOutputStream1.java");
            // 指明要写入数据的文件,如果指定的路径中不存在TestFileOutputStream1.java这样的文件,则系统会自动创建一个
            while((b = in.read()) != -1) {
                out.write(b);
                // 调用write(int c)方法把读取到的字符全部写入到指定文件中去
            }
            in.close();
            out.close();
        }catch(FileNotFoundException e) {
            System.out.println("文件读取失败");
            System.exit(-1);// 非正常退出
        }catch(IOException e1) {
            System.out.println("文件复制失败!");
            System.exit(-1);
        }
        System.out
                .println("TestFileInputStream.java文件里面的内容已经成功复制到文件TestFileOutStream1.java里面");
    }
}

转载:https://www.cnblogs.com/xdp-gacl/p/3634409.html