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 }