目录
装饰者模式前言基本介绍具体案例实现装饰者模式总结
装饰者模式
前言
通过一个案例来解释为什么要用装饰模式要完成这个案例的方法有很多种,传统方式是这样解决的:
根据上面一个方案的问题,提出了一个更好一点的方案:
但是方案二还是有问题,在增加和删除调料的时候,代码的维护量还是很多。 所以就是用装饰者模式去解决这一案例
基本介绍
装饰者模式: 动态的 将新功能 附加到对象上 。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则这里提到的动态的将新功能附加到对象 和 ocp 原则 ,在后面的应用实例上会以代码的形式体现。
具体案例实现
类图代码实现:
public abstract class Drink {
public String des
;
public double price
;
public String
getDes() {
return des
;
}
public void setDes(String des
) {
this.des
= des
;
}
public Double
getPrice() {
return price
;
}
public void setPrice(Double price
) {
this.price
= price
;
}
public abstract double cost();
public abstract String
print();
}
public class Coffee extends Drink{
@Override
public double cost() {
return super.price
;
}
@Override
public String
print() {
return des
;
}
}
public class BlueMountain extends Coffee{
public BlueMountain() {
setDes("蓝山咖啡");
setPrice(10.0);
}
}
public class Espresso extends Coffee{
public Espresso() {
setDes("意大利咖啡");
setPrice(6.0);
}
}
public class Decorator extends Drink{
private Drink drink
;
public Decorator(Drink drink
) {
this.drink
= drink
;
}
@Override
public double cost() {
return drink
.cost()+price
;
}
@Override
public String
print() {
return des
+ drink
.des
;
}
}
public class Milk extends Decorator{
public Milk(Drink drink
) {
super(drink
);
setDes("牛奶");
setPrice(1.0);
}
}
public class Chocolate extends Decorator{
public Chocolate(Drink drink
) {
super(drink
);
setDes("巧克力");
setPrice(2.0);
}
}
public class Client {
public static void main(String
[] args
) {
Drink order
= new BlueMountain();
System
.out
.println(order
.print()+" 价格为:"+order
.cost());
order
= new Milk(order
);
System
.out
.println(order
.des
+" 价格为:"+order
.price
);
System
.out
.println(order
.print()+" 价格为:"+order
.cost());
order
= new Chocolate(order
);
System
.out
.println(order
.des
+" 价格为:"+order
.price
);
System
.out
.println(order
.print()+" 价格为:"+order
.cost());
}
}
结果:
装饰者模式总结
装饰者模式的优点:
目的在于扩展对象的功能。装饰者模式提供比继承更好的灵活性。装饰是动态的,运行时可以修改的;继承是静态的,编译期便已确定好。通过使用不同的装饰类及对它们的排列组合,可以创造出许多不同行为的组合。 装饰者模式的缺点:
利用装饰者模式,常常造成设计中有大量的小类,数量太多,会造成使用此API的人带来困扰,不容易理解。采用装饰者在实例化组件时,将增加代码复杂度。一旦使用装饰者,不仅要实例化组件,同时要将组件实例包装进装饰者。调试时不易排查错误。 适用场景:
需要扩展一个类的功能, 或给一个类增加附加功能。需要动态地给一个对象增加功能, 这些功能可以再动态地撤销。需要为一批的兄弟类进行改装或加装功能, 当然是首选装饰模式