《Android源码设计模式解析与实战》读书笔记(二十一)——装饰者模式
2017-06-06 14:22
274 查看
在之前的我为 RecyclerView 添加 HeaderView 和 FooterView 的时候就提到了 ListView 在添加头布局和脚布局时就用到了装饰者模式,装饰者模式又称为包装模式(Wrapper Pattern),它使用一个对客户端透明的方式来动态扩展对象的功能,同时也是替代继承关系的方案之一。在生活中也能体现装饰者模式,比如人要穿衣服,可以穿运动装和正装,但是无论怎么样,本质都还是一个人,只是装饰了不同的衣着。所以装饰者模式就是装饰物不同,但是本质不变。
Component :抽象组件,一般为接口或者抽象类,充当被装饰的原始对象。
ConcreteComponent :具体组件,具体的被装饰对象。
Decorator :抽象装饰者,一般为抽象类,内部有一个指向组件的引用,根据不同的装饰逻辑实现不同的具体子类,如果具体装饰者只有一个的话,可以省略此类。
ConcreteDecorator :具体装饰者,对抽象装饰者作出具体实现。
就拿开头提到了例子来说,人的衣着可能会随时变化,一个男生,在家穿得可能比较随便,但是出去运动或者约会时,就会装饰不同的穿着,我们就可以用装饰模式来实现,而不用创建多个男生子类,比如运动型男生和约会型男生了。
Person(抽象组件)类:
Boy(具体组件)类:
AbstractDressing(抽象装饰者):
SportDressing(具体装饰者):
DateDressing(具体装饰者):
客户端(MainActivity)调用:
运行程序,打印如下:
Boy 的本质还是那个 Boy,只是根据不同的行为而装饰了不同的东西,SportDressing 和 DateDressing 为 Boy 对象提供了功能扩展,而且是在没有直接修改原有的逻辑和结构的基础上扩展了功能。
Demo下载
第二十一章 装饰模式
1.定义
动态地给一个对象添加一些额外的职责, 就增加功能来说,装饰模式相对于生成子类来说要更灵活。2.使用场景
1).需要透明且动态地扩展类的功能时。3.简单实现
装饰模式一般有四类角色:Component :抽象组件,一般为接口或者抽象类,充当被装饰的原始对象。
ConcreteComponent :具体组件,具体的被装饰对象。
Decorator :抽象装饰者,一般为抽象类,内部有一个指向组件的引用,根据不同的装饰逻辑实现不同的具体子类,如果具体装饰者只有一个的话,可以省略此类。
ConcreteDecorator :具体装饰者,对抽象装饰者作出具体实现。
就拿开头提到了例子来说,人的衣着可能会随时变化,一个男生,在家穿得可能比较随便,但是出去运动或者约会时,就会装饰不同的穿着,我们就可以用装饰模式来实现,而不用创建多个男生子类,比如运动型男生和约会型男生了。
Person(抽象组件)类:
public abstract class AbstractPerson { public abstract void dressed(); }
Boy(具体组件)类:
public class Boy extends AbstractPerson { private AbstractDressing mAbstractDressing; @Override public void dressed() { System.out.println("男生夏天在家一般只穿条内裤"); } public void sport() { if (mAbstractDressing == null || !(mAbstractDressing instanceof SportDressing)) { mAbstractDressing = new SportDressing(this); mAbstractDressing.dressed(); } } public void date(){ if (mAbstractDressing == null || !(mAbstractDressing instanceof DateDressing)) { mAbstractDressing = new DateDressing(this); mAbstractDressing.dressed(); } } }
AbstractDressing(抽象装饰者):
public abstract class AbstractDressing extends AbstractPerson { private AbstractPerson mAbstractPerson; public AbstractDressing(AbstractPerson mAbstractPerson) { this.mAbstractPerson = mAbstractPerson; } @Override public void dressed() { mAbstractPerson.dressed(); } }
SportDressing(具体装饰者):
public class SportDressing extends AbstractDressing { public SportDressing(AbstractPerson mAbstractPerson) { super(mAbstractPerson); } private void sportsVest() { System.out.println("穿上运动背心"); } private void sportShorts() { System.out.println("穿上运动短裤"); } private void sportShoes() { System.out.println("穿上运动鞋"); } @Override public void dressed() { super.dressed(); sportsVest(); sportShorts(); sportShoes(); } }
DateDressing(具体装饰者):
public class DateDressing extends AbstractDressing { public DateDressing(AbstractPerson mAbstractPerson) { super(mAbstractPerson); } private void shirts() { System.out.println("穿上衬衣"); } private void trousers() { System.out.println("穿上西裤"); } private void leatherShoes() { System.out.println("穿上皮鞋"); } @Override public void dressed() { super.dressed(); shirts(); trousers(); leatherShoes(); } }
客户端(MainActivity)调用:
Boy mBoy = new Boy(); System.out.println("在家穿的衣服"); mBoy.dressed(); System.out.println("运动时穿的衣服"); mBoy.sport(); System.out.println("约会时穿的衣服"); mBoy.date();
运行程序,打印如下:
Boy 的本质还是那个 Boy,只是根据不同的行为而装饰了不同的东西,SportDressing 和 DateDressing 为 Boy 对象提供了功能扩展,而且是在没有直接修改原有的逻辑和结构的基础上扩展了功能。
4.总结
装饰模式与代理模式有些相似,往往会把装饰模式误以为是代理模式,它们的区别在于装饰模式是以对客户端透明的方式扩展对象的功能,是替代继承关系的方案之一,而代理模式则是给对象提供一个代理对象,由代理对象来控制对原对象的引用;装饰模式是为对象增加功能,而代理模式只是对对象施加控制,并不会对原对象的功能有所增强。Demo下载
相关文章推荐
- 读书笔记3:Head First设计模式——装饰者模式
- 【读书笔记】读《JavaScript设计模式》之装饰者模式
- 《大话设计模式》读书笔记三——装饰者模式
- 读书笔记之 - javascript 设计模式 - 装饰者模式
- 设计模式读书笔记-----装饰者模式
- HeadFirst设计模式_读书笔记_003_装饰者模式
- 《设计模式》读书笔记:装饰者模式
- 《HeadFirst设计模式》读书笔记-第3章-装饰者模式
- 【深入PHP 面向对象】读书笔记(二十一) - 企业模式(六) - 模板视图和视图助手
- 设计模式读书笔记-----装饰者模式
- 【设计模式】《Head First 设计模式》读书笔记——装饰者模式
- 设计模式读书笔记----装饰者模式
- Java程序性能优化 读书笔记(五)设计模式:装饰者模式
- 《敏捷软件开发:原则、模式与实践》 前三章读书笔记 --概念和原则
- 企业应用架构模式 读书笔记 ZT
- [读书笔记]版本控制模式------With SubVersion
- 设计模式随笔系列:来杯咖啡-装饰者模式(Decorator)[原]
- 《敏捷软件开发:原则、模式与实践》 前三章读书笔记 -- 实践
- Head first design patterns 读书笔记 – Strategy(策略模式)
- 设计模式示例二 Decorator(装饰者)