结构型模式之装饰者模式
一.定义
装饰者模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为“油漆工模式”,它是一种对象结构型模式。
二、模式结构成员构成
• Component: 抽象构件
• ConcreteComponent: 具体构件
• Decorator: 抽象装饰类
• ConcreteDecorator: 具体装饰类
三.代码示例
1 /** 2 * Component 3 * 抽象构件 4 */ 5 public interface Person { 6 7 void eat(); 8 } 9 10 /** 11 * ConcreteComponent 12 * 具体构件 13 */ 14 public class Man implements Person { 15 16 @Override 17 public void eat() { 18 System.out.println("男人在吃"); 19 } 20 } 21 22 /** 23 * Decorator 24 * 抽象装饰类 25 */ 26 public abstract class Decorator implements Person { 27 28 protected Person person; 29 30 public void setPerson(Person person) { 31 this.person = person; 32 } 33 34 @Override 35 public void eat() { 36 person.eat(); 37 } 38 } 39 40 /** 41 * ConcreteDectrator 42 * 具体装饰类 43 */ 44 public class ManDecoratorA extends Decorator { 45 46 @Override 47 public void eat() { 48 super.eat(); 49 reEat(); 50 System.out.println("ManDecoratorA类"); 51 } 52 53 public void reEat() { 54 System.out.println("再吃一顿饭"); 55 } 56 } 57 58 59 /** 60 * ConcreteDectrator 61 * 具体装饰类 62 */ 63 public class ManDecoratorB extends Decorator { 64 65 @Override 66 public void eat() { 67 super.eat(); 68 System.out.println("==============="); 69 System.out.println("ManDecoratorB类"); 70 } 71 } 72 73 74 /** 75 * client 76 */ 77 public class Client { 78 79 public static void main(String[] args) { 80 Man man = new Man(); 81 ManDecoratorA md1 = new ManDecoratorA(); 82 ManDecoratorB md2 = new ManDecoratorB(); 83 84 md1.setPerson(man); 85 md2.setPerson(md1); 86 md2.eat(); 87 } 88 }
四.优点和缺点分析
优点:
>装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
>通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。比如:Java中的IO流
>具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”
>通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。比如:Java中的IO流
>具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”
缺点:
>使用装饰模式进行系统设计时将产生很多小对象,这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。
五.应用场景
>需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。
>当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类定义不能继承(如final类).
你投入得越多,就能得到越多得价值