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

问题描述 投票:0回答:2

当所有涉及的类都在同一个项目中时(

determineSubClass
BaseClass
的成员),以下代码可以很好地工作:

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
移至共享库项目,其中
SubClassOne
SubClassTwo
SubClassThree
SubClassFour
不是在库中定义,而是在使用此库的应用程序中定义图书馆。

我当然可以将

BaseClass

移回到使用此库的每个应用程序,但我想知道:

    有更好的解决办法吗?
  • 有没有一个解决方案可以让我 将
  • BaseClass
     保留在图书馆中
    项目并消除对其的需要
    了解所有超类
    从中衍生出来的?

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

ofType()

做两件事:

    根据内容确定 字符串 p1 和其他参数 p2和p3,是否子类化 被实例化的是
  1. its 类型。
  2. 如果答案是肯定的,则 实例化一个 self 对象 子类。否则,返回 null。
至于你的第二个问题,

BaseClass

此时拥有所有子类的公共数据成员和方法,并且只有这个静态方法,其目的是委派确定要实例化的子类的责任。

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

java dependency-injection dependency-management library-project class-factory
2个回答
3
投票
您的静态

determineSubClass

 方法是工厂方法。它不应位于 
BaseClass
 上;基类不应该知道有关子类的任何信息。在您的情况下,它对此一无所知,因为您想在另一个项目中找到基类。

此方法也不应该位于负责创建

BaseClass

 实例的工厂类中。您应该做的是定义一个接口,用于在 
BaseClass
 旁边创建 
BaseType
 实例,并在应用程序的 
Composition Root 内定义一个实现。当您有多个应用程序时,它们可能每个都有一组不同的 BaseClass
 子类型,因此每个应用程序都会有不同的工厂。当您完成此构造后,您可以将工厂注入到需要 
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); } }
    

2
投票
基类了解其超类并不是一个好的做法。它违反了大约一半的面向对象原则;).....

我会将方法移出到一个名为 HierarchyManager 或类似的新类,并将该方法放在那里。你甚至可以在那里建立一些层次结构 -> 你可以有效地使这个方法“可扩展”....

例如在图书馆你可以有:

BaseClass -> A, B(A, B 子类化 BaseClass) 和一些处理这三个类的 LibraryHierachyManager...

然后在应用程序中使用它:

C、D(基类或 A 或 B 的子类)

以及一些 ApplicationHieararchyManager 正在做的事情:

public static BaseClass determineSubClass(String p1, int p2, Boolean p3) { if (baseObj = C.ofType(.....) { .... } else { return LibraryHierarchyManager.determineSubClass(p1,p2, p3); } }
    
© www.soinside.com 2019 - 2024. All rights reserved.