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. 需要有装饰类,装饰类可以装饰其它对象,即:入参需要是被装饰者或者其上级类,(面向接口编程)
暂时就这些,后期补充.

浙公网安备 33010602011771号