java - 如何为移至库的类工厂反转依赖关系

标签 java dependency-injection dependency-management library-project class-factory

当所有涉及的类都在同一个项目中时(determineSubClassBaseClass 的成员),以下代码工作得很好:

protected static BaseClass determineSubClass(String p1, int p2, Boolean p3) {

    BaseClass baseObj = null;
    if ( (baseObj = SubClassOne.ofType(p1, p2, p3)) != null )
      return baseObj;
    else if ( (baseObj = SubClassTwo.ofType(p1, p2, p3)) != null )
      return baseObj;
    else if ( (baseObj = SubClassThree.ofType(p1, p2, p3)) != null )
      return baseObj;
    else if ( (baseObj = SubClassFour.ofType(p1, p2, p3)) != null )
      return baseObj;
    else
      return new SubClassDefault(p1, p2, p3);
}

但是现在,我想将 BaseClass 移动到共享库项目中,其中 SubClassOneSubClassTwoSubClassThreeSubClassFour 在库中定义,而是在使用此库的应用程序中定义。

我当然可以将 BaseClass 移回每个使用该库的应用程序,但我想知道:

  • 有更好的解决方案吗?
  • 有没有一个解决方案可以让我 将 BaseClass 保存在库中 项目并消除对它的需要 了解所有父类(super class) 从中衍生出来的?

编辑(回答下面的@ahmet alp balkan 问题):

ofType() 每个子类做两件事:

  1. 根据以下内容确定 字符串 p1 和其他参数 p2和p3,是否子类化 被实例化的是它的类型。
  2. 如果答案是肯定的, 实例化自己的对象 子类。否则,返回 null。

至于你的第二个问题,此时 BaseClass 拥有所有子类的公共(public)数据成员和方法,只有这个单一的静态方法旨在委派确定要实例化的子类的责任。

顺便说一句,由于你的问题,我注意到我原来的帖子中有一个可怕的拼写错误:“SuperClassOne”应该是“SubClassOne”等。

最佳答案

您的静态determineSubClass 方法是一个工厂方法。它显然不应该位于 BaseClass 上,因为不仅基类不应该知道任何关于子类的信息,而且在你的情况下它也不知道任何关于它的信息,因为你想找到另一个项目中的基类。不,这个方法应该位于负责创建 BaseClass 实例的工厂类中。您应该做的是在 BaseType 旁边定义一个用于创建 BaseClass 实例的接口(interface)(或基类型),并在 composition root 中定义一个实现。你的应用程序。当您有多个应用程序时,它们可能每个都有一组不同的 BaseClass 子类型,因此每个应用程序都会有一个不同的工厂。完成此构造后,您可以将工厂注入(inject)到需要 BaseClass 实例的类中。

它可能看起来像这样:

// Shared library
public interface IBaseClassFactory
{
    BaseClass CreateNew(String p1, int p2, Boolean p3);
}

public abstract class BaseClass
{
}

// Application code
public class SubClassOne : BaseClass
{
}

public class SubClassTwo : BaseClass
{
}

// Note that this consumer depends on IBaseClassFactory.
public class SomeConsumer
{
    private IBaseClassFactory baseClassFactory;

    public SomeConsumer(IBaseClassFactory factory)
    {
        this.baseClassFactory = factory;
    }

    public void Consume()
    {
        BaseClass instance = this.baseClassFactory
            .CreateNew("foo", 0, false);

        // use instance
    }
}  

// Composition root
class BaseClassFactory : IBaseClassFactory
{
    public BaseClass CreateNew(String p1, int p2, Boolean p3)
    {
        BaseClass baseObj = null;

        if ((baseObj = SubClassOne.ofType(p1, p2, p3)) != null)
           return baseObj;
        // etc
        else
            return new SubClassDefault(p1, p2, p3);
    }
}

关于java - 如何为移至库的类工厂反转依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6526802/

相关文章:

java - 找不到wav文件中2个声帧之间的差异的问题

java - Cordova 上的 Android Lollipop 通知图标 setColor

scala - SBT 与 Maven Central - 在工件 url 中删除 Scala 版本

java - 模块之间的依赖管理

java - 如何使模块 x 的第 3 方依赖项与其一起到达依赖于模块 x 的模块 y 的类路径?

java - 如何从规划实体使用OptaPlanner ValueRange?

Java 8 - 流意识形态

node.js - 如何根据 Onion/Clean Architecture 原则实现 NodeJS 组件?

c# - 使用 Autofac 的单个消息处理程序工厂

asp.net-mvc - ASP.NET MVC 身份默认实现