设计模式原则
- 不变的和变化的分开。
- 针对接口编程,而不针对实现编程。
- 多考虑组合,而不是继承。
- 为了交互对象之间的松耦合设计而努力。
- 开闭原则,对外支持扩展不支持修改。
装饰者模式
动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
例:
- 我们有一个抽象类是饮料的超类:Beverage,下便有很多的格式饮料继承了超类,那么我们在扩展各种的调料,加载不同的子类中,会需要很多代码的修改,但是统一写在超类中,子类中又会多很多自己不需要的代码。
- 我们要解决这个问题,考虑到装饰者模式,以修饰的方式来修饰主体(各种饮料)。
设计思想
- 考虑第五条设计原则,那么我们要考虑,不修改饮料超类,而完成扩展,我们要以不同的调料类来修饰不同的饮料。
总结: 根据上述所说我们现在共有: - 饮料超类1个
- 调料超类1个
- N个饮料品种
- N个调料品种
类设计如下
饮料抽象类
public abstract class Beverage {
// String description = "Unknown Beverage";
String description = "未知饮料";
public String getDescription() {
return description;
}
public abstract double cost();
}
调料抽象类
// 继承 Beverage 是为了 获取 Beverage的类型
public abstract class CondimentDecorator extends Beverage{
// 获取调料名称
public abstract String getDescription();
}
意大利浓缩咖啡
public class Espresso extends Beverage{
public Espresso(){
description = "意大利浓咖啡";
// description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
统计类
public class HouseBlend extends Beverage{
public HouseBlend(){
description = "混合饮料";
// description = "HouseBlend";
}
@Override
public double cost() {
return 1.55;
}
}
混合咖啡类
public class Data implements Observer{
@Override
public void update(Object obj) {
WeatherData.Obj ob = (WeatherData.Obj) obj;
System.out.println(ob.getI() + " " + ob.getJ());
}
}
摩卡类
public class Mocha extends CondimentDecorator{
Beverage beverage ;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " Mocha ";
}
@Override
public double cost() {
return 0.75 + beverage.cost();
}
}
豆浆调料
public class Soy extends CondimentDecorator{
Beverage beverage ;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " Soy ";
}
@Override
public double cost() {
return 0.88 + beverage.cost();
}
}
测试类
public class Text {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println("饮料是 " + beverage.getDescription() + " 价格:"+ beverage.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Soy(beverage2);
System.out.println("饮料是 " + beverage2.getDescription() + " 价格:"+ beverage2.cost());
}
}
测试结果
PS: java.io.*;中 也是使用了装饰者模式,大家可以浏览源码来加深理解