在装饰模式中,我对如何使用装饰器方法感到困惑.我了解到装饰器模式用于向基类添加函数.但是我只能调用最外面的装饰器方法,所以我应该如何使用内部装饰器的方法,如果在接口中没有提到的话.我不擅长英语,所以我写代码来证明我的问题.
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())才会起作用,而另一个方法将不再被调用.我想如果我创造一个士兵,如果我用枪装饰他会射击() – 枪的功能.如果我明天用剑装饰他,他不仅可以射击()而且还可以削减()剑的功能.我可以用装饰模式实现吗?
对于任何误解我感到抱歉,感谢您的帮助.
最佳答案 正如人们在你的问题中的评论中提到的那样,装饰者模式并没有完全像那样使用.
使用你的士兵示例,装饰器将像这样工作:
public abstract class Soldier {
public abstract void attack();
}
public abstract class SoldierDecorator extends Soldier {
protected Soldier soldier;
public SoldierDecorator(Soldier soldier) {
this.soldier = soldier;
}
@Override
public abstract void attack();
}
然后
public class SoldierWithGun extends SoldierDecorator {
public SoldierWithGun(Soldier soldier) {
super(soldier);
}
@Override
public void attack() {
soldier.attack();
shootWithTheGun();
}
private void shootWithTheGun() {
System.out.println("Shooting with the gun...");
}
}
public class SoldierWithSword extends SoldierDecorator {
public SoldierWithSword(Soldier soldier) {
super(soldier);
}
@Override
public void attack() {
soldier.attack();
cutWithSword();
}
private void cutWithSword() {
System.out.println("Cutting with the sword...");
}
}
将你的士兵从装饰师传递给装饰者会增强他们的攻击力;
现在要添加行为/方法,您可以使用普通旧继承.
你可以通过扩展类来添加行为,BaseSoldier可以行走但是SoldierWithGun扩展了BaseSoldier,添加了一种除了行走之外拍摄的方法.
您可以使用接口来确保在实现它们的类中提供某些功能.
它并不是你想要的“装饰”,但我认为这是你想要做的事情的方法.