当所有涉及的类都在同一个项目中时(
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()
做两件事:
BaseClass
此时拥有所有子类的公共数据成员和方法,并且只有这个静态方法,其目的是委派确定要实例化的子类的责任。顺便说一句,由于你的问题,我注意到我原来的帖子中有一个可怕的拼写错误:“SuperClassOne”应该是“SubClassOne”等。
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);
}
}
我会将方法移出到一个名为 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);
}
}