java - 根据构造函数参数实例化特定的子类型

标签 java polymorphism guice instantiation instanceof

我有四种类型的数据对象:

class DataTypeAlpha extends DataType
class DataTypeBeta extends DataType
class DataTypeGamma extends DataType
class DataTypeDelta extends DataType

以及来自 GUI 框架的四种不同的 TreeNode 类型,每一种都特定于包装的 DataType:

class AlphaTreeNode extends MyAppTreeNode
...

现在我经常遇到这样的模式:我有一个 DataType 实例,但需要一个新的 MyAppTreeNode 实例。我看到两个解决方案。解决方案一:

class DataType {
  // Instantiates and returns the appropriate MyAppTreeNode for this DataType
  abstract MyAppTreeNode createTreeNode();
}

解决方案二:

class MyAppTreeNode {
  static MyAppTreeNode createTreeNodeForDataType(DataType dataType) {
    if(dataType instanceOf DataTypeAlpha) return new AlphaTreeNode((DataTypeAlpha)dataType)
    else if (dataType instanceOf DataTypeBety) return new BetaTreeNode((DataTypeBeta)dataType)
    else if ...
    else if ...
    else throw new IllegalArgumentException();
  }
}

解决方案一使用多态性,更短,更“优雅”。但我希望 DataType 类不了解我使用的 GUI 框架。也许我什至可以使用两个不同的 GUI 框架?

您看到第三种解决方案吗?我在这个问题中添加了 Guice 标签。也许 Guice 或其他依赖注入(inject)库中有一些函数可以在这里提供帮助?

查看类似的问题:

  • 当然,我会为此使用工厂模式,但在工厂内部我仍然有问题。

最佳答案

为此,您可以使用受访客启发的方法。与往常一样,所有 DataType 对象都有一个 accept 方法,但与普通访问者模式相反,它不会遍历子对象,并且会返回一个值。为了避免太多困惑,让我们为 operator 而不是 visitor 调用传递给 accept 的对象。诀窍是让 acceptoperators 返回泛型类型。

所以数据模型中的代码将是这样的

public abstract class DataType {
  public abstract <T> T accept(Operator<T> op);
}

public interface Operator<T> {
  T operateAlpha(DataTypeAlpha data);
  T operateBeta(DataTypeBeta data);
  ...
}

public class DataTypeAlpha extends DataType {
  public <T> T accept(Operator<T> op) {
    return op.operateAlpha(this);
  }
}
....

在 GUI 中您将拥有

public class TreeNodeFactory implements Operator<MyAppTreeNode> {
    public MyAppTreeNode operateAlpha(DataTypeAlpha data) {
      return new AlphaTreeNode(data);
    }
    ...
 }

 public class MyAppTreeNode {
   static TreeNodeFactory factory = ...;
   static MyAppTreeNode createTreeNodeForDataType(DataType dataType) {
     return dataType.accept(factory);
   }       
 }

关于java - 根据构造函数参数实例化特定的子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17230283/

相关文章:

java - Play 中的 CConvertException!框架

java - 我很难启动我的 IntellijIDEA 2019.2

java - 是否可以将依赖项绑定(bind)到 TestNG 中的拦截器?

java - 如何通过双击删除行?

java - Spring (Boot) 忽略了我的 log4j.properties 文件

module - 使用多态递归模块创建访问者模式

c++ - g++ "because the following virtual functions are pure"带抽象基类

C++基类指针调用子虚函数,为什么基类指针能看到子类成员

dependencies - 使用 Guice(或 Spring)注入(inject)列表

java - 如何配置 Guice 3.0 的 Maven 依赖项以便在没有 AOP 的情况下使用?