寻求更好的设计,使用java进行多调度 [英] seek better design to have multi-dispatching with java
问题描述
在不支持多种调度的语言(如Java)中,代码可能看起来像这样。
In a language not supporting multiple dispatching, such as Java, the code would probably look something like this
/* Example using run time type comparison via Java's "instanceof" operator */
interface Collideable {
void collideWith(Collideable other);
}
class Asteroid implements Collideable {
public void collideWith(Collideable other) {
if (other instanceof Asteroid) {
System.out.println("AAAAAA");
} else if (other instanceof Spaceship) {
System.out.println("BBBBBB");
} else if (other instanceof Plane) {
System.out.println("CCCCCCC");
}
}
}
class Spaceship implements Collideable {
public void collideWith(Collideable other) {
if (other instanceof Asteroid) {
System.out.println("DDDDDDD");
} else if (other instanceof Spaceship) {
System.out.println("EEEEEEE");
} else if (other instanceof Plane) {
System.out.println("FFFFFFF");
}
}
}
class Plane implements Collideable {
public void collideWith(Collideable other) {
if (other instanceof Asteroid) {
System.out.println("GGGGGGG");
}else if (other instanceof Spaceship) {
System.out.println("HHHHHHH");
}else if (other instanceof Plane) {
System.out.println("KKKKKK");
}
}
}
随着访客模式的帮助为了解决这个问题,我在想,如果我应该把每个叶子类都用
void collideWith(){
visitor.visit(this); //访问者设置在setter
}
As the visitor pattern can help to solve this problem, I'm thinking if I should impl each leaf class with void collideWith() { visitor.visit(this); // visitor is set in the setter }
interface Visitor {
void visit(Collideable c);
void visit(Asteroid c);
void visit(Spaceship c);
void visit(Plane c);
}
然后,每个唯一的println应该在访问者的子类中实现如下?
Then each unique println should be implemented in subclass of visitor as below?
class AsteroidVisitor implements Visitor {
void visit(Collideable c) {}
void visit(Asteroid c) { System.out.println("AAAAAA"); }
void visit(Spaceship c) { System.out.println("BBBBBBB"); }
void visit(Plane c) { System.out.println("CCCCCC"); }
}
//etc for SpaceshipVisitor and PlaneVisitor()
是吗处理这种重构以替代instanceof的最好方法?
Is it the best way to deal with this kind of refactoring to replace instanceof?
编辑:打印输出只是每种方法中唯一操作的示例,而不是最终结果。我修改了我的例子来清楚。
The print out is just example of unique operations in each method, not the ultimate result. I modify my example to be clear.
推荐答案
在你给出的例子中,你不需要两个接口,只需要 Collideable
界面。 Collideable界面可以定义如下:
In the example you gave you don't need two interfaces you only need the Collideable
interface. The Collideable interface can be defined as follows:
interface Collideable {
void collideWith(Collideable other);
String getType();
}
然后太空船
平面
和小行星
将全部实施 collideWith
和的getType
。作为示例实现,Spaceship的实现将如下所示:
Then Spaceship
, Plane
, and Asteroid
would all implement collideWith
and getType
. As an example implementation, Spaceship's implementation would look like this:
class Spaceship implements Collideable {
public void collideWith(Collideable other) {
System.out.println(this.getType() + " collides with " + other.getType());
}
public String getType(){
return "Spaceship";
}
}
您可以进一步说明可竞争抽象类,提供collideWith的实现,因为它总是相同的。例如:
You can go one step further and declare Collideable as an abstract class, providing the implementation of collideWith since it is always the same. For example:
abstract class Collideable {
void collideWith(Collideable other){
System.out.println(this.getType() + " collides with " + other.getType());
}
String getType();
}
作为附注和一般提示,您的访客
界面设计差。接口的目的是定义实现该接口的所有类必须提供方法定义(实现)的方法。但是您的界面非常具体:它提供了几种类型( Spaceship
, Asteroid
等)作为方法参数。所以这是糟糕的设计,你为什么甚至需要这个界面呢?它看起来不像其他地方可以使用。
As a side note and general tip, your Visitor
interface is poor design. The purpose of an interface is to define methods that all classes implementing that interface must provide a method definition (implementation) of. However your interface is very specific: it provides several types (Spaceship
, Asteroid
, etc) as method parameters. Therefore it is bad design, why did you even need that interface to begin with? It doesn't look like it can be used anywhere else.
这篇关于寻求更好的设计,使用java进行多调度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!