寻求更好的设计,使用java进行多调度 [英] seek better design to have multi-dispatching with java

查看:98
本文介绍了寻求更好的设计,使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆