模式导读:

    给你一个没装修的房子,让你利用自己的艺术细菌去想象如何去让自己的房子更加漂亮,更加完美。这就需要我们慢慢去思考了...通过动态的给一个对象增加新的功能,使无需通过继承的方式增加子类既能够扩展对象功能,使用对象的关联关系代替继承关系,更加灵活,同时类型体系的快速膨胀。至于使用继承关系实现为什么膨胀,看下面这张图你就清楚了。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

java设计模式-装饰模式 随笔 第1张

很明显,如果对象的功能开始复杂起来时,我们需要重新定义一个新的对象来实现,这就增加了更多地子类,所以膨胀了。

参考类图:

java设计模式-装饰模式 随笔 第2张

1.Component抽象构件角色:使真实对象和装饰对象有相同的接口,这样,客户端对象就能够以真实对象相同的方式同装饰对象交互。
2.ConcretComponent具体构件角色(真实对象):如io流中的FileInputStream,FileOutputStream。
3.Decorator装饰角色:持有一个抽象构件的引用,装饰对象接收所有的客户端的请求,并把这些请求转发给真实的对象,这样就能够在真实对象调用前后增加新的功能。
4.ConcretDecorator具体装饰角色:负责给构件对象增加新的责任。
代码实现:

1.抽象构件类

1 package com.etc;
2 //抽象构件角色
3 public interface AbstractCar {
4      void move();
5 }

2.具体构件类

 1 package com.etc;
 2 //具体构件角色
 3 public class Car implements AbstractCar{
 4 
 5     @Override
 6     public void move() {
 7         System.out.println("**正常由人操控陆地行驶!**");
 8     }
 9 
10 }

3.装饰者角色类

 1 package com.etc;
 2 //装饰角色,将传入的不同请求转发给真实对象
 3 public class Decorator implements AbstractCar{
 4     private AbstractCar car;
 5     //构造器,用于接收具体的装饰子对象
 6     public Decorator(AbstractCar car) {
 7         super();
 8         this.car = car;
 9     }
10     @Override
11     public void move() {
12         car.move();
13     }
14 
15 }

4.具体装饰角色类

 1 package com.etc;
 2 //具体的装饰角色
 3 public class FlyCar extends Decorator{
 4 
 5     public FlyCar(AbstractCar car) {
 6         super(car);
 7     }
 8     public void fly() {
 9         System.out.println("-->拥有在天上飞行的功能!");
10     }
11     //重写父类的方法,给车增加fly()的功能
12     public void move() {
13         super.move();
14         fly();
15     }
16 }
 1 package com.etc;
 2 
 3 public class SwimCar extends Decorator{
 4 
 5     public SwimCar(AbstractCar car) {
 6         super(car);
 7     }
 8     public void swim() {
 9         System.out.println("-->拥有在水中潜行的功能!");
10     }
11     //重写父类的方法,给车增加swim()的功能
12     public void move() {
13         super.move();
14         swim();
15     }
16 }
 1 package com.etc;
 2 
 3 public class SwimFlyCar extends Decorator{
 4 
 5     public SwimFlyCar(AbstractCar car) {
 6         super(car);
 7     }
 8     public void fly() {
 9         System.out.println("-->拥有在天上飞行的功能!");
10     }
11     public void swim() {
12         System.out.println("-->拥有在水中潜行的功能!");
13     }
14      //重写父类的方法,给车增加fly(),swim()的功能
15     public void move() {
16         super.move();
17         swim();
18         fly();
19     }
20 }
 1 package com.etc;
 2 
 3 public class AICar extends Decorator{
 4 
 5     public AICar(AbstractCar car) {
 6         super(car);
 7     }
 8     public void AI() {
 9         System.out.println("-->拥有由人工智能控制的功能!");
10     }
11     //重写父类的方法,给车增加AI()的功能
12     public void move() {
13         super.move();
14         AI();
15     }
16 }

5.客户端类

 1 package com.etc;
 2 //根据情景需要给车增加不同的功能
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         //让车增加可以飞的功能
 7         Car car=new Car();
 8         FlyCar flyCar=new FlyCar(car);
 9         flyCar.move();
10         //让车增加可以潜水的功能
11         SwimCar swimCar=new SwimCar(car);
12         swimCar.move();
13         //让车增加可以潜水,飞的功能
14         SwimFlyCar sfCar=new SwimFlyCar(car);
15         sfCar.move();
16     }
17 
18 }

效果截图:

java设计模式-装饰模式 随笔 第3张

装饰模式的优缺点:

优点:

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:

多层装饰比较复杂。

适用场景:

1、扩展一个类的功能。
2、动态增加功能,动态撤销。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄