繁体   English   中英

在工厂方法中避免instanceof

[英]Avoiding instanceof in factory method

我正在寻找以下问题的改进解决方案。 我有一个对象,该对象已传递给工厂。 工厂将检查对象类型,创建另一个类型,并使用传入对象中的数据填充该类型,然后返回新的类型。

...

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解决方案。 我该如何改善?

您可以将create方法添加到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);
  }
  ...
}

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放在factoryField 您可以像上面一样将其作为参数传递,由于这些是虚拟成员,因此您仍然可以拥有一个工厂:

class SomeFactory {
   private Object factoryField;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM