设计模式六(IO的不之情-装饰者模式)

前言

java中对象的增强手段大致有三种,继承、装饰者模式、动态代理。先来看看三者的特点:

继承

被增强的对象是固定的
增强的内容也是固定的

装饰者

被增强的对象是可以切换的
增强的内容是固定的

动态代理

被增强的对象是可以切换的
增强的内容也是可以切换的

定义

Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案。

类图

设计模式六(IO的不之情-装饰者模式)_第1张图片
2017-11-25_163302.png

通过类图,我们大致可以看到,装饰者模式有四个角色,被装饰者父接口、被装饰者、装饰者父类,具体装饰者

这里需要注意的是,上类图只是一个完整的装饰者结构,但其实装饰者还是可以有很多改变的地方的,
1、Component接口可以是接口也可以是抽象类,甚至是一个普通的父类
2、装饰器的抽象父类Decorator并不是必须的。

一个demo实例

一个被装饰者接口

/**
 * 被一个装饰接口
 */
public interface Component {
    void fun();
}

一个被装饰者实现类

/**
 * 被装饰对象
 */
public class ConcreteComponent implements Component {

    public void fun() {
        System.out.println("原来的方法!");
    }
}

一个装饰者父类(这里注意,此类要实现与被装饰类相同的接口)

/**
 * 装饰者
 * ClassName: Decorator
 */

//是你  
public class Decorator implements Component {
    //还有你  
    protected Component component;
    
    public Decorator(Component component) {
        super();
        this.component = component;
    }   

    @Override
    public void fun() {
        //component子类对象
        component.fun();// 一切拜托你        
    }
}

若干个装饰者

//A装饰类
public class ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    
    /**
     * 扩展的一个方法
     */
    public void method(){
        System.out.println("扩展的方法!A");
    }
    
    /**
     * 对之前方法进行加强
     */
    public void fun(){
        System.out.println("原方法功能的加强前:包装开始 A");
        super.fun();
        System.out.println("原方法功能的加强后:包装结束 A");
    }
}



//B装饰类
public class ConcreteDecoratorB extends Decorator {

    public ConcreteDecoratorB(Component component) {
        super(component);
    }
    
    /**
     * 扩展的一个方法
     */
    public void method(){
        System.out.println("扩展的方法!B");
    }
    
    /**
     * 对之前方法进行加强
     */
    public void fun(){
        System.out.println("原方法功能的加强前:包装开始 B");
        super.fun();
        System.out.println("原方法功能的加强后:包装结束 B");
    }
}

测试类

public class App{

    public static void main(String[] args) {
        //原来的对象
        Component component = new ConcreteComponent();
        
        System.out.println("---------------------");
        component.fun();//调用原来的方法
        
        
        //装饰A(装饰原对象)
        ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA(component);//装饰A,对原来compent对象进行装饰
        System.out.println("----------------------");
        concreteDecoratorA.fun();
        concreteDecoratorA.method();
        
        //装饰B(装饰原对象)
        ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB(component);//装饰B,对原来compent对象进行装饰
        System.out.println("----------------------");
        concreteDecoratorB.fun();
        concreteDecoratorB.method();
        
        //装饰B(装饰A对象)
        concreteDecoratorB = new ConcreteDecoratorB(concreteDecoratorA);//装饰B,对A对象进行装饰
        System.out.println("----------------------");
        concreteDecoratorB.fun();
        concreteDecoratorB.method();
    }
}
设计模式六(IO的不之情-装饰者模式)_第2张图片
2017-11-25_164633.png

以上就是一个简单的装饰者,另外装饰的父类不是必须的,可以不要装饰父类直接进行装饰。写到这里,不知道大家有没有想到我们使用的IO缓冲流和Collections去创建同步的集合容器。

这里引用一张左盟主的图


设计模式六(IO的不之情-装饰者模式)_第3张图片
2017-11-25_165308.png
BufferedReader br = new BufferedReader(new FileReader(""));
BufferedWriter bw = new BufferedWriter(new FileWriter(""));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(""));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(""));

我们可以看到,对普通流装饰后得到高效的缓冲流。

总之,装饰器模式就是一个可以非常灵活的动态扩展类功能的设计模式,它采用组合的方式取代继承,使得各个功能的扩展更加独立和灵活。

你可能感兴趣的:(设计模式六(IO的不之情-装饰者模式))