问题标签 [open-closed-principle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
847 浏览

c++ - 模板特化还是条件表达式?

我深入研究了一个新项目,我用一堆模板和它们的专业化来解决这个问题。现在,在一天没有编程之后,我发现自己在问是否真的值得额外的代码行。

问题是:专业化有什么好处?

这是:

在任何方面都比更好(更快的执行)

?

编辑:

该代码是供其他人使用的库的一部分。我使用的是 gcc 4.6.3,但最终代码将与不同的编译器一起使用。

编辑:

这两段代码使用 gcc 4.6.3 生成相同的二进制文件。我无法测试完整的案例,因为我的实际代码远不能使用。这似乎真的是一个原则问题,多功能性,可重用性,可维护性等......

0 投票
5 回答
591 浏览

design-patterns - 我怎样才能拥有一个遵守开闭原则的行为丰富的域实体?

闭原则指出:

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

我现在正在设计一个域,并在我的域实体中包含相当多的行为。我正在使用域事件并将依赖项注入方法中,因此请确保我的实体不与外部影响耦合。但是,我突然想到,如果客户以后想要更多功能,我将不得不违反 OCP 并破解打开这些域实体以添加功能。行为丰富的领域实体如何与开闭原则和谐相处?

0 投票
1 回答
788 浏览

c# - 改进本工作单元类的方法,涉及开/关原理和依赖注入/控制反转

我很感兴趣寻找可以改进以下 UnitOfWork 类的使用的方法。如您所见,它当前没有 UnitOfWork 接口,因此当我在 MVC 控制器中使用它时,我必须创建一个新对象,使我的控制器依赖于此类。

我希望能够使用 Ninject 通过将接口传递给我的控制器的构造函数来注入这种依赖关系,我的问题是这个类目前不符合打开/关闭原则,我对任何人关于如何改进的建议感兴趣那。我想我还需要某种方式将存储库传递到这个工作单元中,但我不完全确定如何去做。

任何帮助将不胜感激,谢谢。

0 投票
4 回答
5327 浏览

c# - 移除开关盒的设计模式

我需要根据所提供的验证特定国家/地区的邮政编码是否是强制性的countryid。目前我正在使用switch声明来执行此操作,但此代码违反了 Open/Closed SOLID 原则。我想知道如何摆脱switch这种情况。

0 投票
1 回答
115 浏览

c# - 以下代码中的 CommaDelimLog 类是否违反单一职责原则?

该程序解析日志文件 - 每个日志文件可能具有不同类型的字段格式(固定宽度、逗号分隔等)。此外,每个日志文件都混合了几种不同类型的日志 - 每种都有不同的字段定义)。例如,CSV 日志文件可能看起来像

日志文件 A

以下是代码。下面的代码中违反了多少个坚实的原则?一个人说布局定义列表不应该与解析日志混合。所以它至少违反了 SRP(或更多)?重构结构的最佳方法是什么?

主程序根据文件名模式从LogFileList中获取一项,逐行读取日志文件并赋值Row,然后得到解析后的字符串。

0 投票
6 回答
3986 浏览

java - 如何使用反射满足工厂模式中的开闭原则?

我正在尝试使用 Head First Design Pattern 学习面向对象的设计模式。这是书中工厂模式的一个示例,我想在不违反开放封闭原则的情况下添加新的披萨项目。在书中给出的示例代码中,如果我添加新的比萨项目类,我需要修改 PizzaStore 和 PizzaOrder 类。但我只想添加新的披萨项目而不修改其他类。

}

这个 PizzaStore 类用于创建和订购比萨饼。

}

这是抽象的 Pizza 类:

该类用于接受客户的订单。

这是我的新披萨项目类。我想在不修改 chicagoPizzaStore 和 testDrive 类的情况下订购这个披萨:

0 投票
2 回答
197 浏览

java - 在接口中声明的匿名内部类:什么是外部类?

考虑以下:

InnerClass 不是静态的,必须针对其外部类的实例创建。

new OuterClass().new InnerClass()

常规的内部类包含对创建它的外部类的引用,可以使用Outer.this.myAttribute(在存在“命名冲突”的情况下特别有用


创建匿名内部类时也是一样:创建的匿名内部类持有对外部类的引用,这就是为什么在方法内部声明谓词(匿名方法局部内部类)时,我们仍然可以在内部类内部访问外部类的变量,而不必将它们声明为 final(而我们应该将变量作为方法参数传递。


最后,我们可以在接口中声明常量,这些常量被隐式标记为 public static final。一个对象可以是一个常数。因此,作为匿名内部类创建的对象是接口的合法常量。

例如,在使用 Guava 时,我通常在我的接口函数和谓词中声明,这允许我利用有用的 Guava 函数,例如Maps.uniqueIndex(...).


所以你可能会问自己我的问题是什么?这里是:

当将匿名类声明为接口常量时(请参阅我的上一个代码示例),匿名内部类对哪个外部类持有引用?

0 投票
2 回答
267 浏览

java - 使用 InstanceOf 实现访问者

我很好地掌握了访问者模式。但是,我想知道一些事情。

使用访问者模式最重要的动机是在客户端添加涉及特定数据模型的逻辑,而无需检查真实的数据对象类型。用于求解的技术称为双重调度。

因此,这里是实现accept()方法的数据模型的代码片段:

这里是一个PrintCarVisitor实现Visitor接口:

因此,不需要if/else系列和instanceof系列。

任何客户都是:

但是,既然访问者没有保持开/关原则(因为一个新的数据模型会导致通过添加自己的visit方法来破坏类),我们为什么还要为双重调度而烦恼呢?

if/else我们不能只在访问者实现中隔离系列。

使用这种假设的替代方案,这部分代码将消失:

PrintCarVisitor将会:

使用这种替代方法,每个调用者仍然会像这样处理数据模型抽象:

new PrintCarVisitor().visit(car); //no need to know the exact data type in client side

先验地,第二种方法很棒,因为它不涉及在实现纯访问者模式期间生成的所有样板。

我想这种方法有两个缺点:

1)不保证(如Visitor接口强加)任何使用过的访问者都会处理与Car当前处理的方法相对应的方法。

2) BoilerPlate 代码在 Visitor 实现类中仍然较重,带有instanceofcasting

他们是否有任何其他缺点解释了为什么访问者模式必须使用双重调度,因此不能简单地将instanceof系列隔离在一个类中(例如静态Factory)?

0 投票
3 回答
2851 浏览

java - 访问者模式如何不违反开放/封闭原则?

来自维基百科:

这个想法是一旦完成,一个类的实现只能被修改以纠正错误;新的或更改的功能将需要创建不同的类。该类可以通过继承重用原始类的编码

据我了解,访问者模式是一种强大的技术,可以通过使用双重调度来遍历实现相同接口的相似但不同的对象。在我的一个 Java 示例中,我创建了一组构成树结构的复合对象,这些对象的每个特定实现都实现了可访问接口。访问者接口对每个可访问对象都有一个方法,具体的访问者实现了对每种情况执行的操作。

我想弄清楚的事实是,如果我要向也实现可访问的复合结构添加一个新实现,那么我需要重新打开访问者界面并将该案例添加到其中,这也迫使我修改访问者的每个实现。

虽然这很好,因为无论如何我都需要这样做(如果访问者无法理解它们,添加到您的可访问对象有什么好处?)但是在学术层面上,这不会违反开放封闭原则吗?这难道不是设计模式的核心原因之一吗?试图展示切换到这种模式的正当理由,而不是维护一个 switch 语句来结束所有 switch 语句,但每个人都认为代码无论如何都是一样的,每个案例都有一个方法而不是 switch 块,只是分解了并且更难阅读。

0 投票
1 回答
615 浏览

design-patterns - Façade 是否利用了开闭原则?

开闭原则的维基百科页面(截至今天 2013-02-27)说它是通过继承实现的。

开放/封闭原则这个名称有两种使用方式。两种方式都使用继承来解决明显的困境,但目标、技术和结果是不同的。

“两种方式”是指 Meyer 的实现继承和更常见的多态扩展。

无论如何,我的问题是关于使用继承的外观模式。既然它以简化接口的形式定义了一个对更复杂的子系统(或库)的抽象,难道这也不能被看作是开闭原则吗?进一步来说:

子系统(或库)是开放的,可扩展至使用 Façade 的客户端,其接口对修改是封闭的

还是我只是在扩展信息隐藏的界限(这非常接近 OCP,特别是如果您将其视为Protected Variations)。