装饰者设计模式:
简单定义:增强一个类的功能,而且还可以让这些装饰类互相装饰。
应用场景:当要在某个功能的基础上扩充功能,并且扩充的功能具有大量排列组合,通过继承关系会衍生出大量子类,这时候用装饰者模式来解决。
装饰者设计模式的步骤:
1. 在装饰类的内部维护一个被装饰类的引用。
2. 让装饰类有一个共同的父类或者是父接口。
例如:人有一种行为叫“吃水果”,其中水果有4种:苹果、香蕉、鸭梨、橘子
现在有需求如下:
A类人行为:吃苹果
B类人行为:先吃苹果,再吃香蕉
C类人行为:先吃香蕉,再吃苹果
D类人行为:先吃橘子,后吃鸭梨
我们先用子类继承来实现:代码如下
1 interface IEatFruit{ 2 public void eatFruit(); 3 } 4 5 class PersonA implements IEatFruit{ 6 7 @Override 8 public void eatFruit() { 9 System.out.println("吃苹果"); 10 } 11 12 } 13 class PersonB implements IEatFruit{ 14 15 @Override 16 public void eatFruit() { 17 System.out.println("吃苹果"); 18 System.out.println("吃香蕉"); 19 } 20 21 } 22 class PersonC implements IEatFruit{ 23 24 @Override 25 public void eatFruit() { 26 System.out.println("吃香蕉"); 27 System.out.println("吃苹果"); 28 } 29 30 } 31 class PersonD implements IEatFruit{ 32 33 @Override 34 public void eatFruit() { 35 System.out.println("吃橘子"); 36 System.out.println("吃鸭梨"); 37 } 38 39 }
这样当然是没问题的,每一类人对应new出来的对象 都可以实现对应的需求。
但是,当需求改为:
某类人行为:吃上面四种水果,并且要求有先后顺序
这样的排列组合有24种....
这样你还会用继承去做吗?写24个子类去实现接口,明显不合适。
这时候如果用到装饰者模式,代码则会变成:
1 interface IEatFruit{ 2 public void eatFruit(); 3 } 4 5 class PersonA implements IEatFruit{ 6 IEatFruit eat; 7 public PersonA(){ 8 this.eat = this; 9 } 10 public PersonA(IEatFruit _eat){ 11 this.eat = _eat; 12 } 13 @Override 14 public void eatFruit() { 15 if(!(this.eat instanceof PersonA)){ 16 this.eat.eatFruit(); 17 System.out.println("吃苹果"); 18 }else{ 19 System.out.println("吃苹果"); 20 } 21 } 22 23 } 24 class PersonB implements IEatFruit{ 25 IEatFruit eat; 26 public PersonB(){ 27 this.eat = this; 28 } 29 public PersonB(IEatFruit _eat){ 30 this.eat = _eat; 31 } 32 @Override 33 public void eatFruit() { 34 if(!(this.eat instanceof PersonB)){ 35 this.eat.eatFruit(); 36 System.out.println("吃香蕉"); 37 }else{ 38 System.out.println("吃香蕉"); 39 } 40 } 41 42 } 43 class PersonC implements IEatFruit{ 44 IEatFruit eat; 45 public PersonC(){ 46 this.eat = this; 47 } 48 public PersonC(IEatFruit _eat){ 49 this.eat = _eat; 50 } 51 @Override 52 public void eatFruit() { 53 if(!(this.eat instanceof PersonC)){ 54 this.eat.eatFruit(); 55 System.out.println("吃鸭梨"); 56 }else{ 57 System.out.println("吃鸭梨"); 58 } 59 } 60 61 } 62 class PersonD implements IEatFruit{ 63 IEatFruit eat; 64 public PersonD(){ 65 this.eat = this; 66 } 67 public PersonD(IEatFruit _eat){ 68 this.eat = _eat; 69 } 70 @Override 71 public void eatFruit() { 72 if(!(this.eat instanceof PersonD)){ 73 this.eat.eatFruit(); 74 System.out.println("吃橘子"); 75 }else{ 76 System.out.println("吃橘子"); 77 } 78 } 79 80 } 81 82 83 84 public class Demo2 { 85 86 public static void main(String[] args) { 87 //这样就可以通过上述4类人来相互装饰,就可以随意任意一种组合“吃水果” 88 //如:吃橘子->吃苹果 89 PersonD d = new PersonD(); 90 PersonA a = new PersonA(d); 91 a.eatFruit(); 92 System.out.println("-------我是分割线------------"); 93 //如:吃苹果->吃橘子->吃鸭梨->吃香蕉 94 PersonA a2 = new PersonA(); 95 PersonD d2 = new PersonD(a2); 96 PersonC c2 = new PersonC(d2); 97 PersonB b2 = new PersonB(c2); 98 b2.eatFruit(); 99 } 100 101 }
输出结果如下:
吃橘子
吃苹果
-------我是分割线------------
吃苹果
吃橘子
吃鸭梨
吃香蕉
最后总结:
继承实现的增强类和修饰模式实现的增强类有何区别?
继承实现的增强类:
优点:代码结构清晰,而且实现简单.
缺点:对于每一个的需要增强的类都要创建具体的子类来帮助其增强,这样会导致
继承体系过于庞大。
装饰者模式实现的增强类:
优点:内部可以通过多态技术对多个需要增强的类进行增强, 可以使这些装饰类
达到互相装饰的效果。使用比较灵活。
缺点:需要内部通过多态维护需要被增强的类的实例。进而使得代码稍微复杂
时间: 2024-12-15 23:22:29