工厂方法模式是否违反了开放/封闭原则?

发布于 2024-08-24 01:13:41 字数 780 浏览 3 评论 0原文

工厂方法模式(不要与工厂或抽象工厂模式混淆)是否违反了< 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生生漫 2024-08-31 01:13:41

工厂模式本质上并不违反 OCP

这取决于您如何进一步推进Complex的行为。

如果需要 Complex 来支持生成新类型的 Complex 对象,并且您选择通过添加新的 fromX< 来修改 Complex添加 /code> 方法来支持它们,那么这意味着 Complex 违反了 OCP 因为 Complex 必须重新打开进行修改:

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));
    }

    //class opened for modification
    public static Complex fromOtherMeans(String x , String y) {
        return new Complex(x, y);
    }
}

您可以将此问题推送到文本文件或某种类型的属性文件中,以避免必须更改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 of Complex object, and you choose to modify Complex by adding new fromX methods are added to support them, then this means that Complex becomes a violator of the OCP because Complex must be re-opened for modification:

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));
    }

    //class opened for modification
    public static Complex fromOtherMeans(String x , String y) {
        return new Complex(x, y);
    }
}

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 how Complex is extended but not modified.

Another OCP friendly alternative to altering Complex in this case is the Decorator pattern. Continuously decorating Complex with the ability to create new variants of Complex respects the OCP because Complex 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 of Complex.

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.

碍人泪离人颜 2024-08-31 01:13:41

不,它根本不违反开放/封闭原则。

开放/封闭意味着您可以修改系统的工作方式,而无需修改已存在的代码。您可以扩展代码并以不同的方式使用它,但旧代码仍然完好无损,不需要重新测试。

工厂方法模式将根据指定的参数创建不同类型的对象。如果做得正确的话,工厂方法实际上可以很好地遵循开闭原则。但是,如果您创建一个新类,然后希望工厂方法创建该类型的新对象,则必须更改工厂方法。

不过,如果您有某种配置文件或由工厂方法读入的某种类型的文件,那么您不必更改工厂方法......只需配置文件即可指示将创建什么对象工厂方法。

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.

無心 2024-08-31 01:13:41

没有。从您的维基百科链接:

软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭

覆盖工厂方法就是扩展。您正在创建一个新类。您不更改现有的类。您必须(希望通过 IoC 容器的配置)用子类替换原始类。

Nope. From your Wikipedia link:

software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文