王争《设计模式之美》学习笔记
如何理解“对扩展开放、修改关闭”?
开闭原则
- 开闭原则:SOLID 中的第二个原则,英文全称是 Open Closed Principle,简写为OCP。
- 开闭原则是 SOLID 中最难理解、最难掌握,同时也是最有用的一条原则。
- 对扩展开放、修改关闭,直接影响代码的扩展性,扩展性是代码质量最重要的衡量标准之一。
项目实战
- API 接口监控告警的代码
- Alert类:
- 属性两个:AlertRule 存储告警规则,Notification 是告警通知类
- 方法:check()主要业务逻辑两种报警场景
- 此时要添加一种报警场景,修改:
- check()增加一个参数
- 在check()方法内部增加新报警场景的逻辑代码
- 修改单元测试
- 用扩展的方案,要先重构Alert类:
- 将check()方法的多参数,封装成ApiStatInfo 类
- 引入handler概念,将多种报警场景放在各handler中
- 此时要添加一种报警场景,扩展:
- 在ApiStatInfo 类中新增属性
- 添加一个新的报警场景的handler类
- 重构后的代码十分灵活,添加新的报警场景,完全不需要修改check()的逻辑,只需要添加对应的handler即可。老的单元测试也不用修改,只需要添加新的单元测试。
- 作者得例子都非常有实用场景,之前做过这样的报警,但是没把handler封装成类,而是封装的方法。
修改代码就意味着违背开闭原则吗?
- 当有新需求增加时,首先什么都不改不变是不可能的,好的方案和代码改动量大小无关
- 个人理解修改那就真的是在改,扩展实质都是在新增(模块、类、方法、属性)
- 到底是算修改还是扩展也跟你思考的粒度和单元有关系,要尽量通过增加属性、方法、类的方式
- 不要改动方法的内部逻辑
如何做到“对扩展开放、修改关闭”?
偏向顶层的指导思想
- 写代码的时候,多思考未开可能有哪些需求变更,设计代码结构留好扩展点,新的代码可能很灵活地插入扩展点
- 代码可变部分封装起来,隔离变化
- 代码不变部分抽象出来,以后扩展新的实现即可
具体方法论
- 最常用来提高代码扩展性的方法有:多态、依赖注入、基于接口而非实现编程。
- 文中举例,通过 Kafka 来发送异步消息:
- 所有上层系统都依赖这组抽象的接口编程
- 通过依赖注入的方式来调用
- 当我们要替换新的消息队列的时候,写一个新的消息队列实现即可
如何在项目中灵活应用开闭原则?
- 写出支持“对扩展开放、对修改关闭”的代码的关键是预留扩展点。
- 业务导向的项目,要足够熟悉业务需求,才能知道当下和未开可能支持的业务需求。
- 如果跟业务无关,是偏底层的系统,需要了解系统将被如何使用,才能预估将来可能添加那些功能。
- 也不要过度设计,识别所有扩展点是不可能的,有些复杂的也可以到有需求驱动的时候,通过代码重构的方式实现。
- 代码的扩展性与可读性是冲突的,要根据实际情况权衡取舍。
来源:CSDN
作者:linglongwunv
链接:https://blog.csdn.net/linglongwunv/article/details/104049616