装饰模式
Posted zuolanlan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰模式相关的知识,希望对你有一定的参考价值。
一、基本概念
1、定义:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
2、作用:为已有功能动态地添加更多功能的一种方式。
3、何时使用装饰模式:当系统需要新功能时,要求向旧的类中添加新的代码,这些新的代码通常装饰了原有类的核心职责或主要行为。
4、优点:把类中装饰功能从类中搬移去除,这样可以简化原有的类。
有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
5、特点:在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,并让这个类包装它所需要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地,按顺序地使用装饰功能包装对象了
6、装饰模式结构图
Component:定义一个对象接口(或者抽象类),可以给这些对象动态地添加职责;
ConcreteComponent:定义了一个具体的对象,也可以给这个对象添加一些职责;——人
Decorator:装饰抽象类,继承了Component,从外类来扩展Component类的功能,但Component无需知道Decorator的存在。——衣物
ConcreteDecoratorA:具体的装饰对象,起到给Component添加职责的功能~落到实处;——裙子
7、简化具体的实施过程
- 如果ConcreteComponent只有一个,没有Component,就可以让Decorator直接继承ConcreteComponent;
e.g 给一个人穿各种衣服
- 如果ConcreteDecoratorA只有一种,就可以不要Decorator,直接让ConcreteDecoratorA继承Component。
二、示例:给小仙猪打扮一下
属于简化实施过程的第一种情况。
1、UML图
2、代码
Person类
1 package thirdDecoration; 2 3 // 相当于ConcreteCompement的person 4 public class Person { 5 private String name; 6 public Person(){} 7 public Person(String name){ 8 this.name=name; 9 } 10 11 public void show(){ //由于在Java中,普通类不能拥有抽象方法,且抽象方法无方法体,所以和书上C#的写法不同 12 System.out.println("装扮的"+this.name); 13 }; 14 }
服饰类
1 package thirdDecoration; 2 3 public class Finery extends Person { 4 protected Person compenent; 5 public void Decorate(Person person){ 6 this.compenent=person; 7 } 8 public void show(){ //通过覆写的方式增加子类的特性 9 if (compenent!=null){ 10 compenent.show(); 11 } 12 } 13 }
具体服饰类
1 package thirdDecoration; 2 3 public class Tshirt extends Finery { 4 public void show(){ 5 System.out.println("T恤"); 6 super.show(); 7 } 8 }
1 package thirdDecoration; 2 3 public class Skirt extends Finery { 4 public void show(){ 5 System.out.println("超短裙"); 6 super.show(); 7 } 8 }
1 package thirdDecoration; 2 3 public class Dress extends Finery { 4 public void show(){ 5 System.out.println("连衣裙"); 6 super.show(); 7 } 8 }
客户端
1 package thirdDecoration; 2 3 public class DecorationTest { 4 5 public static void main(String[] args) { 6 Person person=new Person("小仙猪");//把对象找出来 7 Tshirt tshirt=new Tshirt(); //把衣服准备好 8 Skirt skirt=new Skirt(); //把衣服准备好 9 10 skirt.Decorate(person);//裙子穿上 11 tshirt.Decorate(skirt);//再把上衣穿上 12 tshirt.show(); 13 14 System.out.println("done!"); 15 } 16 17 }
分析:
- 这部分和常理的理解有那么一点不太一样,因为我们正常是觉得,人还是那个人,但是穿了不同的衣服,人是主题,贯穿始终,但是这里,人好像被包裹了一件衣服后,就不是这个人了。不过这只是一个例子而已。
- 装饰功能的装饰顺序很重要,示例中“穿衣服”是比较随性的,但是工程中,例如加密数据和过滤词汇都可以是数据持久化的装饰功能,但是一定是先过滤词汇然后再加密,否则会出问题的。
以上是关于装饰模式的主要内容,如果未能解决你的问题,请参考以下文章