Java设计模式——装饰者模式

欢迎探讨,一起进步。

装饰者模式:

动态地将责任附加到对象上,若要扩展功能,装饰者比继承更好,因为使用继承实现功能扩展,如果这些需要扩展的功能的种类很繁多,那么势必有很多子类,增加系统的复杂性。

下面是代码示例:代码有点多。

定义一个装饰者标识并添加两个方法

/**
 *  被装饰者标识类
 * @author wanghao
 * @version C10 2018年5月8日
 * @since SDP V300R003C10
 */
interface Target{
    public void add () ;
    public void remove();
}

定义一个装饰者

/**
 * 定义装饰者
 *
 * @author wanghao
 * @version C10 2018年5月8日
 * @since SDP V300R003C10
 */
class Messter implements Target{
    private Target target;
    
    Messter(Target target){
        this.target = target;
    }
    @Override
    public void add()
    {
        target.add();
    }
    @Override
    public void remove()
    {
        target.remove();
    }
}

然后定义两个装饰模式,第一个是提示语装饰模式,第二个是确认装饰模式:

class Decorator_One extends Messter{

    Decorator_One(Target target)
    {
        super(target);
    }
    public void addMessage() {
        System.out.println("我添加了");
    }
    public void removeMessage() {
        System.out.println("我删除了");
    }
    @Override
    public void add()
    {
        addMessage();
        super.add();
        System.out.println("添加成功");
    }
    @Override
    public void remove()
    {
        removeMessage();
        super.remove();
        System.out.println("删除成功");
    }
}
class Decorator_Two extends Messter{
    Scanner sc = new Scanner(System.in);
    Decorator_Two(Target target)
    {
        super(target);
    }
    public boolean enterAdd() {
        System.out.println("是否添加?");
        boolean b = sc.nextBoolean();
        if(b) {
            System.out.println("你确认添加");
        }else {
            System.out.println("你取消添加");
        }
        return b;
    }
    public boolean enterRemove() {
        System.out.println("是否删除?");
        boolean b = sc.nextBoolean();
        if(b) {
            System.out.println("你确认删除");
        }else {
            System.out.println("你取消删除");
        }
        return b;
    }
    @Override
    public void add()
    {
        if(!enterAdd())return;
        super.add();
        System.out.println("添加成功");
    }
    @Override
    public void remove()
    {
        if(!enterRemove())return;
        super.remove();
        System.out.println("删除成功");
    }
}

定义被装饰者,即真正的实现

/**
 * 定义被装饰者
 *
 * @author wanghao
 * @version C10 2018年5月8日
 * @since SDP V300R003C10
 */
class Decorator implements Target {
    @Override
    public void add()
    {
        System.out.println("+++++++++真正的添加操作,添加+1");
    }
    @Override
    public void remove()
    {
        System.out.println("—————————真正的删除操作,删除-1");
    }
}

总共测试四个,第一不加装饰模式打印,第二添加提醒模式打印,第三,添加开关模式打印,第四双重模式,

     //被装饰者
        Target decorator = new Decorator();
        //原始模式
        System.out.println("不加装饰,添加删除结果为:_________");
        decorator.add();
        decorator.remove();
        System.out.println("不加装饰,结果结束________________\n");
        
        //添加提醒装饰
        System.out.println("添加提醒装饰结果打印为:~~~~~~~~~~~~~");
        Target decorator01 = new Decorator_One(decorator);
        decorator01.add();
        decorator01.remove();
        System.out.println("添加提醒装饰,结果结束~~~~~~~~~~~~~~~\n");
        
        //添加开关装饰
        System.out.println("添加开关装饰结果打印为:~~~~~~~~~~~~~");
        Target decorator02 = new Decorator_Two(decorator);
        decorator02.add();
        decorator02.remove();
        System.out.println("添加开关装饰,结果结束~~~~~~~~~~~~~~~\n");
        
        //添加提醒+开关模式
        System.out.println("添加双重装饰打印结为~~~~~~~~~~~~~~~");
        Target decorator03 = new Decorator_One(new Decorator_Two(decorator)) ;
        decorator03.add();
        decorator03.remove();
        System.out.println("添加双重装饰,结果结束~~~~~~~~~~~~~~~");


先看结果吧:由于电脑屏幕较小,无法全部截取。下面会分批展示:

原始模式打印结果为:

添加提醒模式打印结果为:

添加开关模式打印结果为:

添加双重模式打印结果为: 重要的是装饰者模式,提示两次成功的就暂时不优化了,以后有机会优化

这样解耦和耦合比较灵活,我可以这样双重开关模式

Target decorator03 = new Decorator_Two(new Decorator_Two(decorator)) ;

也可以这样双重提醒模式:

Target decorator03 = new Decorator_One(new Decorator_One(decorator)) ;

如果,模式多了,我可以随便添加,随便装饰。是不是很灵活呢。

 重点来了,重点来了,重点来了,有没有看着眼熟 眼熟 熟呢???

对的,装甲IO流,就是装饰者模式。让我们一起来看一下源码吧,此次看源码只看装饰者模式,跟IO流无关,后期会补IO流总结。

看下面代码

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("")));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("")));

然后点进去看:

public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

我们可以发现,传入的参数是一个顶级接口。有可以包装的对象源对象(被装饰者), 还有包装类,可以包装其它对象,因为参数是顶级接口,所以接口下面的都可以包装,哈哈。

总结一下,装饰者模式:

1. 需要有被装饰对象,即源对象。

2. 需要有装饰类,装饰类可以装饰其它对象,即:入参需要是被装饰者或者其上级类,(面向接口编程)

暂时就这些,后期补充.

 


posted @ 2018-05-08 21:42  苦心明  阅读(445)  评论(0)    收藏  举报