一、 装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。网络
二、组合和继承的区别ide
继承。继承是给一个类添加行为的比较有效的途径。经过使用继承,可使得子类在拥有自身方法的同时,还能够拥有父类的方法。可是使用继承是静态的,在编译的时候就已经决定了子类的行为,咱们不便于控制增长行为的方式和时机。测试
组合。组合即将一个对象嵌入到另外一个对象中,由另外一个对象来决定是否引用该对象来扩展本身的行为。这是一种动态的方式,咱们能够在应用程序中动态的控制。this
与继承相比,组合关系的优点就在于不会破坏类的封装性,且具备较好的松耦合性,可使系统更加容易维护。可是它的缺点就在于要建立比继承更多的对象。spa
三、装饰者模式的优缺点3d
优势调试
一、装饰者模式能够提供比继承更多的灵活性code
二、能够经过一种动态的方式来扩展一个对象的功能,在运行时选择不一样的装饰器,从而实现不一样的行为。对象
三、经过使用不一样的具体装饰类以及这些装饰类的排列组合,能够创造出不少不一样行为的组合。可使用多个具体装饰类来装饰同一对象,获得功能更为强大的对象。blog
四、具体构件类与具体装饰类能够独立变化,用户能够根据须要增长新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
缺点
一、会产生不少的小对象,增长了系统的复杂性
二、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于屡次装饰的对象,调试时寻找错误可能须要逐级排查,较为烦琐。
四、装饰者的使用场景
一、在不影响其余对象的状况下,以动态、透明的方式给单个对象添加职责。
二、须要动态地给一个对象增长功能,这些功能也能够动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
以上内容来自网络
五、UML图(Astah/jude)下载地址:http://pan.baidu.com/s/1eQiVePc
六、示例:
装饰者基类
1 package com.xinye.test.decoration; 2 /** 3 * 食物基类 4 * @author xinye 5 * 6 */ 7 public abstract class Food { 8 9 protected String desc; 10 11 public abstract String getDesc(); 12 }
鸡肉
1 package com.xinye.test.decoration; 2 /** 3 * 鸡肉 4 * @author xinye 5 * 6 */ 7 public class Chicken extends Food { 8 public Chicken(){ 9 desc = "鸡肉"; 10 } 11 @Override 12 public String getDesc() { 13 return desc; 14 } 15 16 }
鸭肉
1 package com.xinye.test.decoration; 2 /** 3 * 鸭肉 4 * @author xinye 5 * 6 */ 7 public class Duck extends Food { 8 public Duck(){ 9 desc = "鸭肉"; 10 } 11 @Override 12 public String getDesc() { 13 return desc; 14 } 15 16 }
装饰者基类
1 package com.xinye.test.decoration; 2 /** 3 * 4 * @author xinye 5 * 6 */ 7 public abstract class FoodDecoration extends Food { 8 9 @Override 10 public abstract String getDesc(); 11 12 }
蒸-装饰者
1 package com.xinye.test.decoration; 2 /** 3 * 蒸食物 4 * @author xinye 5 * 6 */ 7 public class SteamedFood extends FoodDecoration { 8 9 private Food food; 10 11 public SteamedFood(Food f){ 12 this.food = f; 13 } 14 15 @Override 16 public String getDesc() { 17 return getDecoration() + food.getDesc(); 18 } 19 20 private String getDecoration(){ 21 return "蒸"; 22 } 23 }
烤-装饰者
1 package com.xinye.test.decoration; 2 /** 3 * 烤食物 4 * @author xinye 5 * 6 */ 7 public class RoastFood extends FoodDecoration { 8 9 private Food food; 10 11 public RoastFood(Food f){ 12 this.food = f; 13 } 14 15 @Override 16 public String getDesc() { 17 return getDecoration() + food.getDesc(); 18 } 19 20 private String getDecoration(){ 21 return "烤"; 22 } 23 }
客户端
1 package com.xinye.test.decoration; 2 /** 3 * 客户端 4 * @author xinye 5 * 6 */ 7 public class Client { 8 public static void main(String[] args) { 9 // 测试单纯的食物 10 Food f1 = new Chicken(); 11 System.out.println(f1.getDesc()); 12 13 System.out.println("----------------------"); 14 // 测试单重修饰的食物 15 RoastFood rf = new RoastFood(f1); 16 System.out.println(rf.getDesc()); 17 18 System.out.println("----------------------"); 19 // 测试多重修饰的食物 20 SteamedFood sf = new SteamedFood(rf); 21 System.out.println(sf.getDesc()); 22 } 23 }
执行结果:鸡肉----------------------烤鸡肉----------------------蒸烤鸡肉