单一职责在《敏捷软件开发》中的定义是:一个模块应该有且仅有一个变化的原因。
程序最稳定的状态就是不改变或很少发生改变。模块如果经常发生变化,意味着 这个模块没有很好的分离关注点,做了很多不是自己的事情;单一职责让模块仅有一个变化的原因 也就是只让他负责他关注的事情,不是他关注的事情不负责,
这样模块发生变化的原因就只有 一个了:关注负责的事情发生了改变
对扩展开放,对修改关闭。说人话就是 新增功能的时候 不会修改旧的代码,只会新增 新的代码。面向对象软件构造里面甚至提出了更严格的软件设计原则:不修改代码。
为什么不能修改呢?因为修改旧代码就意味着引入新问题,在原有的基础上修改代码会对程序造成破坏。相反扩展添加新的代码不会对原有的程序造成破坏。
扩展点的设计就在于分离关注点并用面向接口将 核心的流程抽取出来,以后新增新的功能时只需要新增一个接口的实体实现不同的逻辑即可。
如何使用:在代码中找到经常发生改变的文件,可能是违反了单一原则负责了不关心的东西,也可能是 违反了开闭原则,没有很好的找出程序中共性的行为,导致出现很多无用的重复代码。应该去 抽取找到程序中不变的部分。尽可能不修改而是通过扩展来增加新功能。面向接口抽取共通的可以复用的接口。
推荐书籍《unix编程的艺术》
在设计继承关系的时候应该保证子类可以完全替换父类,忽略类型做特殊处理。如果不能完全替换意味着行为不一样也就代表着程序会出错(本来需要关心类型做不同处理但是代码中没有区分导致程序出错的情况。因此不能根据类型来做不同的处理)
如果声明类型是父类a,但是不同的子类(b,c)的行为不一样,也就是说不同的子类替换父类后,程序会表现出不同的结果。(用b替换a后结果是e,但是用c替换a后结果确是d)。
最典型的关于lsp的设计题是 长方形和正方形这两个类的设计,凭借经验 正方形是特殊的长方形,因此正方形可以继承长方形。但是长方形和正方形计算面积的方式是不一样的,如果正方形修改长宽后变得不一致那么结果就会出错。正方形的面积是平方,而长方形是长和高的乘积也就是说 计算面积的行为不一样导致了正方形不能替代长方形。
在设计继承时要 时刻提醒自己 用父类的角度去设计子类,保证子类可以完全替换父类忽视类型,一般常见的情况是代码中出现了运行时 识别类型(instance of)而针对不同类型调用不同的方法。如果你需要在编写程序的时候需要知道他的具体类型才能继续编程那么就要注意是否违反了里式替换原则,不能完全替代父类。
而有些时候程序中必须要根据类型来做不同处理,但是如果你确定你的设计已经很好的分离了关注点且可以保证子类可以替代父类 然后还是需要判断类型采取不同的处理方式的话。可以采取另外一个思路:
碰到类型判断模式匹配的情况下,将类型判断放到map中,避免做之后的类型特殊处理
声明类型使用父类进行声明
确保父类的行为子类都有
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。