【架构整洁之道系列】(二)编程范式与设计原则

最近一直在读《Clean Architecture》这本书,书中对与软件设计与架构的阐述是非常深刻的。因此开了一篇专栏,来记录《Clean Architecture》书中一些优秀的架构设计理念,以及我对这些内容的思考。


一、编程范式

1-1、结构化编程

结构化编程是一种编程范式,它采用子程序、块结构、条件分支以及循环等结构,来取代传统的 goto 语句,从而优化计算机程序的可读性和开发时间,避免写出面条式代码。

具体来说,结构化编程是以一些简单、有层次的程序流程架构所组成,可分为“顺序”、“条件分支”及“循环”三大类。

顺序是指程序正常的执行方式,执行完一个指令后,执行后面的指令。
条件分支是根据程序的状态,选择数段程序中的一个来执行,一般会使用 if、switch/case 等关系字来识别。
循环是指一直执行某一段程序,直到满足特定条件,或是集合中的所有元素均已处理过后结束,一般会使用 for、while 等关键字识别。

另外,若一个编程语言的语法允许用成对的关键字包围一段程序,形成一个结构,这种结构我们称之为“块结构”,比如在 C 语言中用大括号 {…} 包围的一段程序。

结构化编程范式中最有价值的地方就是,它赋予了我们编写“可测试的程序单元”的能力。同样的,这也是为什么在架构设计领域,功能性的拆分一直是最佳实践的原因。

1-2、 面向对象编程

面向对象编程到底是什么?业界在这个问题上存在着很多不同的说法和意⻅。然而对一个软件架构师来说,其含义应该是非常明确的:

面向对象编程就是以对象为手段来对源代码中的依赖关系进行控制的能力,这种能力能让软件架构师可以构建出某种插件式架构,让高层策略性组件与底层实现性组件相分离,底层组件也能编译成插件,实现独立于高层组件的开发和部署。

1-3、 函数式编程

函数式编程会将所有的程序视为函数运算,并且避免使用“状态”以及“可变对象”。

相比于指令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是直接设计一个复杂的执行过程。

在函数式编程中,函数是最重要的,意思是说一个函数,既可以作为其它函数的输入参数值,也可以从函数中返回值,被修改或者被分配给一个变量。

1-4、 总结一下

结构化编程、面向对象编程、函数式编程这三个编程范式都对编写的程序提出的限制。每个范式都约束了某种编写代码的方式。

结构化编程是多对程序控制权的直接转移(也就是 goto 语句)的限制。
面向对象编程是对程序控制权的间接转移(也就是指针)的限制。
函数式编程是对程序中赋值操作的限制。

也就是说,不论是框架还是编程范式,核心都是一种规范和约束,而这种约束底层的指导思想就是——什么不该做。

二、设计原则

2-1、概述

设计原则的主要作用就是告诉我们如何将数据和函数组织成为类(注意,这里虽然用到了“类”这个词,但是并不意味着我们将要讨论的这些设计原则仅仅适用于面向对象编程。这里的类仅仅代表一种数据和函数的分组),以及如将这些类组合起来成为程序。

而这些设计原则的目标主要由以下几点:
1、使软件能够灵活、低成本地进行改动。
2、使软件具有更高的可读性和可维护性。
3、构建能在多个软件系统中复用的组件。

2-2、内容

SRP:单一职责原则。软件系统能否达到的“最好的架构”依赖于这个系统内部的模块是如何组织的。所以为了达到“最好的架构”,我们需要尽量保证软件的每个模块都有且只有一个需要被改变的理由。换句话说,就是每个模块只负责干一件事。

OCP:开闭原则。软件需要对扩展开放,但对修改封闭。如果我们希望一个软件系统能够更灵活地应对变更,那么在设计他的架构的时候,就必须要允许能够通过新增代码来修改系统行为,并尽可能的避免修改原来的代码。

LSP:里氏替换原则。所有引用基类的地方必须能透明地使用其子类的对象,换个角度来看,这项原则的意思是如果想用可替换的组件来构建软件系统,那么这些组件就必须遵守同一个约定,以便让这些组件可以相互替换。

ISP:接口隔离原则。这项设计原则主要告诫软件设计师应该在设计中避免不必要的依赖,要尽量避免使用无用的方法和功能。

DIP:依赖反转原则。该设计原则指出高层策略性的代码不应该依赖实现底层细节的代码,恰恰相反,那些实现底层细节的代码应该依赖高层策略性的代码。

猜你喜欢

转载自blog.csdn.net/u011748319/article/details/124944430