工厂方法模式是否违反了开放/封闭原则?
工厂方法模式(不要与工厂或抽象工厂模式混淆)是否违反了< a href="http://en.wikipedia.org/wiki/Open_Closed_Principle" rel="noreferrer">开放/封闭原则?
更新: 为了澄清这一点,我指的是具体类具有静态工厂方法的场景。例如(这是来自 FMP 上的维基百科页面):
class Complex
{
public static Complex fromCartesian(double real, double imag) {
return new Complex(real, imag);
}
public static Complex fromPolar(double modulus, double angle) {
return new Complex(modulus * cos(angle), modulus * sin(angle));
}
private Complex(double a, double b) {
//...
}
}
私有构造函数不会阻止类被子类化,即扩展吗?
是否必须修改该类才能支持新的工厂方法?例如,如果该类最初只有 fromCartesian,后来需要 fromPolar,那么是否需要修改该类来支持这一点?
这两个不都违反了开放/封闭吗?
Does the Factory Method pattern (not to be confused with the Factory or Abstract Factory patterns) violate the Open/Closed principle?
Update:
To clarify, I'm referring to the scenario where a concrete class has static factory methods on it. For example (this is from the Wikipedia page on FMP):
class Complex
{
public static Complex fromCartesian(double real, double imag) {
return new Complex(real, imag);
}
public static Complex fromPolar(double modulus, double angle) {
return new Complex(modulus * cos(angle), modulus * sin(angle));
}
private Complex(double a, double b) {
//...
}
}
Doesn't the private constructor prevent the class from being subclassed, i.e. extended?
Wouldn't the class have to be modified to support new factory methods? For example, if the class initially only had fromCartesian and later fromPolar was needed, didn't the class have to be modified to support this?
Don't both of these violate Open/Closed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
工厂模式本质上并不违反 OCP。
这取决于您如何进一步推进
Complex
的行为。如果需要
Complex
来支持生成新类型的Complex
对象,并且您选择通过添加新的fromX< 来修改
Complex
添加 /code> 方法来支持它们,那么这意味着Complex
违反了 OCP 因为Complex
必须重新打开进行修改:您可以将此问题推送到文本文件或某种类型的属性文件中,以避免必须更改java 类,但它并不妨碍您必须在解决方案的该区域编写额外的逻辑,以支持新类型的
Complex
。根据
Complex
在您的设计中的使用情况(各种类型有何不同?您如何使用它们?),有一些可能适用的替代选项。一种这样的 OCP 友好替代方案是对
Complex
进行子类化以提供额外的工厂方法。子类是Complex
如何扩展但不修改的最简单说明。在这种情况下,另一个 OCP 友好的替代方案来改变
Complex
是 装饰器模式。持续装饰Complex
并能够创建新的Complex
变体,尊重 OCP,因为Complex
不会被修改,而是通过用新功能包装它来扩展。第三种替代方案可能是更改
Complex
的结构,以便通过组合来提供其计算。这将为您提供使用策略模式来区分<的不同行为的机会。代码>复杂。工厂模式的特点是它有助于上下文代码遵守 OCP。人们可以采用上述技术之一,以便与他们的人保持在 OCP 的右侧工厂类,但您的同事可能会看一下对象图,质疑在单个工厂上使用对象图是否明智,并将其简化回一个工厂,这使您回到第一个示例。
在这种情况下,不要试图改变工厂模式的实现来尊重 SOLID 原则,考虑为什么要使用它。
The Factory pattern isn't inherently a violator of OCP.
It depends on how you take the behavior of
Complex
further.If
Complex
is required to support the production of new types ofComplex
object, and you choose to modifyComplex
by adding newfromX
methods are added to support them, then this means thatComplex
becomes a violator of the OCP becauseComplex
must be re-opened for modification:You could push this problem down into a text file or properties file of some sort in order to absolve yourself of having to change the java class, but it doesn't prevent you from having to write extra logic in this area of the solution in order to support new types of
Complex
.Depending on the usage of
Complex
in your design (how are the various types different? How are you using them?), there are some alternative options which may apply well.One such OCP friendly alternative is to subclass
Complex
to provide the additional factory methods. A subclass is the simplest illustration of howComplex
is extended but not modified.Another OCP friendly alternative to altering
Complex
in this case is the Decorator pattern. Continuously decoratingComplex
with the ability to create new variants ofComplex
respects the OCP becauseComplex
is not modified but is extended by wrapping it with new functionality.A third alternative might be to alter the structure of
Complex
so that its calculation is supplied by composition. This would open up to you the opportunity to use the Strategy pattern to diferentiate between the different behaviours ofComplex
.The thing about the Factory pattern is that it helps context code respect OCP. One might employ one of the techniques above in order to stay on the right side of the OCP with their Factory class, but your colleagues are likely to take one look at the object graph, question the wisdom of having an object graph over a single Factory, and simplify it back into one Factory, which brings you back to to the first example.
In such cases, rather than trying to bend your implementation of the Factory pattern to respect the SOLID principles, consider why you're using it at all.
不,它根本不违反开放/封闭原则。
开放/封闭意味着您可以修改系统的工作方式,而无需修改已存在的代码。您可以扩展代码并以不同的方式使用它,但旧代码仍然完好无损,不需要重新测试。
工厂方法模式将根据指定的参数创建不同类型的对象。如果做得正确的话,工厂方法实际上可以很好地遵循开闭原则。但是,如果您创建一个新类,然后希望工厂方法创建该类型的新对象,则必须更改工厂方法。
不过,如果您有某种配置文件或由工厂方法读入的某种类型的文件,那么您不必更改工厂方法......只需配置文件即可指示将创建什么对象工厂方法。
No, it doesn't violate the Open/Closed principle at all.
Open/Closed means you can modify the way a system works without modifying the code that already exists. You can extend the code and use it in different ways, but the old code is still in tact and doesn't need to be re-tested.
The Factory Method pattern will create a different type of object based on specified parameters. Factory Method actually works well with the Open/Closed principle if done correctly. However, if you create a new class and then want the Factory Method to create a new object of that type you would have to change the Factory Method.
Although, if you had some kind of configuration file or something of that sort that is read in by the Factory Method then you wouldn't have to change the Factory Method ... just the config file that then dictates what object will be created by the Factory Method.
没有。从您的维基百科链接:
覆盖工厂方法就是扩展。您正在创建一个新类。您不更改现有的类。您必须(希望通过 IoC 容器的配置)用子类替换原始类。
Nope. From your Wikipedia link:
Overriding the factory method is extension. You're creating a new class. You don't change the existing class. You have to substitute (via configuration of your IoC container hopefully) the subclass for the original.