在装饰模式,我很困惑如何使用装饰方法。我已经了解到,装饰器模式用于将函数添加到基类。但是我只能调用最外层的装饰器的方法,所以如果在接口中没有提到,我应该如何使用inner-decorator的方法。我不擅长英语,所以我编写代码来演示我的问题。装修模式与合同
public class OrderSystem {
public static void main(String[] args) {
Pancakes pancakes = new MixedPancakes();
pancakes = new Ham(pancakes);
((Ham) pancakes).hamState(); // call hamState
pancakes = new Egg(pancakes);
((Egg) pancakes).eggState();
// i can't call hamState() there because it not belong to Egg
Pancakes pancakes1 = new Ham(new Egg(new FlourPancakes()));
// similarly, i can't use eggState() there.
System.out.println("订单:" + pancakes1.getDescription());
System.out.println("价格:" + pancakes1.cost());
}
}
interface Pancakes {
public abstract String getDescription();
public abstract int cost();
}
abstract class Seasoning implements Pancakes {
@Override
public abstract String getDescription();
}
class Ham extends Seasoning {
Pancakes pancakes;
public Ham(Pancakes pancakes) {
this.pancakes = pancakes;
}
@Override
public int cost() {
return pancakes.cost() + 2;
}
@Override
public String getDescription() {
return pancakes.getDescription() + "+火腿";
}
public void hamState() {
System.out.println("火腿切碎");
}
}
class Egg extends Seasoning {
Pancakes pancakes;
public Egg(Pancakes pancakes) {
this.pancakes = pancakes;
}
@Override
public int cost() {
return pancakes.cost() + 1;
}
@Override
public String getDescription() {
return pancakes.getDescription() + "+鸡蛋";
}
public void eggState() {
System.out.println("鸡蛋打碎");
}
}
class MixedPancakes implements Pancakes {
@Override
public String getDescription() {
return "五谷杂粮煎饼";
}
@Override
public int cost() {
return 6;
}
}
class FlourPancakes implements Pancakes {
@Override
public String getDescription() {
return "白面煎饼";
}
@Override
public int cost() {
return 5;
}
}
当我问注释,当装饰用另一个包裹,只在接口中声明的方法(如cost()
和getDescription()
)将工作,而另一种方法将不再被调用。我想如果我创造一个士兵,如果我使用枪装饰他将是shoot()
- 枪的功能。如果我明天用剑装饰他,他不仅可以shoot()
,而且还有cut()
- 剑的功能。我可以用装饰模式实现它吗? 对于任何误解和感谢您的帮助,我很抱歉。
装饰者的要点不是添加方法。这是为了使装饰对象的方法做更多*或*不同*。装饰器应该与正在装饰的对象具有相同的类型。例如,一个BufferedReader装饰另一个读者。它的read()方法委托给装饰阅读器的read()方法,但在顶部添加缓冲区。 –
@JBNizet,我认为这应该是一个答案,而不是评论。 –
@GrzegorzGórkiewicz那不会回答这个问题。 – CKing