避免在工厂方法中使用instanceof

时间:2016-11-11 16:25:00

标签: java factory instanceof

我正在寻找以下问题的改进解决方案。我有一个物品,它被送到工厂;工厂将检查对象类型,创建另一个类型,它使用来自传入对象的数据填充,然后返回新对象。

...

public MyAbstractClass create(MyObject a) {

    if (a instanceof A) {
        A obj = (A) a;
        return new MyAbstractClass_1 (obj.getField(), factoryField);
    } 
    else if (a instanceof B) {
        B obj = (B) a;
        return new  MyAbstractClass_2 (obj.getSomething(), obj.getSomethingElse(), factoryField);
    } 

}

返回类型的实例通常在后面处理。展望未来我需要支持更多类型,如果可能的话,我想避免使用instanceof解决方案。我怎样才能改善这个?

2 个答案:

答案 0 :(得分:2)

您可以将创建方法添加到MyObject吗?这样你就不再需要实例,因为MyObject的每个实例都知道如何“创建”。你不会再有工厂了:(

它看起来像(假设MyObject是一个接口。如果它是一个类,那么只是扩展):

interface MyObject {
  ...
  public MyAbstractClass create(MyObject a);
  ...
}

public class A implements MyObject {
  ...
  public MyAbstractClass create(MyObject a) {
    return new MyAbstractClass_1 (obj.getField(), factoryField);
  }
  ...
}

public class B implements MyObject {
  ...
  public MyAbstractClass create(MyObject a) {
    return new MyAbstractClass_2 (
      obj.getSomething(),
      obj.getSomethingElse(),
      factoryField);
  }
  ...
}

答案 1 :(得分:0)

if语句的正文应该是MyObject上的虚拟或抽象成员。

abstract class MyObject {
   public abstract MyAbstractClass create();
}

class A extends MyObject {
   @Override
   public MyAbstractClass create(Object factoryField) {
      return new MyAbstractClass_1 (this.getField(), factoryField);
   }
}

class B extends MyObject {
   @Override
   public MyAbstractClass create(Object factoryField) {
      return new  MyAbstractClass_2 (this.getSomething(), this.getSomethingElse(), factoryField);
   }
}

通常,当您看到自己根据具体类型检查对象的类型以执行不同的操作时,这可能意味着您应该使用多态,并且代码应该自己进入具体类型。

更新了MyObject数据应来自当前实例,而不是作为参数传递,正如您所指出的那样。唯一的问题是,我不确定你现在放置factoryField的位置。您可以将其作为参数传递给上面,因为这些是虚拟成员,您仍然可以拥有工厂:

class SomeFactory {
   private Object factoryField;

   public SomeFactory(Object factoryField) {
      this.factoryField = factoryField;
   }

   public MyAbstractClass create(MyObject a) {
      return a.create(factoryField);
   }
}