整洁架构之道--三种经典的编程范式(代码片段)

网管叨bi叨 网管叨bi叨     2022-11-29     645

关键词:

本文是《Clean Architecture》--整洁架构之道中关于编程范式相关章节的笔记,首发于公众号「Go 招聘」

这和软件架构的三大关注重点不谋而合:功能性、组件独立性以及数据管理。

的方式。回答此问题的同时另外还会搬出这三个词语:封装(encapsulation)、继承(inheritance)、多态(polymorphism)。其隐含意思就是说面向对象编程是这三项的有机组合,或者任何一种支持面向对象的编程语言必须支持这三个特性。

函数和 distance() 函数,但对它们来说,Point 这个数据结构体的内部细节,以及函数的具体实现方式都是不可见的。

point.h

这个经验从何而来呢?因为一度所有程序都是设备相关的,但是后来我们发现自己其实真正需要的是在不同的设备上实现同样的功能。归根结底,多态其实不过就是函数指针的一种应用。自从 20 世纪 40 年代末期冯·诺依曼架构诞生那天起,程序员们就一直在使用函数指针模拟多态了。也就是说,面向对象编程在多态方面没有提出任何新概念。

依赖反转可以使数据库模块和用户界面模块都依赖于业务逻辑模块。我们让用户界面和数据库都成为业务逻辑的插件。也就是说,业务逻辑模块的源代码不需要引入用户界面和数据库这两个模块。

这样一来,业务逻辑、用户界面以及数据库就可以被编译成三个独立的组件或者部署单元(例如 jar 文件、DLL 文件、Gem 文件等)了,这些组件或者部署单元的依赖关系与源代码的依赖关系是一致的,业务逻辑组件也不会依赖于用户界面和数据库这两个组件。

业务逻辑组件就可以独立于用户界面和数据库来进行部署了,我们对用户界面或者数据库的修改将不会对业务逻辑产生任何影响,这些组件都可以被分别独立地部署。

如果系统中的所有组件都可以独立部署,那它们就可以由不同的团队并行开发,这就是所谓的独立开发能力。

如果变量永远不会被更改,那就不可能产生竞争或者并发更新问题。如果锁状态是不可变的,那就永远不会产生死锁问题。

作为一个软件架构师,当然应该要对并发问题保持高度关注。我们需要确保自己设计的系统在多线程、多处理器环境中能稳定工作。

可变性的隔离

一种常见方式是将应用程序,或者是应用程序的内部服务进行切分,划分为可变的和不可变的两种组件。不可变组件用纯函数的方式来执行任务,期间不更改任何状态。这些不可变的组件将通过与一个或多个非函数式组件通信的方式来修改变量状态(参见图 6.1)。

由于状态的修改会导致一系列并发问题的产生,所以我们通常会采用某种事务型内存来保护可变变量,避免同步更新和竞争状态的发生。事务型内存基本上与数据库保护磁盘数据的方式 1 类似,通常釆用的是事务或者重试机制。

这里的要点是:一个架构设计良好的应用程序应该将状态修改的部分和不需要修改状态的部分隔离成单独的组件,然后用合适的机制来保护可变量

软件架构师应该着力于将大部分处理逻辑都归于不可变组件中,可变状态组件的逻辑应该越少越好。

事件溯源

这里举了个简单的例子,假设某个银行应用程序需要维护客户账户余额信息,当它放行存取款事务时,就要同时负责修改余额记录。

如果我们不保存具体账户余额,仅仅保存事务日志,那么当有人想查询账户余额时。我们就将全部交易记录取出,并且每次都得从最开始到当下进行累计。当然,这样的设计就不需要维护任何可变变量了。

事件溯源,在这种体系下,我们只存储事务记录,不存储具体状态。当需要具体状态时,我们只要从头开始计算所有的事务即可。

这种数据存储模式中不存在删除和更新的情况,我们的应用程序不是 CRUD,而是 CR。因为更新和删除这两种操作都不存在了,自然也就不存在并发问题。如果我们有足够大的存储量和处理能力,应用程序就可以用完全不可变的、纯函数式的方式来编程。

小结
  • 结构化编程是多对程序控制权的直接转移的限制。
  • 面向对象编程是对程序控制权的间接转移的限制。
  • 函数式编程是对程序中赋值操作的限制。
  • 每个范式都约束了某种编写代码的方式,没有一个编程范式是在增加新能力。

    我们必须面对这种不友好的现实:软件构建并不是一个迅速前进的技术。今天构建软件的规则和 1946 年阿兰·图灵写下电子计算机的第一行代码时是一样的。尽管工具变化了,硬件变化了,但是软件编程的核心没有变。

    总而言之,软件,或者说计算机程序无一例外是由顺序结构、分支结构、循环结构和间接转移这几种行为组合而成的,无可增加,也缺一不可。

    总结

    名言警句:

  • 三个编程范式,它们分别是结构化编程(structured programming)、 面向对象编程(object-oriented programming)以及函数式编程(functional programming)。
  • 结构化编程范式:对程序控制权的直接转移进行了限制和规范。
  • 面向对象编程范式:对程序控制权的间接转移进行了限制和规范。
  • 函数式编程范式:对程序中的赋值进行了限制和规范。
  • 面向对象编程在封装性上得 0 分,在继承性上勉强可以得 0.5 分(满分为 1)。
  • 多态是我们跨越架构边界的手段,函数式编程是我们规范和限制数据存放位置与访问权限的手段,结构化编程则是各模块的算法实现基础。
  • 如果系统中的所有组件都可以独立部署,那它们就可以由不同的团队并行开发,这就是所谓的独立开发能力。
  • 面向对象编程就是以对象为手段来对源代码中的依赖关系进行控制的能力。
  • 所有的竞争问题、死锁问题、并发更新问题都是由可变变量导致的。
  • 一个架构设计良好的应用程序应该将状态修改的部分和不需要修改状态的部分隔离成单独的组件,然后用合适的机制来保护可变量。
  • 每个范式都约束了某种编写代码的方式,没有一个编程范式是在增加新能力。
  • 软件,或者说计算机程序无一例外是由顺序结构、分支结构、循环结构和间接转移这几种行为组合而成的,无可增加,也缺一不可。
  • 关于整洁架构之道的第二部分关于三种编程范式的记录今天就介绍到这里了。第三部分从设计原则(SOLID)开始,敬请期待。如果有不同见解欢迎留言讨论。


    欢迎关注Go招聘公众号,获取Go专题大厂内推面经简历股文等相关资料。

    架构整洁之道,看这一篇就够了!(代码片段)

    ...中就不会迷路,架构思想就是这样的知识。本文是《架构整洁之道》的读书心得,作者将书中内容拆解后再组织,不仅加入了个人的独到见解,而且用一张详细的知识脉络图帮助大家了解整本书的精华。如果你读过这本书,可以... 查看详情

    《架构整洁之道》

    目标用最少的人力成本满足构建和维护该系统的需求衡量指标版本迭代——工程师团队规模版本迭代——代码总行数版本迭代——代码变更行数软件系统的价值行为价值按需求文档编写代码可用性功能性bug性能稳定性紧急,但是... 查看详情

    6.软件架构设计:大型网站技术架构与业务架构融合之道---数据库(代码片段)

    第6章数据库6.1范式与反范式 数据库范式要求: 第一范式: 每个字段都是原子的,不能再分解。 第二范式: 1.表必有主键,主键可以是单个属性或者几个属性的组合。 2.非主属性必须完全依赖,而... 查看详情

    架构整洁之道(架构篇)

    ...心意,才能逆天命--猫腻《择天记》接上文:架构整洁之道(原则篇)1.什么是软件架构什么是软件架构?“软件架构师”的工作内容是什么?软件架构设计的目标?2.重复3.划分边界4.尖叫的软件架构5.整洁架构5.1... 查看详情

    架构整洁之道(架构篇)

    ...心意,才能逆天命--猫腻《择天记》接上文:架构整洁之道(原则篇)1.什么是软件架构什么是软件架构?“软件架构师”的工作内容是什么?软件架构设计的目标?2.重复3.划分边界4.尖叫的软件架构5.整洁架构5.1... 查看详情

    架构整洁之道-软件架构

    第十五章什么是软件架构软件架构的实质就是规划如何将系统切分成组件,并安排好组件之间的排列关系,以及组件之间互相通信的方式。设计软件架构的目的,就是为了在工作中更好地对这些组件进行研发、部署、运行以及维... 查看详情

    好书推荐探究构架设计的方法论|《架构整洁之道》

    ...雨青年,一名程序员。今天为你推荐的书籍是《架构整洁之道》。架构就是最小的人力成本来满足构建和维护系统需求的设计行为。随着业务的不断发展,项目代码里充满着解决实际问题的逻辑,这些逻辑给系统带来... 查看详情

    好书推荐探究构架设计的方法论|《架构整洁之道》

    ...雨青年,一名程序员。今天为你推荐的书籍是《架构整洁之道》。架构就是最小的人力成本来满足构建和维护系统需求的设计行为。随着业务的不断发展,项目代码里充满着解决实际问题的逻辑,这些逻辑给系统带来... 查看详情

    读《代码整洁之道》有感

    本周我开始阅读RobertC.Martin所著的《代码整洁之道》一书,希望能从中收获高效编写代码的诀窍,因为我自认为我的代码有时候比较糟糕,不太容易维护。一方面,是我没有养成良好的编程习惯;另一方面,我不太清楚什么才是... 查看详情

    架构实践软件架构之道:论架构的原则范式及治理

    目录架构原则【什么是架构】【架构的思考维度】【架构的原则】 查看详情

    架构实践软件架构之道:论架构的原则范式及治理

    目录架构原则【什么是架构】【架构的思考维度】【架构的原则】 查看详情

    程序员该读的10本好书

    ...可以挑选感兴趣的来读一读。序号书名看点备注01《代码整洁之道》《代码整洁之道》值得所有的程序员读一读。软件的质量,不仅依赖于架构,更与代码质量息息相关。而代码的质量与其整洁度成正比关系,越整洁的代码,其... 查看详情

    代码整洁之道(代码片段)

    有意义的命名1名副其实2避免误导3做有意义的分区废话都是冗余。Variable永远不应出现在变量名中,Table一词永远不应出现在表名中。当缺少明确约定:变量moneyAmout与money没区别,customerInfo与customer没区别,accountData与account没区别... 查看详情

    代码整洁之道(代码片段)

    有意义的命名1名副其实2避免误导3做有意义的分区废话都是冗余。Variable永远不应出现在变量名中,Table一词永远不应出现在表名中。当缺少明确约定:变量moneyAmout与money没区别,customerInfo与customer没区别,accountData与account没区别... 查看详情

    架构整洁之道-架构设计二

    第二十章业务逻辑通常将应用程序划分为业务逻辑和插件两部分。业务实体是计算机系统中的一种对象,这种对象中包含了一系列用于操作关键数据的业务逻辑。用例描述的是某种特定应用情景下的业务逻辑。用例更靠近系统的... 查看详情

    php整洁之道(代码片段)

    摘录自RobertC.Martin的CleanCode书中的软件工程师的原则,适用于PHP。这不是风格指南。这是一个关于开发可读、可复用并且可重构的PHP软件指南。并不是这里所有的原则都得遵循,甚至很少的能被普遍接受。这些虽然只是指导,但是... 查看详情

    代码整洁之道-对象和数据结构(代码片段)

    现在,有一个计算面积的需求,其中一种实现如下:classSquarepublic$side;classGeometrypublicfunctionarea($shape)if($shapeinstanceofSquare)return$shape->side*$shape->side;return0; 有人看了,你这抽象的有问题啊,很明显是面向过程的,如果新加 查看详情

    代码整洁之道(代码片段)

    文章目录一、有意义的命名1.名副其实2.避免误导3.做有意义的区分一、有意义的命名软件中随处可见命名。我们给变量、函数、参数、类和封包命名、源代码文件命名、目录命名,良好的命名规范使得代码以及工程的维护难... 查看详情