导读:如果感觉有点困难,请看后面的例子和最后一句话
开始的思维:
这是一个父类,假设是某种产品的总称,比如:饮料(beverage):
public class Beverage {
private String description;//产品的描述
public String getDescription(){//返回产品的描述
return this.description;
}
public String cost(){ //由子类继承来返回当前产品的价格
return "no chird";
}
}
如果有很多产品,那么就需要建立很多的子类,导致维护的时候就会变得非常麻烦。(子类继承cost() 只重写方法,返回对应的价格。 )
设计原则:类应该对扩展开发,对修改关闭。
我们的目标是允许类容易扩展,在不修改现有的代码的情况下,就可以搭配新的行为,如能实现这样的目标,有什么好处呢?这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的 需求。
正文开始:
要做到:
1.拿一个对象,比如DarkRoast(**咖啡)
2.以摩卡(Mocha)对象装饰它
3.对奶泡(Whip)对象装饰它
4.调用cost()方法,并依赖委托(delegate) 将调料的价格加上去
所谓装饰者就是分为两类,一类是装饰的对象,另一类是被装饰的对象。就像红豆牛奶,红豆是修饰者,牛奶是被修饰者,
在饮品店里,你可以单买牛奶,但是不可以单买红豆(配料)[不要钻牛角尖,认真你就输了.....] 所以我们在写程序的时候就需要实现两个类型的类。
那么现在是被装饰对象的主类,他是一个抽象对象(接口也可以,随你开心)
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return this.description;
}
public abstract Double cost();
}
它是所有的超类,主要的作用是把后面的子类的形态定住。
接下来是装饰者的抽象类
//首先,必须让Condiment Decorator 能够取代Beverage,所以将CondimentDecorator扩展自Beverage类
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();//所有的被装饰者都必须重新实现getDescription()方法。
}
让其作为上面超类的子类,也是为了把形态固定住,重命名肯定是必须的。
接下来是实现多个装饰对象
//摩卡(配料)
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 .20 + beverage.cost(); //组合价格
}
}
public class Whip extends CondimentDecorator{
Beverage beverage;
//把饮料(主体传入)
public Whip(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
@Override
public Double cost() {
return .30 + beverage.cost(); //组合价格
}
}
接下来是被装饰者
//浓缩咖啡
public class Espresso extends Beverage{
public Espresso(){
description = "Espresso";
}
@Override
public Double cost() {
return 1.99;
}
}
//另一种
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend";
}
@Override
public Double cost() {
return .89;
}
}
接下来是测试类:
public class StarbuzzCoffee {
public static void main(String args[]) {
Beverage beverage = new Espresso();
//订一杯Espresso 不加调理 打印价格
System.out.println(beverage.getDescription()
+ " $" + beverage.cost());
Beverage beverage1 = new HouseBlend();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);//加入第二份
beverage1 = new Whip(beverage1);
System.out.println(beverage1.getDescription()
+ " $" + beverage1.cost());
}
}