rma*_*ski 22 java open-closed-principle
开放封闭原则指出"软件实体(类,模块,功能等)应该是可以扩展的,但是对于修改是封闭的".
然而,Joshua Bloch在其着名的书"Effective Java"中给出了以下建议:"继承的设计和文档,或者禁止它",并鼓励程序员使用"final"修饰符来禁止子类化.
我认为这两个原则显然是相互矛盾的(我错了吗?).编写代码时遵循哪个原则,为什么?你是否打开你的课程,不允许继承你的课程(哪些?),或者尽可能使用最终修饰语?
cle*_*tus 26
坦率地说,我认为开放/封闭原则更不合时宜.它从80年代和90年代开始,当OO框架建立在一切必须从其他东西继承并且一切都应该是可子类化的原则的基础上.
这在MFC和Java Swing这个时代的UI框架中最为典型.在Swing中,你有一个荒谬的继承,其中(iirc)按钮扩展复选框(或相反的方式)给出其中一个未使用的行为(我认为它是复选框上的setDisabled()调用).为什么他们分享祖先?没有其他原因,他们有一些共同的方法.
这些天的成分比继承更受青睐.虽然Java默认允许继承,但.Net采取了(更现代的)默认禁用它的方法,我认为这更正确(并且更符合Josh Bloch的原则).
DI/IoC还进一步提出了组合案例.
Josh Bloch还指出继承打破了封装并提供了一些很好的例子.还有人证明,如果通过委派而不是扩展类来改变Java集合的行为更加一致.
就个人而言,我在很大程度上认为继承只不过是现在的实施细节.
我不认为这两个陈述相互矛盾.类型可以打开以进行扩展,并且仍然可以关闭以进行继承.
一种方法是使用依赖注入.类型可以在创建时提供这些类型,而不是创建自己的帮助器类型的实例.这允许您在不更改类型本身的情况下更改类型的部件(即打开以进行扩展)(即关闭以进行修改).
在开闭原则(打开扩展,关闭以进行修改)中,您仍然可以使用最终修饰符.这是一个例子:
public final class ClosedClass {
private IMyExtension myExtension;
public ClosedClass(IMyExtension myExtension)
{
this.myExtension = myExtension;
}
// methods that use the IMyExtension object
}
public interface IMyExtension {
public void doStuff();
}
Run Code Online (Sandbox Code Playgroud)
该ClosedClass闭合的类内的修改,但开放用于通过另一个延伸部.在这种情况下,它可以是任何实现IMyExtension接口的东西.这个技巧是依赖注入的变种,因为我们用另一个来提供封闭的类,在这种情况下是通过构造函数.由于扩展是一个interface不可能final但它的实现类可以.
使用final on classes在java中关闭它们类似于sealed在C#中使用.在.NET方面有类似的讨论.
我非常尊重 Joshua Bloch,我认为Effective Java几乎是Java 圣经。但我认为自动默认private访问通常是一个错误。我倾向于在protected默认情况下制作东西,以便至少可以通过扩展类来访问它们。这主要是因为需要对组件进行单元测试,但我也发现它可以方便地覆盖类的默认行为。当我在自己公司的代码库中工作并最终不得不复制和修改源代码时,我觉得这很烦人,因为作者选择“隐藏”所有内容。如果这完全在我的能力范围内,我会游说更改访问权限protected以避免重复,恕我直言,这要糟糕得多。
还要记住,Bloch 的背景是设计非常 公开的基础 API 库;使此类代码“正确”的标准必须设置得非常高,因此很可能与您将编写的大多数代码的情况不同。重要的库(例如 JRE 本身)往往会受到更多限制,以确保该语言不被滥用。查看JRE 中所有已弃用的API?几乎不可能改变或移除它们。您的代码库可能不是一成不变的,因此如果您最初犯了错误,您确实有机会修复问题。
现在我默认使用final修饰符,几乎反射性地作为样板的一部分.当你知道给定的方法将始终如你正在查看的代码中看到的那样时,它会使事情更容易推理.
当然,有时会出现类层次结构正是您想要的情况,然后不使用它就很愚蠢.但要害怕超过两个级别的层次结构,或者非抽象类进一步子类化的层次结构.课程应该是抽象的或最终的.
大多数时候,使用构图是要走的路.将所有常用机器放入一个类中,将不同的案例放入不同的类中,然后将实例合并为一个整体.
你可以称之为"依赖注入",或"策略模式"或"访问者模式"或其他什么,但它归结为使用组合而不是继承来避免重复.
| 归档时间: |
|
| 查看次数: |
5054 次 |
| 最近记录: |