设计模式之装饰模式
来源:互联网 发布:golang教程 csdn 编辑:程序博客网 时间:2024/06/15 08:52
装饰模式定义:装饰模式动态的将责任附加到对象上,若要扩展功能,装饰模式提供了比继承更有弹性的替代方案
看下下面的例子,总共有两种咖啡:Decaf、Espresso,另有两种调味品:Mocha、Whip(3种设计的主要差别在于抽象方式不同)
设计一:
即使添加在多的调味品,咖啡依然是咖啡,在抽象的过程中并没有考虑咖啡和调味品之间的关系
当咖啡和调味品的种类很多时,将会产生大量的类,如果一种咖啡的价格发生变动,需要找到所有相关的类逐一修改
设计二:
public class Coffee { private boolean mocha ; private boolean whip ; public double cost() { double price = 0d; if (mocha ) { price += 0.5; } if (whip ) { price += 0.1; } return price ; } public void addMocha() { this.mocha = true; } public void addWhip() { this.whip = true; }}
public class Decaf extends Coffee { public double cost() { double price = super.cost(); price += 2.0; return price ; }}
public class Espresso extends Coffee{ public double cost() { double price = super.cost(); price += 2.5; return price ; }}
public class Test { public static void main(String[] args) { Coffee coffee = new Decaf(); coffee.addMocha(); coffee.addWhip(); //2.6 System. out.println(coffee .cost()); }}
1,如果调味品的种类较多,Coffee类将会变得相当庞大,难以维护
2,无法处理顾客希望添加双倍的Mocha的场景
3,添加一种新的咖啡IceCoffee,从逻辑上来说IceCoffee是不能加Mocha的,但是由于IceCoffee类继承自Coffee类,IceCoffee类依然从父类继承了addMocha()方法,这就需要在IceCoffee类中重写一个空的addMocha()方法,并且当使用IceCoffee类时,不能够面向Coffee类编程,以避免错误的调用父类方法
设计三--装饰器模式:
装饰模式分为3个部分:
1,抽象组件 -- 对应Coffee类
2,具体组件 -- 对应具体的咖啡,如:Decaf,Espresso
3,装饰者 -- 对应调味品,如:Mocha,Whip
装饰模式有3个特点:
1,具体组件和装饰者都继承自抽象组件(Decaf、Espresson、Mocha和Whip都继承自Coffee),并且装饰者持有抽象组件的引用
2,可以使用装饰者组合具体组件创造出新的类(Mocha组合Decaf创造出MochaDecaf)
3,过程2可以重复,直到创造出需要的类
使用装饰模式,想要获得一个WhipDoubleMochaEspresso是很容易的:
public interface Coffee { public double cost(); }
public class Espresso implements Coffee{ @Override public double cost() { return 2.5; }}
public class Dressing implements Coffee { private Coffee coffee; public Dressing(Coffee coffee) { this.coffee = coffee ; } public double cost() { return coffee .cost(); }}
public class Whip extends Dressing{public Whip(Coffee coffee) {super(coffee);}public double cost() {return super.cost() + 0.1;}}public class Mocha extends Dressing {public Mocha(Coffee coffee) {super(coffee);}public double cost() {return super.cost() + 0.5;}}
public class Test {public static void main(String[] args) {Coffee coffee = new Espresso();coffee = new Mocha(coffee);coffee = new Mocha(coffee);coffee = new Whip(coffee);// 3.6(2.5 + 0.5 + 0.5 + 0.1)System.out.println(coffee.cost());}}
装饰模式的缺点:
1,装饰模式虽然扩展性较高,但是没有设计二简洁,类的数量略多(但肯定比设计一少很多),如何取舍可扩展性和简洁性是个问题,有所选择就要有所牺牲
- 设计模式之装饰
- 设计模式之装饰
- 设计模式之装饰
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之 装饰模式
- 设计模式之-装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- I
- c++ poco StreamSocket tcpclient测试用例
- Scala的implicit
- MongoDB——GridFS
- “可变参数列表”的学习
- 设计模式之装饰模式
- python中的坐标表示方法
- 同时安装office2016s,visio,project
- 拓扑(有向图判断环)—— HDU 5961
- Tensorflow BN
- Java线程池
- 最长公共子序列
- 树形Dp
- 虚幻引擎的TArray:数组