开放-封闭原则
开放-封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。
这个原则其实是有两个特征,一个是说“对于扩展是开放的(Open for extension)”,另一个是说“对于更改是封闭的(Closed for modification)”[ASD]
例如,公司的考勤制度,公司规定九点上班,不允许迟到。但有的员工总是迟到。
迟到不是主要问题,每天保证8小时的工作量是老板最需要的,甚至8小时工作时间也不是主要问题,业绩目标的完成或超额完成才是最重要的指标,于是应该改变管理方式,比如弹性上班工作制,早到早下班,晚到晚下班,对市场销售人员可能就更加以业绩为标准,工作时间不固定了--这其实就是对工作时间或业绩成效的修改关闭,而对时间制度扩展的开放。
无论模块是多么的封闭,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应该对哪种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化[ASD]
在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化[ASD]就像之前简单工厂模式里关于计算器的算法,当需求只有加法的时候,可以在一个类中完成,此时变化还没有发生。然后,有个添加减法的需求,这就违背了‘开放-封闭原则’,于是就该考虑重构,增加一个抽象的运算类,通过一些面向对象的手段,来隔离具体操作的耦合,需求依然可以满足,还能应对变化。这时,如果再要添加乘除,就不用修改之前的代码,增加子类就可以。即面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。[ASD]
开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要[ASD]