开放关闭原则【The Open Closed Principle】

来源:互联网 发布:美国日本关系知乎 编辑:程序博客网 时间:2024/05/18 00:52

作者:Uncle Bob

原文链接

1988年,Bertrand Meyer定义了软件工程中几个最重要原则中的一个:开放关闭原则(The Open Closed Principle OCP)。在《面向对象软件构造》Object Oriented Software Construction中他写道:


一个符合要求的模块分解技术必须满足一个要求:它所分解出来的模块应该既是开放的又是关闭的。

  • 我们说一个模块是开放的,那么它一定是可扩展的。例如,我们应该能修改它的数据结构,或者增加新功能。
  • 我们说一个模块是关闭的,那么它必能被其他模块所使用。这要求这个模块具有定义良好且稳定的描述(从信息隐藏的意义上来说,只的就是接口)。对于编程语言的模块,闭合的模块也许就是一个被编译好并存放在程序库的一个东东。对于设计模块或者规格模块,闭合一个模块就是经管理层同意,允许将此模块加入项目正式的版本库(也叫做项目基线),并发布其接口供其他模块设计者使用。

这个定义明显过时了。目前许多语言并不要求模块能被编译。另外,模块规格需要管理层同意也带着瀑布式开发的心态。但是,一个伟大原则的精髓还是在这里闪闪发光:

你应该能够在不修改系统的情况下,扩展系统的行为。

仔细想想,如果你系统中的所有模块的行为都能在不修改它们的情况下进行扩展,那么你可以不需要修改任何老代码就能为你的系统增加新特性。这些新特性完全是通过新增代码而加入的。

更重要的是,因为没有修改老代码,那么你的系统就不要重新编译,所以也就不需要重新部署。增加新特性就变成了:老代码不要动,仅仅部署新代码,也许是一个新的jar包,或者一个新的dll,gem。

这应该给你一个暗示:jar包、dll、gem到底应该是什么?他们应该是可隔离的特性。


荒谬吗?

一开始独到开放关闭原则也许好像完全没有意义。我们的语言和设计常常不允许新特性在与系统其他部分相隔离的情况下开发,编译,部署。我们很少发现我们的系统对于修改是闭合的,而能用新特性进行扩展。

确实,常见的情况是,我们把代码修改得体无完肤来新增特性。我们早在Martin Fowler 出版散弹式手术Shotgun Surgery这本书之前,我们就知道这种做法很有害处,但是我们还是照样在做。

但是,这里还有Eclipse, IntelliJ,  Visual Studio,  Vim,  Text Mate,  Minecraft ......,嗯,我的意思你懂的。有许多工具是不需要修改或者重新部署就能很容易进行扩展的,我们通过写插件来扩展它们。

插件系统是开放关闭原则的终极典范,证明开放关闭系统是可能的,有用的,并且是无比强大的。

这些系统到底是如何对于主要业务的修改保持关闭,但是让整个应用的扩展保持开放的?简单。他们相信OCP,他们使用面向对象工具分离底层细节和高层策略。他们仔细管理依赖关系,对于那些架构上跨越重要边界的错误依赖方向进行反转。

毕竟,你获取一个插件架构就是确保所有依赖都在插件内,并指向系统。系统内没有任何东西指向插件。这种系统不了解插件,但是插件了解系统。

插件架构


你的系统设计是基于插件的,就像Vim, Emacs, Minecraft,Eclipse,会怎么样?你能够插入(plug in)数据库或者GUI会如何?你能够插入新特性,也能拔出老特性会如何?你的系统能够配置插件来进行控制会如何?这将给你什么力量?增加一个新特性,一个新用户接口,一个新机器/机器接口有多容易呢?增加、删除SOA有多容易呢?增加,删除REST有多容易?增加、删除Spring,Rails,Hibernate,Oracle....有多容易呢?

嗯,我想你懂我的意思。当基本的业务规则是插件系统的核心,那么你将永远不会受制于一个特定的特性集,接口,数据库,框架,以及其他任何东西。(译者注:这些东西都能随时进行插拔,当然不会受它们的约束)

结论

我 听说,OCP是错误的,是不能工作的,是不实际的,不是给真正的程序员做真正工作用的。插件架构的出现证明这种观点完全是胡说。正相反,一个强大的插件架构很可能是未来软件系统最重要的方面。

0 0
原创粉丝点击