如何反转类工厂移至库的依赖关系
当所有涉及的类都在同一个项目中时(defineSubClass
是 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,是否子类化 被实例化的是其类型。
- 如果答案是肯定的,则 实例化一个 self 对象 子类。否则,返回 null。
至于你的第二个问题, BaseClass
此时保留所有子类的公共数据成员和方法,并且只有这个静态方法,旨在委派确定要实例化的子类的责任。
顺便说一句,由于你的问题,我注意到我原来的帖子中有一个可怕的错字:“SuperClassOne”应该是“SubClassOne”等。
The following code works very well when all involved classes are in the same project (determineSubClass
is a member of 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);
}
But now, I want to move the BaseClass
to a shared Library project, in which SubClassOne
, SubClassTwo
, SubClassThree
and SubClassFour
are not defined in the library but rather in the applications using this library.
I could of course move BaseClass
back to each and every application using this library, but I wonder:
- Is there a better solution?
- Is there a solution that would let me
keepBaseClass
in the Library
project and eliminate the need for it
to know about all superclasses
derived from it?
EDIT (answering @ahmet alp balkan question below):
ofType()
of each subclass does 2 things:
- Determines, based on the content of
String p1 and the other parameters
p2 and p3, whether the subclass to
be instantiated is of its type. - If the answer is positive, it
instantiates an object of self
subclass. Otherwise, returns null.
As for your second question, BaseClass
at this point holds common data members and methods to all subclasses and only this single static method which is aimed at delegating the responsibility of determining subclass to be instantiated.
BTW, thanks to your question I noticed a horrible typo in my original post: "SuperClassOne" should be "SubClassOne" etc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的静态
defineSubClass
方法是一个工厂方法。它不应该位于BaseClass
上;基类不应该知道有关子类的任何信息。在您的情况下,它对此一无所知,因为您想在另一个项目中找到基类。此方法也不应该位于负责创建 BaseClass 实例的工厂类中。您应该做的是定义一个接口,用于在
BaseType
旁边创建BaseClass
实例,并在 组合根 您的应用程序。当您有多个应用程序时,它们可能每个都有一组不同的 BaseClass 子类型,因此每个应用程序都会有不同的工厂。当您完成此构造后,您可以将工厂注入到需要BaseClass
实例的类中。它可能看起来像这样:
Your static
determineSubClass
method is a factory method. It should not be located on theBaseClass
; the base class should not know anything about the subclasses. In your case it can't know anything about it, because you want to locate the base class in another project.Neither should this method be located in a factory class that is responsible for creating
BaseClass
instances. What you should do is define an interface for creatingBaseClass
instances next to theBaseType
and defines an implementation inside the Composition Root of your application. When you have multiple applications, they probably each have a different set ofBaseClass
sub types, so each application will have a different factory. When you have this construction in place, you can inject the factory into classes that needBaseClass
instances.It might look something like this:
基类了解其超类并不是一个好的做法。它违反了大约一半的面向对象原则;).....
我会将该方法移至一个名为 HierarchyManager 或类似的新类,并将该方法放在那里。你甚至可以在那里建立一些层次结构 ->你可以有效地使这个方法“可扩展”......
例如在库中你可以有:
BaseClass -> A、B(A、B 子类化 BaseClass)
一些 LibraryHierachyManager 处理这三个类...
然后在应用程序中使用它:
C、D(子类化 BaseClass 或 A 或 B)
和一些 ApplicationHieararchyManager 执行以下操作:
It's not a good practice that the base class knows about its super classes. It violates about half of OO principles ;).....
I'd move out the method to a new Class called HierarchyManager or smth like that and have the method there. You could even build some hierarchy there -> you could effectively make this method "extendable" ....
For example in library you could have:
BaseClass -> A, B (A, B subclassing BaseClass)
and some LibraryHierachyManager handling these three classes...
and then in application using it:
C, D (subclassing BaseClass or A or B)
and some ApplicationHieararchyManager doing: