(java)从零开始之--装饰者设计模式
2016-04-18 23:26
369 查看
装饰者设计模式:
简单定义:增强一个类的功能,而且还可以让这些装饰类互相装饰。
应用场景:当要在某个功能的基础上扩充功能,并且扩充的功能具有大量排列组合,通过继承关系会衍生出大量子类,这时候用装饰者模式来解决。
装饰者设计模式的步骤:
1. 在装饰类的内部维护一个被装饰类的引用。
2. 让装饰类有一个共同的父类或者是父接口。
例如:人有一种行为叫“吃水果”,其中水果有4种:苹果、香蕉、鸭梨、橘子
现在有需求如下:
A类人行为:吃苹果
B类人行为:先吃苹果,再吃香蕉
C类人行为:先吃香蕉,再吃苹果
D类人行为:先吃橘子,后吃鸭梨
我们先用子类继承来实现:代码如下
这样当然是没问题的,每一类人对应new出来的对象 都可以实现对应的需求。
但是,当需求改为:
某类人行为:吃上面四种水果,并且要求有先后顺序
这样的排列组合有24种....
这样你还会用继承去做吗?写24个子类去实现接口,明显不合适。
这时候如果用到装饰者模式,代码则会变成:
输出结果如下:
吃橘子
吃苹果
-------我是分割线------------
吃苹果
吃橘子
吃鸭梨
吃香蕉
最后总结:
继承实现的增强类和修饰模式实现的增强类有何区别?
继承实现的增强类:
优点:代码结构清晰,而且实现简单.
缺点:对于每一个的需要增强的类都要创建具体的子类来帮助其增强,这样会导致
继承体系过于庞大。
装饰者模式实现的增强类:
优点:内部可以通过多态技术对多个需要增强的类进行增强, 可以使这些装饰类
达到互相装饰的效果。使用比较灵活。
缺点:需要内部通过多态维护需要被增强的类的实例。进而使得代码稍微复杂
简单定义:增强一个类的功能,而且还可以让这些装饰类互相装饰。
应用场景:当要在某个功能的基础上扩充功能,并且扩充的功能具有大量排列组合,通过继承关系会衍生出大量子类,这时候用装饰者模式来解决。
装饰者设计模式的步骤:
1. 在装饰类的内部维护一个被装饰类的引用。
2. 让装饰类有一个共同的父类或者是父接口。
例如:人有一种行为叫“吃水果”,其中水果有4种:苹果、香蕉、鸭梨、橘子
现在有需求如下:
A类人行为:吃苹果
B类人行为:先吃苹果,再吃香蕉
C类人行为:先吃香蕉,再吃苹果
D类人行为:先吃橘子,后吃鸭梨
我们先用子类继承来实现:代码如下
interface IEatFruit{ public void eatFruit(); } class PersonA implements IEatFruit{ @Override public void eatFruit() { System.out.println("吃苹果"); } } class PersonB implements IEatFruit{ @Override public void eatFruit() { System.out.println("吃苹果"); System.out.println("吃香蕉"); } } class PersonC implements IEatFruit{ @Override public void eatFruit() { System.out.println("吃香蕉"); System.out.println("吃苹果"); } } class PersonD implements IEatFruit{ @Override public void eatFruit() { System.out.println("吃橘子"); System.out.println("吃鸭梨"); } }
这样当然是没问题的,每一类人对应new出来的对象 都可以实现对应的需求。
但是,当需求改为:
某类人行为:吃上面四种水果,并且要求有先后顺序
这样的排列组合有24种....
这样你还会用继承去做吗?写24个子类去实现接口,明显不合适。
这时候如果用到装饰者模式,代码则会变成:
interface IEatFruit{ public void eatFruit(); } class PersonA implements IEatFruit{ IEatFruit eat; public PersonA(){ this.eat = this; } public PersonA(IEatFruit _eat){ this.eat = _eat; } @Override public void eatFruit() { if(!(this.eat instanceof PersonA)){ this.eat.eatFruit(); System.out.println("吃苹果"); }else{ System.out.println("吃苹果"); } } } class PersonB implements IEatFruit{ IEatFruit eat; public PersonB(){ this.eat = this; } public PersonB(IEatFruit _eat){ this.eat = _eat; } @Override public void eatFruit() { if(!(this.eat instanceof PersonB)){ this.eat.eatFruit(); System.out.println("吃香蕉"); }else{ System.out.println("吃香蕉"); } } } class PersonC implements IEatFruit{ IEatFruit eat; public PersonC(){ this.eat = this; } public PersonC(IEatFruit _eat){ this.eat = _eat; } @Override public void eatFruit() { if(!(this.eat instanceof PersonC)){ this.eat.eatFruit(); System.out.println("吃鸭梨"); }else{ System.out.println("吃鸭梨"); } } } class PersonD implements IEatFruit{ IEatFruit eat; public PersonD(){ this.eat = this; } public PersonD(IEatFruit _eat){ this.eat = _eat; } @Override public void eatFruit() { if(!(this.eat instanceof PersonD)){ this.eat.eatFruit(); System.out.println("吃橘子"); }else{ System.out.println("吃橘子"); } } } public class Demo2 { public static void main(String[] args) { //这样就可以通过上述4类人来相互装饰,就可以随意任意一种组合“吃水果” //如:吃橘子->吃苹果 PersonD d = new PersonD(); PersonA a = new PersonA(d); a.eatFruit(); System.out.println("-------我是分割线------------"); //如:吃苹果->吃橘子->吃鸭梨->吃香蕉 PersonA a2 = new PersonA(); PersonD d2 = new PersonD(a2); PersonC c2 = new PersonC(d2); PersonB b2 = new PersonB(c2); b2.eatFruit(); } }
输出结果如下:
吃橘子
吃苹果
-------我是分割线------------
吃苹果
吃橘子
吃鸭梨
吃香蕉
最后总结:
继承实现的增强类和修饰模式实现的增强类有何区别?
继承实现的增强类:
优点:代码结构清晰,而且实现简单.
缺点:对于每一个的需要增强的类都要创建具体的子类来帮助其增强,这样会导致
继承体系过于庞大。
装饰者模式实现的增强类:
优点:内部可以通过多态技术对多个需要增强的类进行增强, 可以使这些装饰类
达到互相装饰的效果。使用比较灵活。
缺点:需要内部通过多态维护需要被增强的类的实例。进而使得代码稍微复杂
相关文章推荐
- 提高 MyEclipse 开发速度
- JAVA动态代理(jdk和cglib)
- 学习javacv入门示例1:图像的读取显示翻转处理
- springMVC+freeMarker表单验证
- java编译运行原理
- java内部类设计的作用详解
- 解决普通文件夹转化为Eclipse工程
- Java中的int与Integer对比
- 论Jdk1.7 HashMap实现
- Struts的配置问题
- Struts的意义
- 有关java并发程序同步概念的全部意义
- servlet跳转出错的一个可能
- java制作登陆窗口示例
- Java中String类总结
- Myeclipse工具栏快捷图标丢失后找回
- Struts2框架中OGNL表达式的学习
- 4.Java中获取当前目录的方法
- 关于java中bean拷贝的思考
- javaweb怎么用eclipse连接mysql