开闭原则
开闭原则
开闭原则(Open Closed Principle
,OCP
)。
英文描述:
1 | software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification |
中文翻译:
1 | 软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭” |
扩展性是代码质量最重要的衡量标准之一。
在 23 种经典设计模式中,大部分设计模式都是为了解决代码的扩展性问题而存在的,主要遵从的设计原则就是开闭原则。
一、如何理解“对扩展开放、对修改关闭”
添加一个新的功能时,应该做到:
- 在已有代码基础上扩展代码(新增模块、类、方法等)
- 而非修改已有代码(修改模块、类、方法等)
尽量避免修改已有的代码,而是追加新代码。
二、为什么要“对扩展开放、对修改关闭”?
- 对扩展开放是为了应对变化(需求)
- 对修改关闭是为了保证已有代码的稳定性
- 最终结果是为了让系统更有弹性
三、修改代码就意味着违背开闭原则吗?
- 添加一个新功能,不可能任何模块、类、方法的代码都不“修改”,这个是做不到的
- 要做的是尽量让修改操作更集中、更少、更上层
- 尽量让最核心、最复杂的那部分逻辑代码满足开闭原则
四、如何做到“对扩展开放、对修改关闭”?
开闭原则讲的就是代码的扩展性问题,写出扩展性好的代码就是遵循开闭原则:
- 要时刻具备扩展意识、抽象意识、封装意识
- 多思考未来需求,猜测未来可能出现的扩展点,在设计时预先留好这些扩展点
- 尽量识别出可变部分和不可变部分,将可变部分封装起来,隔离变化,同时提供抽象化的不可变接口
常用来提高代码扩展性的方法有:
- 多态
- 依赖注入
- 基于接口而非实现编程
- 大部分的设计模式(比如,装饰、策略、模板、职责链、状态等)
这些方式实际上都是同一种设计思路,只是从不同的角度、不同的层面来阐述而已。
五、如何在项目中灵活应用开闭原则?
要想识别出尽可能多的扩展点,就要对业务有足够的了解:
- 了解当下以及未来可能要支持的业务需求
- 它们会被如何使用?
- 今后打算添加哪些功能?
- 未来会有哪些更多的功能需求?
了解需求以后,就可以去设计扩展点,但是要辨别出可扩展设计和过度设计。
可做的扩展设计:
- 比较确定的、短期内就可能会扩展的
- 需求改动对代码结构影响比较大的
- 实现成本不高的扩展点
过度设计的情况:
- 不确定未来是否要支持的需求
- 实现起来比较复杂的扩展点
过度设计的情况,可以等到有需求驱动的时候,再重构代码来支持扩展需求。
六、开闭原则可能带来的弊端
- 有些情况下,代码的扩展性会跟可读性相冲突,理解起来比以前难一些
- 重构之后的代码要比之前的代码,在结构上可能会复杂很多