对修改关闭,对扩展开放。
开放闭合原则
Shubho:这里是开放闭合原则的海报
开放闭合原则海报
从面向对象设计角度看,它可以这么说:"软件实体(类,模块,函数等等)应当对扩展开放,对修改闭合。"
通俗来讲,它意味着你应当能在不修改类的前提下扩展一个类的行为。就好像我不需要改变我的身体而可以穿上衣服。
Farhana:有趣。你能够按照你意愿穿上不同的衣服来改变面貌,而从不用改造身体。你对扩展开放了,对不?
Shubho:是的。在OOD里,对扩展开发意味着类或模块的行为能够改变,在需求变化时我们能以新的,不同的方式让模块改变,或者在新的应用中满足需求。
Farhana:并且你的身体对修改是闭合的。我喜欢这个例子。当需要变化时,核心类或模块的源代码不应当改动。你能用些例子解释一下吗?
Shubho:当然,看下面这个例子。它不支持"开放闭合"原则。
违反开发闭合原则的类结构
你看,客户端和服务段都耦合在一起。那么,只要出现任何变化,服务端变化了,客户端一样需要改变。
Farhana:理解。如果一个浏览器以紧耦合的方式按照指定的服务器(比如IIS)实现,那么如果服务器因为某些原因被其他服务器(如Apache)替换了,那么浏览器也需要修改或替换。这确实很可怕!
Shubho:对的。下面是正确的设计。
遵循开放闭合原则的类结构
在这个例子中,添加了一个抽象的服务器类,客户端包含一个抽象类的引用,具体的服务类实现了抽象服务类。那么,因任何原因引起服务实现发生变化时,客户端都不需要任何改变。
这里抽象服务类对修改是闭合的,实体类的实现对扩展是开放的。
Farhana:我明白了,抽象是关键,对吗?
Shubho:是的,基本上,你抽象的东西是你系统的核心内容,如果你抽象的好,很可能在扩展功能时它不需要任何修改(就像服务是一个抽象概念)。如果在实现里定义了抽象的东西(比如IIS服务器实现的服务),代码要尽可能以抽象(服务)为依据。这会允许你扩展抽象事物,定义一个新的实现(如Apache服务器)而不需要修改任何客户端代码。