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


一、什么是软件架构师

软件架构师首先必须是程序员,而且得是能力技术强的一线程序员。他们会在自身承接编程任务的同时逐步引导团队向最佳的系统设计方向前进。如果不在一线亲自编码,就体会不到设计的好与坏,就会迷失正确的设计方向。

二、软件架构的目的

设计软件架构的目的就是为了在工作中更好地对这些组件进行研发、部署、运行以及维护。

而在设计过程中,我们需要在保证系统能够正常工作的基础上,尽可能长时间地保留尽可能多的“可选项”,这样才能够更灵活地应对未来的功能变更。

比如说,在早期开发阶段,我们其实不需要过于关心我们要使用哪一种数据库,也不需要过早的引入诸如 DI、ORM 之类的框架。这样做的好处是我们在设计架构时如果能有意地让自己摆脱实现细节的纠缠,我们就能够更灵活地进行决策。

三、业务逻辑

业务逻辑是一个软件系统存在的意义,是最核心的功能,是给我们创造收益的那部分代码。

这些业务逻辑应该保持纯净,不要掺杂用户界面或者所使用的数据库相关的东⻄。在理想情况下,这部分代表业务逻辑的代码应该是整个系统的核心,其他低层概念的实现应该以插件形式接入系统中。业务逻辑应该是系统中最独立、复用性最高的代码。

四、划分边界

设计软件架构本身就是一种划分边界的行为,我们需要把一个软件切分为各个模块。而如何合理的划分每个模块的边界,是一个架构师必须要考虑的事情。

划分边界线的原则:边界线应该划在那些不相关的事情中间,比如 GUI 与业务逻辑无关,这两者中间应该要划边界线。

而当我们把系统切割成一个又一个的模块之后,就会发现有一部分模块是系统的核心业务逻辑,另一部分是与核心业务逻辑无关但也提供了必要的功能。而后者我们可以将它们视为一个又一个的插件,然后通过对源代码的修改让这些插件依赖于核心业务组件。这样,我们就能使用插拔插件的方式,来切换很多不同类型的模块,提高系统面对功能变更时的灵活性。

而我们按照这种方式设计出来的系统,通常都会有如下特点:

1、独立于框架:这些系统的架构并不依赖某个功能丰富的框架之中的某个函数。框架可以被当成工具来使用,但不需要让系统来适应框架。
2、可被测试:这些系统的业务逻辑可以脱离诸如 UI、数据库或其他的外部元素来进行测试。
3、独立于 UI:这些系统的 UI 变更起来很容易,不需要修改其他的系统部分。例如,我们可以在不修改业务逻辑的前提下将一个系统的 UI 由 Web 界面替换成命令行界面。
4、独立于数据库:我们可以轻易地替换系统使用的数据库。因为业务逻辑与数据库之间已经完成了解耦。
5、独立于任何外部系统:这些系统的业务逻辑并不需要知道任何其他外部接口的存在。

五、举个例子

假设我们要做一款基于文本的冒险游戏,这个游戏的操作是通过玩家输入“上下左右”这样的简单文字命令来完成的。玩家在输入命令之后,计算机就会返回玩家⻆色触发的事件。

现在,假设我们决定保留这种基于文字的交互方式,但是需要将 UI 与游戏业务逻辑之间的耦合解开,以便我们的游戏版本可以在不同地区使用不同的语言。我们该怎么做呢——我们需要让游戏的业务逻辑与 UI 之间用一种与自然语言无关的 API 来进行通信,而由 UI 负责将 API 传递进来的信息转换成合适的自然语言,就像下图这样:

同时,假设玩家在游戏中的状态会被保存到某种持久化存储模块中(比如闪存,又或者是云端存储),但我们不希望游戏引擎了解这些细节,所以,我们仍然需要创建一个 API 来负责游戏的业务逻辑组件与数据存储组件之间的通信。

另外,语言并不是 UI 变更的唯一方向,我们也可能会改变文字的输入输出方式(比如采用命令行,或者信息窗口),这样我们就又要构建一套 API,这样整个系统就更加复杂了。

然后我们将它简化一下,去掉具体实现,就变成下面这样:

可以看到所有模块和箭头共同组成了一个有向无环图,且箭头最终都指向了 Game Rules 这个核心模块,这种设计就是很合理的设计。但实际上,我们很难遇到这种所有数据流都汇聚到同一个组件上的情况。就拿这个 Game Rules 来说,我需要处理玩家的移动逻辑,同时也要处理玩家的血量、攻击力等逻辑。那么这个系统的架构就会变成这样:

再比如,如果我们需要把这个游戏变成一个多人在线的游戏,然后我们规定玩家的逻辑在本地处理,移动逻辑在服务端处理,那系统就变得更复杂了:

所以你看,一个很简单的文字冒险游戏,也能拓展成一个具有相当多模块和边界的复杂程序。

六、总结一下

作为架构师,我们必须要小心审视究竟在什么地方才需要设计架构边界。另外,我们还必须弄清楚完全实现这些边界将会带来多大的成本。同时,我们也必须要了解如果事先忽略了这些边界,后续再添加会有多么困难。

所以作为架构师,我们应该怎么办?这个问题恐怕没有一个通用的答案。

一方面,就像一些很聪明的人多年来一直告诉我们的那样,不应该将未来的需求抽象化,臆想中的需求事实上住往是不存在的,过度的工程设计往往比工程设计不足还要糟糕。

但另一方面,如果我们发现自己在某个位置确实需要设置架构边界,却又没有事先准备的时候,再添加边界所需要的成本和⻛险往往是很高的。

现实就是这样。作为软件架构师,我们必须有一点未卜先知的能力。有时候要依靠猜测,有时需要依赖过往的经验,当然最重要的是要用点脑子。软件架构师必须仔细权衡成本,决定哪里需要设计架构边界,以及这些地方需要的是完整的边界,还是不完全的边界,还是可以忽略的边界。

当出现问题时,我们还需要权衡一下实现这个边界的成本,并拿它与不实现这个边界的成本对比。我们的目标是找到设置边界的优势超过其成本的拐点,那就是实现该边界的最佳时机。

【架构整洁之道系列】(四)软件架构师与软件架构相关推荐

  1. 架构整洁之道, 看这一篇就够了!

    为什么80%的码农都做不了架构师?>>>    阿里妹导读:程序的世界飞速发展,今天所掌握的技能可能明年就过时了,但有些知识历久弥新,掌握了它们,你在程序的海洋中就不会迷路,架构思想 ...

  2. 一文读懂架构整洁之道(附知识脉络图)

    程序的世界飞速发展,今天所掌握的技能可能明年就过时了,但有一些东西是历久弥新,永远不变的,掌握了这些,在程序的海洋里就不会迷路,架构思想就是这样一种东西. 本文是<架构整洁之道>的读书笔记 ...

  3. 架构整洁之道 pdf_代码有整洁之道,而架构同样有整洁之道

    大家好!我是超级机器人 UltraBot,今天给大家一些值得阅读的开源书籍和项目. Etcd3 学习笔记 etcd 是一个分布式一致性键值存储,用于共享配置和服务发现.etcd 是 Go 编写,并使用 ...

  4. 读书·架构整洁之道(原则篇)

    十四年不修行,只读书,一年通幽.二十日不解碑,只静坐,一日看尽前陵碑 ----- 猫腻<择天记> 一.设计与架构究竟是什么? 二.SOLID设计原则 SRP:单一责任原则(Single R ...

  5. 再读《架构整洁之道》

    时至今日,软件开发技术中最热闹的领域就是前端开发了,各种 xxxScript 语言,各种前端框架,以至于很长时间都没有再听过"面向对象"这种"古老"的词汇了.作 ...

  6. 阿里专家马飞翔:一文读懂架构整洁之道

    淘系技术 马飞翔(泽畔) 读完需要 9 分钟 速读仅需 3 分钟 相信大家都非常清楚,如何编写可读性强的代码是一个合格程序员的必修课.我在之前的文章<谈谈什么是好的代码>中谈了一些自己对整 ...

  7. 架构整洁之道-学习笔记

    高层架构&底层设计细节 架构"这个词往往使用于"高层级"的讨论中.这类讨论一般都把"底层"的实现细节排除在外.而"设计"一 ...

  8. 高清架构整洁之道PDF下载

    架构整洁之道高清PDF下载,请扫描如下二维码,支付3元.并加微信,发给你.谢谢.

  9. 架构整洁之道学习笔记

    1.设计原则 1.1 SRP 单一职责原则 一个软件系统的最佳结构高度依赖于开发这个系统的组织的内部结构.任何一个软件模块都应该只对某一类行为者负责. 单一职责原则主要讨论的是函数和类之间的关系,但是 ...

最新文章

  1. Hadoop - MapReduce MRAppMaster-剖析
  2. pip install python-docx报错_python各种模块的安装
  3. Servlet笔记1
  4. android视频聊天桌面小窗口怎么实现,android视频通话悬浮窗的适配
  5. django orm 常用查询筛选
  6. JavaFX之TableView的MenuButton
  7. win8.1 计算机 桌面快捷方式,win8.1操作系统中我的电脑在哪里?win8.1我的电脑快捷键添加方法介绍...
  8. mysql最小费用最大流问题_最小费用最大流问题
  9. 在移动设备中创建ArcGIS API for JavaScript地图应用程序
  10. QTP鼠标点击和浏览器事件的动态切换
  11. python 程序块 挂掉的服务_写一个python的服务监控程序
  12. 基于Tensorflow实现声音分类
  13. Echarts快速入门
  14. js 基础词汇及方法整理
  15. 「 LaTex 」使用多级标题
  16. (附源码)计算机毕业设计SSM基于框架的旅游订票系统
  17. form表单的enctype
  18. linux apk 拆分 odex,android apk反编译和odex转dex-Go语言中文社区
  19. fifo的rdata_FIFO的使用总结
  20. 数据采集—数据采集技术

热门文章

  1. IBM T60声卡安装
  2. 黑马程序员-java高新技术-代理和类加载器
  3. 100个python进阶实战小项目(适合新手) 微信撤回查看|抖音批量下载等
  4. Linux 上如何禁用 USB 存储设备
  5. android 循环播放mp3,android – 使用AudioTrack播放循环音频
  6. 【DMA】DMA 控制器文档
  7. 踩到一个R8代码压缩工具的坑
  8. teradata数据仓库
  9. 安卓开发 phoenix下拉刷新+taurus下拉刷新
  10. android 录音异常setAudioSource failed