首页 > 代码库 > 设计模式-装饰者模式

设计模式-装饰者模式

1 模式动机

我们知道可以通过定义子类,在不改变现有代码的情况下,动态的扩展功能。如果因为子类过多或其它原因不能新建子类时,还可以通过新建装饰者的方式来动态的扩展功能。

 

2 模式定义

装饰模式(Decorator Pattern):以对客户端透明的方式动态地给一个对象附加上更多的责任。

 

3 模式分析

Component抽象构件:

    可以是一个接口,也可以是抽象类,定义了统一的接口,其它角色均会实现。

ConcreteComponent具体构件:

    被装饰的对象,提供一个基础的功能实现,在此基础上通过装饰者扩展功能。

Decorator装饰角色:

    包含对Component统一接口的实现。

ConcreteComponent具体装饰角色:

包含对接口的具体装饰实现。

类图如下所示:

技术分享 

 

4 实例演示

package com.pattern.decorator;
// 所有炒饭的接口类
public interface Rice {
    public int cost();

    public String getDescription();
}


package com.pattern.decorator;
// 标准版炒饭实现类
public class EggRice implements Rice {
    @Override
    public int cost() {
        // 标准版8元每份
        return 8;
    }

    @Override
    public String getDescription() {
        return "Rice standard";
    }
}


package com.pattern.decorator;
// 炒饭装饰者基类
public abstract class RiceDecorator implements Rice {
    protected Rice rice = null;

    public RiceDecorator(Rice rice) {
        this.rice = rice;
    }

    @Override
    public String getDescription() {
        return rice.getDescription();
    }
}


package com.pattern.decorator;
// 加蛋装饰器
public class EggDecorator extends RiceDecorator {
    public EggDecorator(Rice rice) {
        super(rice);
    }

    @Override
    public int cost() {
        // 加蛋加一元
        return rice.cost() + 1;
    }
}

 
package com.pattern.decorator;
// 加肉装饰器
public class MeatDecorator extends RiceDecorator {
    public MeatDecorator(Rice rice) {
        super(rice);
    }

    @Override
    public int cost() {
        // 加肉加两元
        return rice.cost() + 2;
    }
}


package com.pattern.decorator;
public class RiceTest {
    public static void main(String args[]) {
        // 计算加肉加蛋后的炒饭价格
        Rice theRice = new EggRice();
        // 加肉加两个鸡蛋
        Rice myRice = new MeatDecorator(new EggDecorator(new EggDecorator(theRice)));
        System.out.println("Price(standard):"+theRice.cost());
        System.out.println("Price(two eggs and one meat):"+ myRice.cost());
    }
}

 

5 优缺点

优点:

1 可以扩展对象的功能,提供比继承更多的灵活性。

2 可以使用不同的装饰类来达到很多不同行为的组合。 

缺点:

1 比继承更加复杂

2 会导致设计中出现许多小类,如果过度使用,会使程序变得复杂

 

6 适用环境

1 需要增加一些由基本功能的排列组合而产生的大量功能,可能导致子类爆炸性的增加,从而使得继承关系变得不现实。

2 类定义为不能生成子类,不能通过直接继承扩展。

 

7 总结

1 当无法通过继承进行扩展,可以考虑通过装饰扩展,其实就是通过组合和委托扩展。

2 装饰者可以在被装饰者行为的前面或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,从而达到特定的目的。

3 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

设计模式-装饰者模式