当所有涉及的类都在同一个项目中时(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
保存在库中 项目并消除对它的需要 了解所有父类(super class) 从中衍生出来的?
编辑(回答下面的@ahmet alp balkan 问题):
ofType()
每个子类做两件事:
- 根据以下内容确定 字符串 p1 和其他参数 p2和p3,是否子类化 被实例化的是它的类型。
- 如果答案是肯定的, 实例化自己的对象 子类。否则,返回 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/