gpt4 book ai didi

java - 您如何使实用程序类处理子类中的差异?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:51:24 24 4
gpt4 key购买 nike

这可能是一个不好的例子,但请使用它。我有一个父类(super class) Cake 和两个子类:ExampleCakeSaleCake。我还有一个 Baker,他可以对蛋糕进行逆向工程以烘烤它的副本,并且知道之后如何处理它。

(全是伪代码)

public class Cake{
radius;
height;
ingredients;
color;
name;
}

public class ExampleCake extends Cake{
shelfLocation;
}

public class SaleCake extends Cake{
owner;
}

public class Baker{
Cake bakeCake(Cake);
Cake bakeSaleCake(Cake, Owner);
Cake bakeExampleCake(Cake, Location);

void handleCake(Cake);
}

Baker 需要知道如何处理通用 Cakes、ExampleCakes 和 SaleCakes。所以他的 bakeCake 函数看起来像这样:

Cake bakeCake(cake){
newCake = cake.copy();
mixIngredients(newCake);
putCakeInOven(newCake);
putIcing(newCake);
return cake;
}

Cake bakeSaleCake(cake, owner){
newCake = bakeCake(cake);
newCake.setOwner(owner);
return newCake;
}

Cake bakeExampleCake(cake, location){
newCake = bakeCake(cake);
newCake.setLocation(location);
return newCake;
}

void handleCake(cake){
if(cake instanceof ExampleCake)
putOnShelf((ExampleCake)cake);

else if(cake instanceof SaleCake)
giveToCustomer((SaleCake)cake);

else
putOnTable(cake);
}

我的问题是 Baker 被硬编码为只能处理某些类型的蛋糕。如果出现新类型的蛋糕,他将无法处理它们。有没有一种干净、通用的方法来处理这个问题,或者我上面的伪代码有点“足够好”(比如,它不会伤害你的眼睛或心脏)?

谢谢。

最佳答案

要复制蛋糕,您可以使用复制构造函数。这样就取决于具体的蛋糕如何 self 复制。要处理任意蛋糕,您可以使用访客模式。通过访问者,您可以“询问”蛋糕的类型,而不用使用 instanceof 检查类型。

代码可能如下所示(除了复制构造函数之外,您还需要其他 Cake 构造函数):

//蛋糕类

public class Cake{
int radius;
int height;

public Cake(Cake cake){
this.radius = cake.radius;
this.height = cake.height;
}

<R> R accept(CakeVisitor<? extends R> visitor){
return visitor.visit(this);
}

}

//示例蛋糕类

public class ExampleCake extends Cake{
String shelfLocation;

public ExampleCake(Cake cake, String shelfLocation){
super(cake);
this.shelfLocation = shelfLocation;
}

<R> R accept(CakeVisitor<? extends R> visitor){
return visitor.visit(this);
}

}

//销售蛋糕类

public class SaleCake extends Cake{
String owner;

public SaleCake(Cake cake, String owner){
super(cake);
this.owner = owner;
}

<R> R accept(CakeVisitor<? extends R> visitor){
return visitor.visit(this);
}

}

//访客界面

public interface CakeVisitor<R> {

R visit(Cake cake);
R visit(SaleCake cake);
R visit(ExampleCake cake);

}

//烘焙类

public class Baker {
private final CakeVisitor<Void> cakeHandler = new CakeVisitor<Void>(){

@Override
public Void visit(Cake cake) {
putOnTable(cake);
return null;
}

@Override
public Void visit(SaleCake cake) {
giveToCustomer(cake);
return null;
}

@Override
public Void visit(ExampleCake cake) {
putOnShelf(cake);
return null;
}

};

Cake bakeCake(Cake cake){
return processedCake(new Cake(cake));
}

SaleCake bakeSaleCake(Cake cake, String owner){
return processedCake(new SaleCake(cake, owner));
}

ExampleCake bakeExampleCake(Cake cake, String location){
return processedCake(new ExampleCake(cake, location));
}

void handleCake(Cake cake){
cake.accept(cakeHandler);
}

private <C extends Cake> C processedCake(C cake){
mixIngredients(cake);
putCakeInOven(cake);
putIcing(cake);
return cake;
}
}

现在,如果您想用 Baker 处理一种新型蛋糕,默认情况下会将其放在 table 上,除非您提供一个专门接受新蛋糕类型对象的访问方法。我认为你真的不能让它比这更通用,因为当你有一种新型 Cake 时,你希望以不同于其他类型蛋糕的方式处理它,并且处理它的新代码必须放在某个地方。像 putOnTable() 这样的代码不应该放在蛋糕类中,因为蛋糕不知道它是如何放在 table 上的——面包师知道 -> 因此是访问者模式。

关于java - 您如何使实用程序类处理子类中的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41863879/

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