设计原则-开闭原则

怎样的代码改动才能被定义为“扩展”?

怎样的代码改动才定义为“修改”?

怎样才算满足或者违反开闭原则?

修改代码意味着违反开闭原则吗?

开闭原则是最难理解,也是最难掌握,同时也是最有用的一条原则。这条原则并不是看几篇文章,理解了其概念就能掌握和灵活应用的。要想深入理解,掌握这条原则,需要大量的实战。

 

开闭原则,英文全称:Open Closed Principle,简称OCP。软件实体(模块、类、方法等)应该“对扩展开放,对修改关闭”。也就是说:添加一个新的功能,在已有代码的基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

这里需要正确的理解“扩展”和“修改”?

添加新的功能,完全不修改已有的代码是不可能,你需要弄明白的是:什么样的代码改动称的上“扩展”?什么样的代码改动才被定义为“修改”?弄明白这两个问题需要回到这条原则的设计初衷上来。

 

开闭原则设计的初衷

只要它没有破坏原有代码的正常运转,没有破坏原有的单元测试,那么它就是一个合格的改动。

也就是说,当我们添加新功能的时候,即使对原有代码做了相应的改变,只要原有的功能还能正常的运行,原有的单元测试还能正常使用,那我们就可以认为这样的代码改动属于扩展,而原有的功能和原有的单元测试已经无法使用了,那我们就说这样的代码改动是修改

举个栗子:在版本升级的过程中,如果升级前的版本提供了A功能,升级后的版本,A功能仍能正常使用,那这次版本升级时符合开闭原则的,如果升级后的A功能不能使用的,那它就不遵循开闭原则。

 

实际上,开闭原则讲的是扩展性问题,是判定一端代码是否易扩展的“金标准”,如果某段代码在应对未来需求的变化的时候,能够做到“对扩展开放,对修改关闭”,那也就说明这段代码的扩展性好。所以问如何才能做到“对扩展开放,对修改关闭”,也就等同于在问,如何才能写出扩展性好的代码?那如何才能做到“对扩展开放,对修改关闭”呢?

 

如何才能做到对“对扩展开放,对修改关闭”?

为了尽量写出扩展性好的代码,我们时候具备扩展意识、抽象意识、封装意识,这些“潜意识”可能比任何开发技巧都要重要。在写代码的时候,我们需要多发时间思考一下,这段代码可能会有哪些需求更变,如何设计代码结构,事先留好扩展点,以便在未来的需求更变的时候,在不改变代码整体结构、做到最小改动的情况,将新代码灵活的插入扩展点。

很多的设计原则、设计思想、设计模式、都是以提高代码的扩展性为最终目的的,特别是23种经典设计模式,大部分都是为了解决代码的扩展性而总结出来的,都是以开闭原则为指导原则。最常用的提高代码的方法有:多态、依赖注入、基于接口而非实现编程。以及大部分设计模式(比如:装饰、策略、模板、责任链、状态)。

 

在项目中如何灵活的应用开闭原则呢?

比较合理的做法是,对于一些比较确认的,短期内可能就会扩展,或者需求改动对代码结构影响比较大的情况,或者实现成本不高的扩展点,在编码的时候,我们可以事先做一些代码扩展性设计。这个当然建立在你对需求的掌握程度之上。

对于一些未来不确定的是否需要的需求,或者实现起来比较复杂的扩展点,我们可以等到需求驱动的时候,在通过代码重构的方式来支持扩展需求。

 

开闭原则也并不是免费的,有些情况下,代码的可扩展性会和可读性发生冲突。为了支持扩展性,我们对代码进行重构,重构之后的代码可能会比之前的的代码复杂很多,理解起来也会更加的困难。但是具体情况,需要具体分析,并没有一个防止四海皆准的标准,全凭应用场景来决定。在一些情况下,扩展性可能更加重要,就会牺牲一下可读性,而在一些情况下,可读性更重要,就可以牺牲一下扩展性。在有些情况下,实现功能之后,业务需求没有扩展点了 ,也每必要花更多的时间去重构以提高代码的扩展性。

 

参考:设计模式之美--王争

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值