当所有涉及的类都在同一个项目中时,以下代码非常有效(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巴尔干问题):
每个子类的 ofType()
做两件事:
关于你的第二个问题,此时BaseClass
包含所有子类的公共数据成员和方法,并且只有这个单一的静态方法,旨在委派确定子类的责任进行实例化。
答案 0 :(得分:1)
基类知道它的超类不是一个好习惯。它违反了大约一半的OO原则;).....
我将这个方法转移到一个名为HierarchyManager的新类,或者像这样的方法,并在那里使用方法。你甚至可以在那里建立一些层次结构 - >你可以有效地使这种方法“可扩展”....
例如,您可以在库中使用:
BaseClass - > A,B(A,B子类化BaseClass) 和一些LibraryHierachyManager处理这三个类...
然后在使用它的应用程序中:
C,D(继承BaseClass或A或B)
和一些ApplicationHieararchyManager在做:
public static BaseClass determineSubClass(String p1, int p2, Boolean p3) {
if (baseObj = C.ofType(.....) {
....
} else {
return LibraryHierarchyManager.determineSubClass(p1,p2, p3);
}
}
答案 1 :(得分:1)
您的静态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);
}
}