视频讲解链接:(审核中......)
1.概念与结构
1.1定义
在不必改变原类文件和原类使用的继承的情况下,动态地扩展一个对象的功能。就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。
装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为。例如我们买了手机之后给手机装上手机壳,贴上手机膜等。这些,都可以说是装修模式的应用。装饰模式与继承不一样,继承是需要一个子类来拓展对象的功能,而装饰模式则不一样,它是通过定义一个装饰类,在这个装饰类中持有某些对象的引用,然后通过使用对象之间的关联关系来取代类之间的继承关系。
1.2结构
装饰模式包含四个角色:
- 抽象构件(Component):它是具体构件和抽象装饰类的共同父类,声明了要在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象。抽象构件一般定义为接口。
- 具体构件(ConcreteComponent):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰对象可以给它增加额外的职责(方法)。
- 抽象装饰类(Decorator):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
- 具体装饰类(ConcreteDecorator):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。
2.实现
举个例子:在n年前,人类捕捉了动物之后,会直接杀了之后就拿来吃,而不会把它烤熟、弄上一些配料之后再吃。但是到了后来,人类就懂得了把动物烤熟、弄上配料之后再吃了。现在我们假设人类本来是不会烤熟之后再吃的,而是被装饰了一些额外的能力之后,才知道烤熟之后再吃。类图和代码如下:
/** * 定义作为人类应有的一些规范 */ public interface Human { void eating(); } /** * 具体构件类 */ public class Man implements Human{ @Override public void eating() { System.out.println("吃刚刚捕获的美味佳肴"); } } /** * 抽象装饰者,需要实现抽象构件接口 */ public class Decorator implements Human{ //维持对抽象构件的引用 private Human human; //注入构件实例 public Decorator(Human human) { this.human = human; } @Override public void eating() { human.eating(); } } public class ConcreteDecorator extends Decorator { public ConcreteDecorator(Human human){ super(human); } @Override public void eating() { System.out.println("把捕捉的动物给烤熟了,在加些配料"); super.eating(); System.out.println("吃完饭之后洗手"); } //需要增加的其他方法 } public class Demo { public static void main(String[] args){ Human man = new Man(); //没进行装饰之前 man.eating(); System.out.println("--------------------"); //进行装饰之后 man = new ConcreteDecorator(man); man.eating(); } }
3.优点与缺点
3.1优点
- 使用装饰者模式比使用继承更加灵活,因为它选择通过一种动态的方式来扩展一个对象的功能,在运行时可以选择不同的装饰器,从而实现不同的行为。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
- 具体构件类与具体装饰类可以独立变化,他能是低耦合的。用户可以根据需要来增加新的具体构件类和具体装饰类,在使用时再对其进行各种组合,原有代码无须改变,符合“开闭原则”。
3.2缺点
- 会产生很多的小对象,增加了系统的复杂性。
- 由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
参考链接:https://zhuanlan.zhihu.com/p/44003220
https://www.cnblogs.com/adamjwh/p/9036358.html
https://wenku.baidu.com/view/616366cc03d276a20029bd64783e0912a2167ccc.html
来源:https://www.cnblogs.com/kyl626/p/12651504.html