简单易懂设计模式 之 装饰者(decorator)

大部分人对装饰这个概念都不会感到陌生,比如实际生活中常见的房屋装修,房屋在装修前,是毛坯房,只具备最简单的起居功能,而经过墙面粉刷,地板铺设等装饰后,它会给人以舒服的感觉,让居住者更加舒心,而如果再辅以各种家用电器的装饰,则会给人以家的感觉,一扫一天的疲惫;房子本质上还是原来的毛坯房,只是通过装饰让其在基本居住的基础上增加了更多的功能特性,在软件设计上也同样有通过代码包装将原本功能单一的对象组装成功能丰富的对象的代码形式,我们称之为装饰者模式

使用场景

当需要对某个对象的功能进行扩展时,一般考虑使用装饰者模式,这些扩展可以是静态扩展,也可以是动态扩展,如引言部分描述的实际生活中的房屋装修的例子,对于墙面粉刷等这种更换频率较低的装修,可以使用静态扩展,而对于家用电器等这种更换频率较高的装修,可以考虑采用动态扩展

代码示例

首先创建一个房子的抽象接口:

public interface House {
    void liveIn();
}

实现房子接口的毛坯房类(一般作为被装饰者):

public class RoughHouse implements House{
    @Override
    public void liveIn() {
        System.out.println("take a sleep");//毛坯房仅仅就是一个睡觉的地方
    }
}

房子装饰者抽象类(装饰者的父类,每个装饰者类中都包含有其需要装饰的对象):

public abstract class HouseDecorator implements House{
    protected House beDecoratedHouse;//被装饰对象

    public HouseDecorator(House beDecoratedHouse) {
        this.beDecoratedHouse = beDecoratedHouse;
    }
}

墙面装修装饰者:

public class PaintedHouse extends HouseDecorator{
    public PaintedHouse(House beDecoratedHouse) {
        super(beDecoratedHouse);
    }

    @Override
    public void liveIn() {
        System.out.println("have fun");//经过简单的墙面装修后,开始觉得住在里面有点乐趣了
        beDecoratedHouse.liveIn();
    }
}

电器装饰者类:

public class DianqiHouse extends HouseDecorator{
    public DianqiHouse(House beDecoratedHouse) {
        super(beDecoratedHouse);
    }

    @Override
    public void liveIn() {
        System.out.println("Dianqi is good");//有了电器,生活变得不错了
        beDecoratedHouse.liveIn();
    }
}

宜家家具装饰者类:

public class IkeaDianqiHouse extends HouseDecorator{
    public IkeaDianqiHouse(House beDecoratedHouse) {
        super(beDecoratedHouse);
    }

    @Override
    public void liveIn() {
        System.out.println("ikea is nice");//有了家具,生活开始美好起来
        beDecoratedHouse.liveIn();
    }
}

客户端调用:

public class Client {
    public static void main(String[] args) {
        House myHouse = new DianqiHouse(new PaintedHouse(new RoughHouse()));

        myHouse.liveIn();
        System.out.println("--涨工资了,买些宜家家具--");
        House myNewHouse = new IkeaDianqiHouse(myHouse);
        myNewHouse.liveIn();
    }
}

//调用结果
Dianqi is good
have fun
take a sleep
--涨工资了,买些宜家家具--
ikea is nice
Dianqi is good
have fun
take a sleep

通过装饰者,可以对对象的功能进行方便的组装,扩展;它是开闭原则和单一职责原则的良好体现

应用实例

java.io.InputStream
java.io.OutputStream
java.io.Reader
java.io.Writer

你可能感兴趣的:(简单易懂设计模式 之 装饰者(decorator))