设计模式之禅PK之结构类
结构类设计模式
- 结构类模式:
- 适配器模式
- 桥梁模式
- 组合模式
- 装饰模式
- 门面模式
- 享元模式
- 代理模式
- 相同点:他们都是通过组合类或对象产生更大的结构以适应更高的层次的逻辑需求
【装饰模式】VS【适配器模式】
- 装饰模式和适配器模式在通用类图上没有太多的相似之处,差别比较大
- 他们的功能上有很多【相似】的地方:
- 都是包装作用
- 都是通过委托方式实现其功能
- 他们的【不同】点是:
- 装饰包装的是自己的兄弟类,隶属于同一个家族
- 适配器模式则修饰非血缘关系类,把一个非本家族的对象伪装成本家族的对象注意是伪装。因此本质上它还是非相同接口的对象
- 从丑小鸭的华丽蜕变来开始
- "话说鸭妈妈有5个孩子,其中4个孩子都是黄白相间的颜色,而最小的那只也就是叫做丑小鸭的那只,是纯白色的,与兄弟姐妹都不相同,在遭受了诸多的嘲讽和讥笑后,最终丑小鸭变成了一只美丽的天鹅"
- 现在开始,进入丑小鸭的华丽蜕变过程吧!
装饰模式版的丑小鸭 | 适配器模式版的丑小鸭 |
---|---|
首先肯定丑小鸭就是一只天鹅,只是因为它从小或者是鸭妈妈的无知才没有被认出来是白天鹅,经过一段时间后,它逐步变成了一个漂亮、自信、优美的白天鹅 | 需要从鸭妈妈的角度分析,四个鸭子都是真正的鸭子,丑小鸭实际不是鸭--“雄兔脚扑朔,雌兔眼迷离,双兔傍地走,安能辨我是雌雄” |
设计:先设计一个丑小鸭,然后根据时间的先后来进行不同的美化处理--长出漂亮的羽毛--然后学会飞行--最后变成一只白天鹅 | 设计:鸭和天鹅,然后鸭妈妈把一只天鹅看成了小鸭子,最终时间到来的时候丑小鸭变成了白天鹅 |
类图的比较
装饰模式 | 适配器模式 |
---|---|
![]() | ![]() |
代码详解
-
装饰模式的丑小鸭的华丽蜕变
-
Swan
package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public interface Swan {// 天鹅会飞public void fly();// 天鹅会叫public void cry();// 天鹅都有漂亮的外表public void desAppaearance(); }
-
Uglyducking
package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class Uglyducking implements Swan {@Overridepublic void fly() {System.out.println("丑小鸭还比较小,还不能飞行!");}@Overridepublic void cry() {System.out.println("叫声是克鲁-克鲁-克鲁。。");}@Overridepublic void desAppaearance() {System.out.println("外形是脏兮兮的白色。毛茸茸的大脑袋!");}}
-
Decorator
package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class Decorator implements Swan {private Swan swan;public Decorator(Swan swan) {super();this.swan = swan;}@Overridepublic void fly() {swan.fly();}@Overridepublic void cry() {swan.cry();}@Overridepublic void desAppaearance() {swan.desAppaearance();}}
-
StrongBehavior
package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class StrongBehavior extends Decorator {// 强化谁public StrongBehavior(Swan swan) {super(swan);}// 会飞行了@Overridepublic void fly() {System.out.println("会飞行了!!!");}}
-
BeautifyAppearance
package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class BeautifyAppearance extends Decorator {// 要美化谁public BeautifyAppearance(Swan swan) {super(swan);}// 外表美化处理@Overridepublic void desAppaearance() {System.out.println("外表是纯色到的,非常惹人喜爱!");}}
-
Client
package com.peng.pk_zs;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class Client {public static void main(String[] args) {System.out.println("=====很久很久以前,这里有一只丑陋的小鸭子=====");Swan ducking = new Uglyducking();// 展示一下小鸭子ducking.desAppaearance();ducking.cry();ducking.fly();// 丑小鸭终于发现自己是一只白天鹅System.out.println("=====时间过去了很久,丑小鸭长大了=====");ducking = new BeautifyAppearance(ducking);ducking.desAppaearance();ducking = new StrongBehavior(ducking);ducking.fly();} }
-
执行结果
=====很久很久以前,这里有一只丑陋的小鸭子===== 外形是脏兮兮的白色。毛茸茸的大脑袋! 叫声是克鲁-克鲁-克鲁。。 丑小鸭还比较小,还不能飞行! =====时间过去了很久,丑小鸭长大了===== 外表是纯色到的,非常惹人喜爱! 会飞行了!!!
-
-
适配器模式的丑小鸭的华丽蜕变
-
Duck
package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public interface Duck {// 会叫public void cry();// 鸭子的外形public void desAppearance();// 鸭子的其他行为public void desBehavior(); }
-
Ducking
package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class Ducking implements Duck {@Overridepublic void cry() {System.out.println("叫声是:嘎嘎~~");}@Overridepublic void desAppearance() {System.out.println("外形是黄白相间的,嘴长!");}@Overridepublic void desBehavior() {System.out.println("会游泳~");}}
-
Swan
package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public interface Swan {// 天鹅会飞public void fly();// 天鹅会叫public void cry();// 天鹅都有漂亮的外表public void desAppaearance(); }
-
WhiteSwan
package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class WhiteSwan implements Swan {@Overridepublic void fly() {System.out.println("会飞~~");}@Overridepublic void cry() {System.out.println("叫声:克鲁-克鲁");}@Overridepublic void desAppaearance() {System.out.println("外形是纯白色,惹人喜爱!");}}
-
UglyDucking
package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class UglyDucking extends WhiteSwan implements Duck {@Overridepublic void cry() {super.cry();}@Overridepublic void desAppearance() {super.desAppaearance();}@Overridepublic void desBehavior() {System.out.println("会游泳!");super.fly();}}
-
Client
package com.peng.pk_sp;/*** @author kungfu~peng* @data 2017年12月13日* @description*/ public class Client {public static void main(String[] args) {// 鸭子System.out.println("鸭妈妈的四个孩子是这样的:");Duck duck = new Ducking();duck.cry();duck.desAppearance();duck.desBehavior();// 独特的丑小鸭System.out.println("丑小鸭长大后:");Duck dk = new UglyDucking();dk.cry();dk.desAppearance();dk.desBehavior();} }
-
执行结果
鸭妈妈的四个孩子是这样的: 叫声是:嘎嘎~~ 外形是黄白相间的,嘴长! 会游泳~ 丑小鸭长大后: 叫声:克鲁-克鲁 外形是纯白色,惹人喜爱! 会游泳! 会飞~~
-
最佳实践
- 装饰模式与适配器模式的不同
不同 | 装饰模式 | 适配器模式 |
---|---|---|
意图 | 加强对象的功能(也可以削弱) | 转化(把一个天鹅当做一个鸭子来看待) |
施与对象 | 自己的同宗 | 两个不同的对象 |
场景不同 | 任何时候 | 补救模式(项目已经完毕:紧急处理手段) |
扩展性不同 | 容易 | 难 |
声明
- 摘自秦小波《设计模式之禅》第2版;
- 仅供学习,严禁商业用途;
- 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;