java设计模式-装饰模式

模式导读:

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

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

参考类图:

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 //将共同的特征抽取出来  ->swim,fly,ai
 2 public class Feature {
 3 
 4     // 私有化构造器
 5     private Feature() {
 6 
 7     }
 8 
 9     // 可以潜水
10     public static void swim() {
11         System.out.println("具备潜水功能");
12     }
13 
14     // 可以飞
15     public static void fly() {
16         System.out.println("具备飞行功能");
17     }
18 
19     // 可以人工智能
20     public static void ai() {
21         System.out.println("具备人工智能");
22     }
23 }

5.具体装饰角色类

 1 public class SwimCar extends Decorator {
 2 
 3     public SwimCar(AbstractCar car) {
 4         super(car);
 5     }
 6 
 7     // 重写父类的方法,给车增加swim()的功能
 8     public void move() {
 9         super.move();
10         Feature.swim();
11     }
12 }
 1 public class SwimFlyCar extends Decorator {
 2 
 3     public SwimFlyCar(AbstractCar car) {
 4         super(car);
 5     }
 6 
 7     // 重写父类的方法,给车增加fly(),swim()的功能
 8     public void move() {
 9         super.move();
10         Feature.fly();
11         Feature.swim();
12     }
13 }
 1 //具体的装饰角色
 2 public class FlyCar extends Decorator {
 3 
 4     public FlyCar(AbstractCar car) {
 5         super(car);
 6     }
 7 
 8     // 重写父类的方法,给车增加fly()的功能
 9     public void move() {
10         super.move();
11         Feature.fly();
12     }
13 }
 1 public class AICar extends Decorator {
 2 
 3     public AICar(AbstractCar car) {
 4         super(car);
 5     }
 6 
 7     // 重写父类的方法,给车增加AI()的功能
 8     public void move() {
 9         super.move();
10         Feature.ai();
11     }
12 }

6.客户端类

 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 }

效果截图:

装饰模式的优缺点:

优点:

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

缺点:

多层装饰比较复杂。

适用场景:

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

原文地址:https://www.cnblogs.com/weekstart/p/decarator.html