首页 > IT职业 > IT职场 > 3 分钟吃透开闭原则,架构设计筑基必知必会
来源:mikechen的互联网架构
在开发项目时,几乎都会再三强调开闭原则。
开闭原则是面向对象设计中“可复用设计”的基石,它可以在不破坏现有功能的情况下,去扩展原有代码。解决了软件开发中的两个问题:可扩展性、可维护性。
在设计模式的 6 大原则中,如果说开闭原则是精神领袖(抽象类),那么其它设计原则,则是它的具体形态(具体实现类)。

今天我们深入开闭原则,本文内容包括:
什么是开闭原则
开闭原则的 UML 类图
开闭原则的设计背景
开闭原则的应用示例
两大方法避免违反开闭原则
架构设计:预留扩展点思路
大家好,我是 mikechen。
开闭原则是良好架构设计的基石,非常重要。为方便大家系统学习,我已将本文归纳到《阿里架构师进阶专题合集》。需要的同学,拉到文末自取。

开闭原则,英文全称 Open/Closed Principle。
开闭原则是指一个软件实体(类、函数等),应该 对扩展开放、对修改封闭 。
1)对扩展开放(open for extension)
是指允许组件模块功能的扩展。
当需求发生变化时,可以通过对模块进行扩展,来实现新的需求。
2)对修改封闭(closed for modification)
是指对原有代码的修改封闭。
当组件模块功能进行扩展时,不应该修改原有代码。

抽象化是开闭原则的关键。
为了满足开闭原则,需要对系统进行抽象化设计。
在 Java 中,我们可以为系统定义一个相对稳定的抽象层,再将不同的实现行为移至具体的实现层中完成。
如果需要修改系统,无须对抽象层进行任何改动,只要增加新的具体类,就能实现新的需求,在不修改已有代码的基础上扩展系统的功能,满足了开闭原则的要求。
假设:
我们要实现一个绘制图表的功能,支持多种图表显示方式,例如柱状图、饼状图...等多种图表。
系统结构:

在 ChartDisplay 类的 display() 方法中,存在如下代码片段:

上面代码中,
如果需要增加一个新的图表类(例如折线图 LineChart),就需要修改 ChartDisplay 类的 display() 方法的源代码,增加新的判断逻辑,违反了开闭原则。
为了满足开闭原则,现在我们重构系统。
1)增加一个抽象图表类 AbstractChart,将具体图表类作为它的子类;
2)ChartDisplay 类针对抽象图表类进行编程,由客户端来决定使用哪个具体图表。
重构后,系统结构是这样的:

我们引入了抽象图表类 AbstractChart,且 ChartDisplay 针对抽象图表类进行编程,并通过 setChart() 方法由客户端来设置实例化的具体图表对象。
在 ChartDisplay 的 display() 方法中,调用 chart 对象的 display() 方法显示图表。
后续,如果还要增加新的图表,不需要修改原来的代码,只需要将 LineChart 也作为 AbstractChart 的子类,在客户端向 ChartDisplay 中注入一个 LineChart 对象就行了。
那是否只要修改原有代码,就会违反开闭原则呢?
违反开闭原则的情况,通常是指频繁且不必要的修改,这可能会增加bug概率,系统维护困难。
在修复错误、性能优化或其他合理情况下,修改代码本身并不违反开闭原则。
当业务规则改变时,完全不“修改”原有代码,这几乎是不可能的。
例如:
类需要创建、组装、做一些初始化操作,才能构建成可运行的程序。
这部分代码的修改,是不可难免的。
一些思路,供大家参考:
1)在架构设计阶段,就要去关注系统的可扩展性,事先预留扩展点。
事先预留设计扩展点,可以在未来业务发生改变时,用最少的修改来满足新的需求。
哪些情况需要预留扩展点呢?
需要预留扩展点的常见情况:
对于相对确定的、可能短期内需要扩展的;
对于改动对代码结构影响比较大的;
对于可能用到、且实现成本不高的。
当然了,合理预留设计扩展点的前提,是需要对业务有足够了解。
这个部分涉及到的实施细节、要素较多,本文只是提供参考思路,后续我再单独更文介绍。
2)对于必须的合理修改,让修改操作尽量更集中、更少、更上层,让最为核心复杂的逻辑代码满足开闭原则。
开闭原则是面向对象设计中“可复用设计”的基石。它可以在不破坏现有功能的情况下,去扩展原有代码,让系统可维护、可扩展、可复用。
事先合理预留设计扩展点,是避免违反开闭原则的关键。在架构设计阶段,就需要关注系统的可扩展性。
开闭原则既是面试高频、也是必知必会,非常重要。
建议收藏备用,划走就再也找不到了。
以上
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024420/viewspace-2991738/ ,如需转载,请注明出处,否则将追究法律责任。