您的位置:首页 > 其它

装饰器模式

2017-11-02 13:56 169 查看

什么是装饰器模式

  装饰器模式又称包装(Wrapper)模式,能够实现动态的为对象添加功能。是继承关系的一个替代方案,因为可以在不创造子类的情况下将对象的功能加以扩展。

  通常给对象添加新功能,要么直接修改对象添加,要么派生对应的子类添加或者使用对象组合的方式。在面上对象的设计中,我们应该尽量使用对象组合而不是对象继承来扩展。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。

装饰器模式的结构和说明

  -抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任对象。

  -具体构件角色(Concrete Component):定义一个将要接收附加责任的类。

  -装饰角色(Decorator):持有一个构件(Component)对象引用,并定义一个与抽象构件接口一致的接口

  -具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任

                              


装饰器模式的特点

  -装饰器对象和真是对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。

  -装饰对象包含一个真实对象的引用。

  -装饰对象接收所有来自客户端的请求。它把这些请求转发给真实的对象。

  装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不能修改给定对象的构件就可以在外部增加附加功能。在面向对象的设计中,通常是通过集成来实现对给定类的功能扩展

示例:

  步骤:

写一个组件对象接口 Component.java

写一个类 ConcreteComponent.java 实现 组件对象接口

写一个装饰器抽象类 Decorator.java 实现组件接口

写装饰器具体的实现对象 ConcreteDecorator1.java和ConcreteDecorator2.java

步骤一:写一个组件对象接口

package org.burning.sport.design.pattern.decoratorpattern;

/**
*  @Description: 组件对象接口,可以给这些对象动态的添加职责
*/
public interface Component {
public void doSomething();
}


步骤二:写一个具体构件角色

package org.burning.sport.design.pattern.decoratorpattern;

/**
*  @Description: 具体的组件对象,实现了组件接口。该对象通常就是被装饰器装饰的原始对象,可以给这个对象添加职责
*/
public class ConcreteComponent implements Component {
@Override
public void doSomething() {
System.out.println("功能A");
}
}


步骤三:写一个装饰器抽象类

package org.burning.sport.design.pattern.decoratorpattern;

/**
*  @Description: 所有装饰器的父类,需要定义一个与组件接口一致的接口(主要是为了实现装饰器功能的复用,
*                 即具体的装饰器A可以装饰另外一个具体的装饰器B,因为装饰器类也是一个Component),并持有一个Component对象,
*                 该对象其实就是被装饰的对象。如果不实现组件接口类,则只能为某个组件添加单一的功能,
*                 即装饰器对象不能再装饰其他的装饰器对象
*/
public abstract class Decorator implements Component {
/**
* 持有组件对象
*/
private Component component;

public Decorator(Component component) {
this.component = component;
}

@Override
public void doSomething() {
//转发请求给组件对象,可以在转发前后执行一些附加动作
component.doSomething();
}
}


步骤四:写装饰器具体的实现对象

package org.burning.sport.design.pattern.decoratorpattern;

/**
*  @Description: 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象
*/
public class ConcreteDecorator1 extends Decorator {
public ConcreteDecorator1(Component component) {
super(component);
}

@Override
public void doSomething() {
super.doSomething();
this.doAnotherThing();
}

/**
* 新功能
*/
private void doAnotherThing() {
System.out.println("功能B");
}
}


package org.burning.sport.design.pattern.decoratorpattern;

/**
*  @Description: 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象
*/
public class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Component component) {
super(component);
}

@Override
public void doSomething() {
super.doSomething();
this.doAnotherThing();
}

private void doAnotherThing() {
System.out.println("功能C");
}
}


步骤五:测试

package org.burning.sport.design.pattern.decoratorpattern;

/**
*  @Description: 装饰器模式(包装模式Wrapper)
*   装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。
*   装饰器模式的本质就是动态组合,动态是手段,组合才是目的
*/
public class ClientMain {
public static void main(String[] args) {
//节点流
//        Component component = new ConcreteComponent();  //首先创建需要被装饰的原始对象(即要被装饰的对象)
//过滤流
//        Component component2 = new ConcreteDecorator1(component); //给对象透明的增加功能B并调用
//过滤流
//        Component component3 = new ConcreteDecorator2(component2);//给对象透明的增加功能C并调用
//        component3.doSomething();

Component component1 = new ConcreteDecorator1(new ConcreteDecorator2(new ConcreteComponent()));

component1.doSomething();

}
}


https://gitee.com/play-happy/base-project

参考:

[1] 博客, http://blog.csdn.net/hust_is_lcd/article/details/7884320

[2] 博客,http://www.runoob.com/design-pattern/decorator-pattern.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: