创建对象和多态

flo*_*ake 7 java polymorphism design-patterns

我想避免使用标记类和大的if-else块或切换语句,而是将多态性用于类层次结构,我相信这是更好的做法.

例如,类似于下面的内容,其中执行方法的选择仅依赖于Actor类型的对象的一个​​字段.

switch(actor.getTagField())
{
    case 1: actor.act1(); break;
    case 2: actor.act2(); break;
    [...]
}
Run Code Online (Sandbox Code Playgroud)

会成为

actor.act();
Run Code Online (Sandbox Code Playgroud)

并且act方法将在Actor的子类中被覆盖.

但是,在运行时决定实例化哪个子类的最明显的方法看起来与原始类似:

Actor newActor(int type)
{
    switch(type)
    {
        case 1: return new Actor1();
        case 2: return new Actor2();
        [...]
    }
}
Run Code Online (Sandbox Code Playgroud)

所以似乎没有真正获得任何东西; 逻辑刚刚被移动了.

有什么更好的方法呢?我能想出的唯一方法是为Actor的每个子类实现一个工厂类,但对于这样一个简单的问题,这似乎相当麻烦.

我是否想过这个?如果我在其他地方做同样的事情,似乎没有必要做出原始的改变.

lti*_*_sh 4

问题是“是否”您需要一家工厂。工厂的目的是管理实例的创建,而不是管理相关实例的行为。

否则,您只是在查看基本继承。就像是..

class Actor{
  public void act(){
    System.out.println("I act..");
  }
}

class StuntActor extends Actor {
  public void act(){
    System.out.println("I do fancy stunts..");
  }
}

class VoiceActor extends Actor {
  public void act(){
    System.out.println("I make funny noises..");
  }
}
Run Code Online (Sandbox Code Playgroud)

使用时,您可以直接实例化您需要的 Actor 类型。

Actor fred = new Actor();
Actor tom = new VoiceActor();
Actor sally = new StuntActor();

fred.act();
tom.act();
sally.act();
Run Code Online (Sandbox Code Playgroud)

输出:

I act..
I make funny noises..
I do fancy stunts..
Run Code Online (Sandbox Code Playgroud)

编辑:

如果您需要集中创建 Actors..aka 相对于工厂,您将无法摆脱某种切换逻辑 - 在这种情况下..我通常会使用枚举来提高可读性:

public class Actor{
  public enum Type{ REGULAR, VOICE, STUNT }

  public static Actor Create(Actor.Type type){
    switch(type) {
      case VOICE:
        return new VoiceActor();
      case STUNT:
        return new StuntActor();
      case REGULAR:
      default:
        return new Actor();
    }
  }

  public void act(){
    System.out.println("I act..");
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

Actor some_actor = Actor.Create(Actor.Type.VOICE);
some_actor.act();
Run Code Online (Sandbox Code Playgroud)

输出:

I make funny noises..
Run Code Online (Sandbox Code Playgroud)