gpt4 book ai didi

java - 具有不同契约(Contract)的装饰器模式

转载 作者:搜寻专家 更新时间:2023-11-01 03:33:06 24 4
gpt4 key购买 nike

在装饰器模式中,我对如何使用装饰器方法感到困惑。我了解到装饰器模式用于向基类添加函数。但是我只能调用最外层装饰器的方法,如果没有在interface中提到,我应该如何使用内层装饰器的方法。我的英语不好,所以我写代码来演示我的问题。

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;
}
}

正如我在注解中所问,当一个装饰器被另一个装饰器包裹时,只有在接口(interface)中声明的方法(如 cost()getDescription())才有效,另一个方法将不再被调用。我想如果我创建一个士兵,如果我使用枪装饰他将是 shoot() -- 枪的功能。如果我明天用剑装饰他,他不仅可以 shoot() 还可以 cut() -- 剑的功能。我可以用装饰器模式实现吗?对于任何误解,我深表歉意,感谢您的帮助。

最佳答案

正如人们在您的问题的评论中提到的那样,装饰器模式的使用方式并不完全相同。

使用您的士兵示例,装饰器将像这样工作:

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,除了行走之外还添加了射击方法。

您可以使用接口(interface)来确保某些功能在实现它们的类中可用。

这并不完全是你想要的“装饰”,但我认为这是你想要做的事情的方式。

关于java - 具有不同契约(Contract)的装饰器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42315140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com