软件设计原则(下)
admin
2024-02-20 18:02:07
0

在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的无效信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。

文章目录

    • 0 前言
    • 1 开闭、依赖倒转、里氏替换
      • 1.1 开闭原则
      • 1.2 依赖倒转原则与面向接口编程
        • 1.2.1 两者关系
        • 1.2.2 泛化接口的概念
      • 1.3 里氏替换原则与多态
        • 1.3.1 两者关系
        • 1.3.2 泛化多态的概念
      • 1.4 三者关系
    • 2 最佳实践
      • 2.1 运用上述原则的关键
      • 2.2 可参考的设计经验
      • 2.3 编码阶段如何落地
    • 3 总结

0 前言

上一篇的3个设计原则主要关注的是 职责 ,本篇介绍的3个设计原则主要关注的是 变化

1 开闭、依赖倒转、里氏替换

1.1 开闭原则

开闭原则的定义是:对扩展开放,对修改关闭。

修改指的是修改原有代码;扩展指的是新增代码。对于业务需求的变更(修改或者新增),尽量使用扩展的方式,而不是修改原有代码的方式实现。因为这种方式是最安全的,也是最便捷的。

开闭原则本质上关注的是如何处理变化 —— 将变化集中处理(把兔子关到笼子里,并不是杀掉兔子)。

将变化集中的另外一层含义是保留稳定部分不动。具体思路是将变化和稳定分离开,然后只需要关注变化部分。

用PCA的思想来分析这个过程,就是找到一个维度方向(x轴),该方向上变化的方差是最大的(变化区分度更大,也就意味着代码更容易扩展),垂直x轴方向的维度(y轴)代表稳定,由于稳定的代码我们不需要经常改动,所以y轴可以舍弃不进行分析,这样就做到了降维的效果。

所以,开闭原则最底层的思想是 降维 。分割就是为了达到降维的目的。

1.2 依赖倒转原则与面向接口编程

1.2.1 两者关系

  1. 关系

面向接口编程就会导致依赖倒转,遵循了依赖倒转原则写代码就是面向接口编程。

  1. 约束

所以,特意区分这两个概念没有价值,掌握两者对编码的约束就好了。

高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节;细节应该依赖抽象。

Tips:对高层模块和低层模块做一个解释:如果把低层模块比作积木,那高层模块就是由积木拼成的房子。

  1. 好处
  • 可以充当“风险堤坝”,防止一个模块内的“坏代码”导致的风险溢出和扩散。

  • 方便接口测试和TDD(Test-Driven Development),以及问题定位。

  • 方便团队协作开发。

1.2.2 泛化接口的概念

面向接口编程、面向协议、面向锲约编程说的都是一回事儿——都是 面向抽象编程

抽象是一枚硬币,模块间稳定的联系和模块内灵活的变化是这枚硬币的两面。

接口要稳定,实现要灵活。稳定与变化就可兼得。

在代码中稳定的东西一般都是抽象的东西,太细节的东西是很容易变化的,所以依赖抽象才会使两个模块或类之间的联系变得稳定,但又是因为抽象,没有把联系约束的很死板,使得模块或类真正实现时又可以变得很灵活,可以有多种不同的实现方式(这不就是多态么,后文会再次提到)。

代码越抽象就意味着代码越灵活,也意味着代码的复用性和扩展性更强。

抽象的协议都可以作为接口,并不一定指Java中的Interface这类的狭义接口。

接口不光可以是方法接口,也可以是纯数据接口。比如各种通信协议就是纯数据接口。

接口也并不一定只存在于类与类之间或者模块和模块之间,还可以存在于方法与方法之间或者系统与系统之间。也就是说可以有不同粒度的接口。

接口也可以是一个模板。活字印刷就是很好的例子。

1.3 里氏替换原则与多态

1.3.1 两者关系

里氏替换原则为使用多态的正确性提供了保证。

里氏替换原则就是要程序员保证只要父类能出现的地方,就可以使用子类替换,而且不会产生任何错误和异常。

而多态就是调用者使用父类(或接口)引用时调用父类(或接口)内的方法,但由于引用指向的子类不同而导致调用方法的细节实现不同。

有一种提法是静态多态和动态多态。编译期的绑定(前绑定)就是静态多态。运行时绑定(后绑定或延迟绑定)就是动态多态。

1.3.2 泛化多态的概念

接口相同,内部实现不同就是泛化的多态。

如果泛化多态的概念,那解决扩展问题的思路就可以豁然打开了。

  1. 可以使用子类覆写父类虚函数的狭义多态实现方法。
  2. 可以使用函数指针动态绑定(狭义多态就是使用函数指针实现的)。
  3. 可以使用通用数据类型(void *配合共用体;或者使用C++17开始支持的std::any)。
  4. 可以使用命令字的方式。
  5. 可以使用字符串对象指向不同的配置文件(使用metadata的方式)。

1.4 三者关系

开闭原则讲的是面对业务变化我们要朝哪个方向走;依赖倒转原则为“开闭”中的 “闭” 提供了一种解决方案,泛化的接口则包含了所有的解决方案;里氏替换原则为开闭中的 “开” 提供了一种解决方案,泛化的多态则包含了所有的解决方案。

2 最佳实践

2.1 运用上述原则的关键

关键是对业务把控能力很强,抽象出的接口不光能兼顾当前功能,还能兼容新增业务。

能够将接口标准化,则需要对业务乃至整个行业都有精准和深入的理解。

2.2 可参考的设计经验

  1. 泛化接口+泛化多态+工厂

    可以将变化约束在2个地方:新增类和修改“工厂”。

  2. 泛化接口+泛化多态+依赖注入

    可以将变化约束在2个地方:新增类和外部配置文件。

  3. 其它设计模式的灵活应用

2.3 编码阶段如何落地

  1. 设计类时先设计接口。
  2. 设计接口时要尽量抽象和通用。
  3. 父类不要调用子类方法。
  4. 子类只覆写(不要重载)父类虚函数。如果不是写库,无论什么业务场景都不建议使用函数重载,太容易用混。

3 总结

本篇的3个设计原则非常重要,指导了几乎所有的设计模式。

此外,牢记抽象稳定变化接口多态 这几个关键词。

恭喜你又坚持看完了一篇博客,又进步了一点点!如果感觉还不错就点个赞再走吧,你的点赞和关注将是我持续输出的哒哒哒动力~~

相关内容

热门资讯

小学楼道里涂鸦墙用水粉颜料可以... 小学楼道里涂鸦墙用水粉颜料可以吗,墙上是油漆涂过的不可以,用水粉一擦就掉了,用丙烯颜料,和水粉感觉差...
有什么科幻小故事,短一些? 有什么科幻小故事,短一些? 遇见外星人一天,我在公园里散步。突然,一个像盘子一样发着许多光的东西...
幼儿园安吉室外投放哪些材料 幼儿园安吉室外投放哪些材料幼儿园安吉室外投放材料滚筒、积木、长板、木箱、梯子、沙水、锅、碗、瓢、盆、...
爱情的十字路口我该怎么选择? 爱情的十字路口我该怎么选择?真爱掌握在你自己手中!爱他就努力争取,不顾一切!还不是很爱他,那就等等,...
有没有和《恶魔狂想曲之明日骄阳... 有没有和《恶魔狂想曲之明日骄阳》差不多精彩的小说?女主角很多,个性鲜明,主角多情但不滥情,富于正义文...
功利主义是否认为道德应该是一种... 功利主义是否认为道德应该是一种绝对的命令?最源头的定义是边沁的观点,使所有人的快乐最大化。之后有缪尔...
什么是CC猫啊 什么是CC猫啊CC是一只可爱活泼的猫猫,因为诞生于沪江网校所以全称:沪江网校CC猫。CC猫常常出没于...
美剧迷失第三季好看吗? 美剧迷失第三季好看吗?个人觉得,迷失第一季还不错,很惊异.越往后看越没意思.相信我你会越看越迷失的....
求推荐一些奇幻和爱情主题的动漫 求推荐一些奇幻和爱情主题的动漫刀剑神域 强烈推荐妖精的尾巴哈尔的移动城堡~~强烈推荐刀剑神域!!!...
张晓风的这篇柳运用什么的修辞手... 张晓风的这篇柳运用什么的修辞手法张晓风的这片《柳》运用了比喻,对比的修辞手法。希望我的解答对我有帮助...
我想在手机上看童话书,请问在哪... 我想在手机上看童话书,请问在哪里找?我记得有类似的书,是不是一本红皮的?那个是有点类似杂志或者丛书的...
远古是一个怎样的世界 远古是一个怎样的世界漫漫四十多亿年哪,多长的时间呀,搞不好,以前主宰地球的物种的科技比我们还牛些的!...
有色没胆 有胆没色 有色没胆 有胆没色这两种男人有什么区别?哦这个.有色就是好色也不敢动手.有胆就是胆大不好色.或者是自...
华胥引中君伟的结局 华胥引中君伟的结局君玮最后是和苏仪在一起了。七七微段子里提到的慕言和阿拂家的孩子其实是君玮和苏仪的然...
带烁字的男孩名字 带烁字的男孩名字带烁字的男孩名字,用烁字起名烁(shuò):烁表示光亮、烁亮、烁烁。 繁体:烁;部首...
《披荆斩棘的哥哥》正在热播,看... 《披荆斩棘的哥哥》正在热播,看完这档节目后你有什么观后感?看完这档节目之后,我觉得挺好的,这次的节目...
我女儿的生辰八字:壬午年 丙... 我女儿的生辰八字:壬午年 丙午月 丙寅日 庚寅时 (2002年6月27日农历五月十七日早上...
点读机什么品牌好啊,怎么选啊? 点读机什么品牌好啊,怎么选啊?步步高点读机比较好,选大商场的正品,不要上网或电子市场买。
吴用只是个文弱书生,李逵为何会... 吴用只是个文弱书生,李逵为何会对他言听计从?尽管吴用只是一个文弱书生,但他对李逵忠心耿耿,所以李逵会...
开心星星球里甜心超人魔方玩了4... 开心星星球里甜心超人魔方玩了4秒是哪一集39集,新人。。。第四部《甜心超人的新爱好》