《Android源码设计模式解析与实战》读书笔记(二十一)——装饰者模式

来源:互联网 发布:淘宝自动输入验证码 编辑:程序博客网 时间:2024/05/17 13:10

在之前的我为 RecyclerView 添加 HeaderView 和 FooterView 的时候就提到了 ListView 在添加头布局和脚布局时就用到了装饰者模式,装饰者模式又称为包装模式(Wrapper Pattern),它使用一个对客户端透明的方式来动态扩展对象的功能,同时也是替代继承关系的方案之一。在生活中也能体现装饰者模式,比如人要穿衣服,可以穿运动装和正装,但是无论怎么样,本质都还是一个人,只是装饰了不同的衣着。所以装饰者模式就是装饰物不同,但是本质不变。


第二十一章 装饰模式

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下载

阅读全文
0 0
原创粉丝点击