设计模式(三)——装饰模式

1.描述

动态的给对象添加一些额外的职责。就功能来说,装饰模式比生成子类更为灵活。

2.优点

·被装饰者和装饰者之间是松耦合关系

·装饰者模式满足“开闭原则”

·可以使用多个具体装饰来装饰具体组件的实例。

3.用途

·程序动态的增强类的某个对象的功能,而又不影响该类的其他对象。

·采用继承阿里增强对象不利于程序的维护和扩展。

4.模式的使用

·抽象组件(Component):抽象组件是一个抽象类。抽象组件定义了“被装饰者”需要进行“装饰”的方法。

·具体装饰(ConcreteComponent):具体组件是抽象组件的一个子类具体组件的实例称作“被装饰者”。

·装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包含一个抽象组件声明的变量以保存“被装饰者”的引用。装饰可以使抽象类也可以是非抽象类,如果是非抽象类,那么该类的实例称作“装饰者”。

·具体装饰(ConcreteDecotator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称作“装饰者”。

5.UML图

6.案例

案例一:

鸟(Bird)类中的麻雀实例,其中的fiy()方法可以飞行100米,现在需要能飞行150、200米的麻雀类。不能使用继承的方式生成麻雀类的子类。(降低耦合度)

代码:

 1 package 装饰模式.test1;
 2 
 3 public class test1 {
 4     public static void needBird(Bird bird){
 5         int flyDistance = bird.fly();
 6         System.out.println("这只鸟能飞" + flyDistance + "米");
 7     }
 8     public static void main(String[] args) {
 9         Bird sparrow = new Sparrow(); //这只鸟只能飞100米
10         Bird sparrowDecorator1 = new SparrowDecorator(sparrow); //装饰之后,这只鸟能飞150米
11         Bird sparrowDecorator2 = new SparrowDecorator(sparrowDectorator1); //装饰之后,这只鸟能飞200米
12         needBird(sparrow);
13         needBird(sparrowDecorator1);
14         needBird(sparrowDecorator2);
15     }
16 
17 }
18 
19 /**
20  * 抽象组件
21  */
22 abstract class Bird{
23     public abstract int fly();
24 }
25 
26 /*
27  * 具体组件
28  */
29 class Sparrow extends Bird{
30     public final int DISTANCE = 100;
31 
32     @Override
33     public int fly() {
34         return DISTANCE;
35     }
36     
37 }
38 
39 /*
40  * 装饰
41  */
42 abstract class Decorator extends Bird{
43     protected Bird bird;
44     public Decorator(){}
45     public Decorator(Bird bird){
46         this.bird = bird;
47     }
48 }
49 
50 /*
51  * 具体装饰
52  */
53 class SparrowDecorator extends Decorator{
54     public final int DISTANCE = 50;
55     SparrowDectorator(Bird bird){ 
56         super(bird);
57     }
58     public int fly() {
59         int distance = 0;
60         distance = bird.fly() + eleFly();  //委托被装饰者bird调用fly()方法,然后再调用eleFly()方法
61         return distance;
62     }
63     
64     private int eleFly(){  //装饰者新添加的方法
65         return DISTANCE;
66     }
67 }
68 

案例二:使用多个装饰者

现在需要能飞行120、150、170的麻雀类

在实现一个具体装饰2(SparrowDecoratpr2)

 1 class SparrowDecorator2 extends Decorator{
 2     public final int DISTANCE = 20; //eleFly()方法飞20米
 3     SparrowDecorator2(Bird bird){ 
 4         super(bird);
 5     }
 6     public int fly() {
 7         int distance = 0;
 8         distance = bird.fly() + eleFly();  //委托被装饰者bird调用fly()方法,然后再调用eleFly()方法
 9         return distance;
10     }
11     
12     private int eleFly(){  //装饰者新添加的方法
13         return DISTANCE;
14     }
15 }

主函数改为

 1 public static void main(String[] args) {
 2         Bird sparrow = new Sparrow(); //这只鸟只能飞100米
 3         Bird sparrowDecorator1 = new SparrowDecorator(sparrow); //装饰之后,这只鸟能飞150米
 4         Bird sparrowDecorator2 = new SparrowDecorator(sparrow); //装饰之后,这只鸟能飞120米
 5         Bird sparrowDecorator3 = new SparrowDecorator2(sparrowDecorator1); //装饰之后,这只鸟能飞170米。
 6         needBird(sparrow);
 7         needBird(sparrowDecorator1);
 8         needBird(sparrowDecorator2);
 9         needBird(sparrowDecorator3);
10     }

 

原文地址:https://www.cnblogs.com/cxy2016/p/7569599.html