全国咨询/投诉热线:400-618-4000

Java装饰者模式

更新时间:2018年10月19日16时53分 来源:传智播客 浏览次数:

装饰者模式目标
把许多要实现的功能,加载在子类上,类的继承,显得很臃肿,装饰着模式是在不改变原有类文件和使用继承的情况下,通过创建一个包装对象动态地扩展一个对象的功能,相比生成子类更为灵活
装饰模式的结构 
在装饰模式中的角色有:
  ●  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  ●  具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
  ●  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  ●  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任
源代码
抽象构件角色
[Java] 纯文本查看 复制代码
1
2
3
4
5
public interface Component {
    
    public void sampleOperation();
    
}

具体构件角色
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
public class ConcreteComponent implements Component {
    @Override
    public void sampleOperation() {
        // 写相关的业务代码
    }
}

装饰角色
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
public class Decorator implements Component{
    private Component component;
    
    public Decorator(Component component){
        this.component = component;
    }
    @Override
    public void sampleOperation() {
        // 委派给构件
        component.sampleOperation();
    }
    
}

 具体装饰角色
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    
    @Override
    public void sampleOperation() {
     super.sampleOperation();
        // 写相关的业务代码
    }
}

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }
    
    @Override
    public void sampleOperation() {
      super.sampleOperation();
        // 写相关的业务代码
    }
}

齐天大圣的例子
孙悟空有七十二般变化,他的每一种变化都给他带来一种附加的本领。他变成鱼儿时,就可以到水里游泳;他变成鸟儿时,就可以在天上飞行。
  本例中,Component的角色便由鼎鼎大名的齐天大圣扮演;ConcreteComponent的角色属于大圣的本尊,就是猢狲本人;Decorator的角色由大圣的七十二变扮演。而ConcreteDecorator的角色便是鱼儿、鸟儿等七十二般变化
源代码
抽象构件角色“齐天大圣”接口定义了一个move()方法,这是所有的具体构件类和装饰类必须实现的。
[Java] 纯文本查看 复制代码
1
2
3
4
5
//大圣的尊号
public interface TheGreatestSage {
    
    public void move();
}

具体构件角色“大圣本尊”猢狲类
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
public class Monkey implements TheGreatestSage {
    @Override
    public void move() {
        //代码
        System.out.println("Monkey Move");
    }
}

抽象装饰角色“七十二变”
[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
public class Change implements TheGreatestSage {
    private TheGreatestSage sage;
    
    public Change(TheGreatestSage sage){
        this.sage = sage;
    }
    @Override
    public void move() {
        // 代码
        sage.move();
    }
}

 具体装饰角色“鱼儿”
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
public class Fish extends Change {
    
    public Fish(TheGreatestSage sage) {
        super(sage);
    }
    @Override
    public void move() {
        // 代码
        System.out.println("Fish Move");
    }
}

具体装饰角色“鸟儿”
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
public class Bird extends Change {
    
    public Bird(TheGreatestSage sage) {
        super(sage);
    }
    @Override
    public void move() {
        // 代码
        System.out.println("Bird Move");
    }
}

客户端类
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
public class Client {
    public static void main(String[] args) {
        TheGreatestSage sage = new Monkey();
        // 第一种写法
        TheGreatestSage bird = new Bird(sage);
        TheGreatestSage fish = new Fish(bird);
        // 第二种写法
        //TheGreatestSage fish = new Fish(new Bird(sage));
        fish.move();
    }
}

“大圣本尊”是ConcreteComponent类,而“鸟儿”、“鱼儿”是装饰类。要装饰的是“大圣本尊”,也即“猢狲”实例。
  上面的例子中,系统把大圣从一只猢狲装饰成了一只鸟儿(把鸟儿的功能加到了猢狲身上),然后又把鸟儿装饰成了一条鱼儿(把鱼儿的功能加到了猢狲+鸟儿身上,得到了猢狲+鸟儿+鱼儿)。
如上图所示,大圣的变化首先将鸟儿的功能附加到了猢狲身上,然后又将鱼儿的功能附加到猢狲+鸟儿身上。
设计模式在JAVA I/O库中的应用
装饰模式在Java语言中的最著名的应用莫过于Java I/O标准库的设计了。
  由于Java I/O库需要很多性能的各种组合,如果这些性能都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量性能重复的类出现。而如果采用装饰模式,那么类的数目就会大大减少,性能的重复也可以减至最少。因此装饰模式是Java I/O库的基本模式。
  Java I/O库的对象结构图如下,由于Java I/O的对象众多,因此只画出InputStream的部分。
根据上图可以看出:
  ●  抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。
  ●  具体构件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等类扮演。它们实现了抽象构件角色所规定的接口。
  ●  抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。
  ●  具体装饰(ConcreteDecorator)角色:由几个类扮演,分别是BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream。

作者:传智播客JavaEE培训学院
首发:http://java.itcast.cn/

javaee

python

web

ui

cloud

test

c

netmarket

pm

Linux

movies

robot

uids

北京校区

    14天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    8天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    0天免费试学

    基础班入门课程限时免费

    申请试学名额

    12天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    10天免费试学

    基础班入门课程限时免费

    申请试学名额