装饰模式

概括

动态地给对象添加一些额外的职责。就功能来说装饰模式相比子类更为灵活。


概述

在许多设计中,可能需要改进类的某个类的某个对象的某个功能,而不是该类创建的所有对象。例如 麻雀类的实例(麻雀)可以飞行100米 ,但有一只麻雀安装了特殊的装置 可以飞行150米。

装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。“具体组件“类与“具体装饰“类是该模式中最重要的两个角色。前者的实例被称为“被装饰者” 后者被称为“装饰者”。“具体装饰”类需要包括“具体组件”类的一个实例的引用,以便装饰 “被装饰者”。

注:装饰模式中非常重要的一点是:“具体组件”和“装饰”都是“抽象组件”的子类 ,则“抽象组件”声明的对象既可以存放“被装饰者”的引用也可以存放“装饰者”的引用。对用户而言 “装饰者”所实现抽象组件中的方法是“被装饰者”相应的方法的改进或修正。因此,用户如果需要调用“被装饰者”原始方法就让“抽象组件”声明的对象存放“被装饰者”的引用,反之,则存放“装饰者”的引用。


UML类图

这里写图片描述

装饰模式的四种角色

  • 抽象组件(Component): 抽象组件是一个抽象类,定义了“被装饰者”需要进行“装饰”的方法。
  • 具体组件(ConcreteComponent):具体组件是抽象组件的一个子类,具体组件的实例被称作“被装饰者”。
  • 装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包含一个抽象组件声明的变量以便保存“被装饰者”的引用。装饰可以是抽象类也可以是非抽象类,如果是非抽象类,那么该类的实例被称作“被装饰者”。
  • 具体装饰(ConcreteDecotator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称作“装饰者”。

例子:从冰箱中拿出大象
Pattern.java

public interface Pattern {

    public void doGet();

}

Decorator.java

public abstract class Decorator implements Pattern{

    private Pattern pattern;

    Decorator(Pattern pattern){
        this.pattern = pattern;
    }


    public Pattern getPattern() {
        return pattern;
    }

    public void setPattern(Pattern pattern) {
        this.pattern = pattern;
    }

    public void doGet(){
        pattern.doGet();
    }


}

装饰器实例

public class DecoratorOne extends Decorator{

    DecoratorOne(Pattern pattern) {
        super(pattern);
        // TODO Auto-generated constructor stub
    }

    public void  openFrige(){
        System.out.println("第一步  打开冰箱");
    }
    @Override
    public void doGet(){
        super.doGet();
        openFrige();
    }

}

public class DecoratorTwo extends Decorator{
    DecoratorTwo(Pattern pattern) {
        super(pattern);
        // TODO Auto-generated constructor stub
    }

    public void  getElephant(){
        System.out.println("第二步 拿出大象");
    }
    @Override
    public void doGet(){
        super.doGet();
        getElephant();
    }
}

public class DecoratorThree extends Decorator{

    DecoratorThree(Pattern pattern) {
        super(pattern);
        // TODO Auto-generated constructor stub
    }

    public void closeFridge(){
        System.out.println("第三步  关上冰箱");
    }
    @Override
    public void doGet(){
        super.doGet();
        closeFridge();
    }

}

被装饰者

public class Person implements Pattern{



    @Override
    public void doGet() {
        // TODO Auto-generated method stub
        System.out.println("我想把冰箱里的大象拿出来");
    }

}

Test.java

public class Test {
public static void main(String[] args) {
    Pattern pattern = new Person();
    Decorator decorator = new DecoratorThree
            (new DecoratorTwo(new DecoratorOne(pattern)));

    decorator.doGet();
}
}

运行结果:
我想把冰箱里的大象拿出来
第一步 打开冰箱
第二步 拿出大象
第三步 关上冰箱


要点:

  1. 如上述例子 ,装饰者也可以被装饰 成为被装饰者,经过一层层装饰 达到类似于过滤链的效果;Decorator抽象类中,持有Pattern接口,需要改进或修正的方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。
  2. 具体被装饰者类,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。
  3. 装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。所以:扩展体现在继承、修改在子类中,而不是具体的抽象类,这充分体现了依赖倒置原则,这是自己理解的装饰者模式。

    参考:http://blog.csdn.net/jason0539/article/details/22713711

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值