设计模式之——装饰者模式

转载请注明出处:http://blog.youkuaiyun.com/binbinqq86/article/details/71487272

装饰者模式,提到“装饰”二字,字面意思就是一个事物,可以添加东西去装饰它,比如新买的房子要装修,一个人要买衣服首饰来打扮自己等等。。。老规矩,先通过一个房子装修简单的例子来说明吧:

整体结构图:

这里写图片描述

图中我们可以看出,首先定义了一个抽象类House,这就是我们从开发商那里拿到的毛坯房,什么都没有,我们在里面定义了一个抽象方法decorator(),子类去继承它来执行具体的装修方案,另外一个就是getDescription(),这个是用来输出当前装修情况和进度的,这个类就是抽象组件类。而MyHouse继承于House,这个就是具体的房子,比如张三的,李四的,等等,属于具体的一个组件。HouseDecorator则是一个抽象装饰者,它抽象了所有装修材料,同样它也是继承House。下面的WindowDecorator,DoorDecorator等等就是具体的装修材料了,你想添加什么东西来装饰你的房子,就可以去继承HouseDecorator这个类,它们都是具体的装饰者类。

下面是伪代码:

package com.example.tb.designpatten.decorator.abstractcomponent;

/**
 * Created by tb on 2017/5/10.
 * 定义房子抽象基类(抽象组件)
 */

public abstract class House {
    /**
     * 装修情况说明
     */
    protected String description;

    public String getDescription(){
        return description;
    }
    /**
     * 房子有一个装修的抽象方法
     */
    public abstract void decorate();
}
package com.example.tb.designpatten.decorator.abstractdecorator;

import com.example.tb.designpatten.decorator.abstractcomponent.House;

/**
 * Created by tb on 2017/5/10.
 * 用来装修房子的各种材料的抽象基类(抽象装饰者)
 */

public abstract class HouseDecorator extends House {
    /**
     * 返回房子装修情况
     * @return
     */
    public abstract String getDescription();

}
package com.example.tb.designpatten.decorator.concretecomponent;

import com.example.tb.designpatten.decorator.abstractcomponent.House;

/**
 * Created by tb on 2017/5/10.
 * 具体的需要装修的我的房子(具体组件)
 */

public class MyHouse extends House {
    private static final String TAG = "MyHouse";
    public MyHouse(){
        description=TAG+":还未开始任何装修的毛坯房";
    }
    @Override
    public void decorate() {
        //具体装修逻辑,省略。。。
    }
}
package com.example.tb.designpatten.decorator.concretedecorator;

import com.example.tb.designpatten.decorator.abstractcomponent.House;
import com.example.tb.designpatten.decorator.abstractdecorator.HouseDecorator;

/**
 * Created by tb on 2017/5/10.
 * 门(具体装饰者)
 */

public class DoorDecorator extends HouseDecorator {
    /**
     * 持有一个house类的引用
     */
    private House house;

    public DoorDecorator(House house){
        this.house=house;
    }

    @Override
    public void decorate() {
        //执行具体的装修逻辑,代码省略。。。
    }

    @Override
    public String getDescription() {
        return house.getDescription()+"——增加了门";
    }
}
package com.example.tb.designpatten.decorator.concretedecorator;

import com.example.tb.designpatten.decorator.abstractcomponent.House;
import com.example.tb.designpatten.decorator.abstractdecorator.HouseDecorator;

/**
 * Created by tb on 2017/5/10.
 * 窗户(具体装饰者)
 */

public class WindowDecorator extends HouseDecorator {
    /**
     * 持有一个house类的引用
     */
    private House house;

    public WindowDecorator(House house){
        this.house=house;
    }

    @Override
    public void decorate() {
        //执行具体的装修逻辑,代码省略。。。
    }

    @Override
    public String getDescription() {
        return house.getDescription()+"——增加了窗户";
    }
}

整体的五个类的伪代码就全部列出了,很简单。下面我们就写测试代码:

public void test(){
        House house=new MyHouse();
        house=new WindowDecorator(house);
        house=new DoorDecorator(house);
        Log.e("Decorator:",house.getDescription());
    }

下面看运行结果:
这里写图片描述

怎么样,跟我们预想的一致,这就是装饰者模式:也成为包装模式,同时它也是继承关系的一种替代方案之一,在现实生活中,你也可以看到很多这样的例子。装饰者模式动态的给一个对象增加一些额外的职责。就增加功能来说,装饰者模式相比生成子类更为灵活。

装饰者模式在Java和Android的源码中都有应用,比如Java中的IO,在java.io包内的类太多了,简直是。。。。。。“排山倒海”。你第一次(还有第二次第三次)看到这些API发出“哇”的惊叹时,放心,你不是唯一受到惊吓的人。InputStream就是这个抽象组件,而FileInputStream,StringBufferInputStream。。。这些就是具体组件,FilterInputStream是一个抽象装饰者,下面的BufferedInputStream,LineNumberInputStream。。。这些就是具体的装饰者了。但是Java I/O也引出装饰者模式的一个“缺点”:利用装饰者模式,常常造成设计中有大量的小类,数量实在太多,可能会造成使用此API程序员的困扰。但是,当你了解了其中的原理之后,就可以很容易地辨别出他们的装饰者类是如何组织的,以方便用包装方式取得想要的行为。

再来看看Android源码中装饰者模式的应用:Context。我们最常接触的一个类,但是可能并不一定有过真正的了解,Context类在Android里是一个抽象类,在我们的装饰者模式里就相当于抽象组件,而ContextImpl就是具体的组件,它继承于Context,并且实现了里面的抽象方法,我们知道Activity继承于ContextThemeWrapper,而ContextThemeWrapper又继承于ContextWrapper,最终的这个ContextWrapper又继承于Context,ContextWrapper就是我们要找的装饰者了,源码中可以看到,ContextWrapper中有个mBase,是一个Context类的引用,这个类里面所有的方法都是调用了ContextImpl中对应的方法,这就是装饰者模式的套路。。。对于具体的方法的包装扩展则有ContextWrapper的具体子类完成,比如我们的Activity、Service、Application。可以看到即便是Android源码中应用,装饰者模式也并不难理解,比较简单。

总结:装饰者模式主要就是抽象组件、具体组件(继承抽象组件并实现里面的方法),抽象装饰者(持有一个抽象组件的引用并且继承抽象组件),数不清的具体装饰者(随意扩展增加功能进行包装)。

好了,今天的讲解到此结束,有不明白的地方可以下面留言,谢谢大家~

源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值