继承,装饰者模式和动态代理之间的区别
2016-02-24 21:14
696 查看
Java中,需要对对象进行增强时,我们常用的三种方法是 继承, 装饰者模式和动态代理.现在,举个例子来描述这三者之间的区别.
在星巴克喝咖啡时, 可以选择各种调味品, 黑咖啡中可以选择加糖,加奶,加蜂蜜. 这样咖啡的味道被改变,我们可以说黑咖啡被"增强"了.用java代码这样表示:
这样子我们得到了三种不同口味的黑咖啡. 现在又有了新的问题, 要求要加奶又加糖的咖啡,需要给加奶的咖啡加上糖,用继承这样子来实现
可能还需要加奶加蜂蜜的咖啡... 多种排列组合就会出现很多类, 出现了新的一种口味又需要增加很多的类.
这时候我们用装饰者模式来解决这个问题
* 继承
被增强的对象固定的
增强的内容也是固定的
* 装饰者模式
被增强的对象是可以切换的
增强的内容是固定的
还有一种更加灵活的方式,面向切面编程(AOP) ,比装饰者模式更加灵活, 被增强的对象和增强的内容都是可以更换的.
在星巴克喝咖啡时, 可以选择各种调味品, 黑咖啡中可以选择加糖,加奶,加蜂蜜. 这样咖啡的味道被改变,我们可以说黑咖啡被"增强"了.用java代码这样表示:
/** * 创建一个咖啡的类,里面有黑咖啡 */ class Coffee{ void blankCoffee(){ System.out.println("黑咖啡"); } } /** * 现在要对黑咖啡加糖 */ class Sugar extends Coffee { void blankCoffee() { super.blankCoffee(); System.out.println("加糖"); } } /** * 现在要对黑咖啡加奶 */ class Milk extends Coffee { void blankCoffee() { super.blankCoffee(); System.out.println("加奶"); } } /** * 现在要对黑咖啡加蜂蜜 */ class Honey extends Coffee { void blankCoffee() { super.blankCoffee(); System.out.println("加蜂蜜"); } }
这样子我们得到了三种不同口味的黑咖啡. 现在又有了新的问题, 要求要加奶又加糖的咖啡,需要给加奶的咖啡加上糖,用继承这样子来实现
/** * 现在需要加奶加糖咖啡 */ class SugarMilke extends Milk { void blankCoffee() { super.blankCoffee(); System.out.println("加糖"); } } ...
可能还需要加奶加蜂蜜的咖啡... 多种排列组合就会出现很多类, 出现了新的一种口味又需要增加很多的类.
这时候我们用装饰者模式来解决这个问题
/** * 首先定义一个接口来规范咖啡. */ interface Coffee { void coffee(); } /* * 实现这个上面这个接口中的方法. */ class CoffeeImpl implements Coffee { public void coffee(){ System.out.println("黑咖啡"); } } /* * 在给黑咖啡添加调味品之前,我们先定义一个类,这个类是所有添加调味品咖啡的父类,进行包装 */ class CoffeeWrapper implements Coffee { private Coffee cof; public CoffeeWrapper(Coffee cof){ this.cof = cof; } public void coffee(){ cof.coffee(); } } /** * 加糖咖啡 */ class Sugar extends CoffeeWrapper { public Sugar(Coffee cof) { super(cof); } public void coffee(){ super.coffee(); System.out.println("加糖"); } } /** * 加奶咖啡 */ class Milk extends CoffeeWrapper { public Milk(Coffee cof) { super(cof); } public void coffee(){ super.coffee(); System.out.println("加奶"); } } /** * 蜂蜜咖啡 */ class Honey extends CoffeeWrapper { public Honey(Coffee cof) { super(cof); } public void coffee(){ super.coffee(); System.out.println("加蜂蜜"); } }
/** * 演示 */ public class Demo() { public static void main(String[] args) { //首先创建一个黑咖啡 Coffee cof = new CoffeeImpl(); //加糖咖啡 Coffee sugar = new Sugar(cof); sugar.coffee(); //加糖又加奶咖啡 Coffee milk = new Milk(sugar); sugar.coffee(); } }这样我们就解决了这个问题.
* 继承
被增强的对象固定的
增强的内容也是固定的
* 装饰者模式
被增强的对象是可以切换的
增强的内容是固定的
还有一种更加灵活的方式,面向切面编程(AOP) ,比装饰者模式更加灵活, 被增强的对象和增强的内容都是可以更换的.
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树