回顾Bob大叔的简洁架构

Robert Martin 就是我们常说的Bob大叔,是码界的骨灰级人物了,在4年前提出了所谓的简洁架构,值得回顾反思一下,看看是否可以借鉴到微服务中呢?

大叔在文中介绍了一下几种知名的架构思想:

  • Alistair Cockburn 的Hexagonal Architecture
  • Jeffrey Palermo 的 Onion Architecture
  • Screaming Architecture 在Bob 大叔的博客上
  • DCI 是 James Coplien, 和 Trygve Reenskaug提出的架构模型
  • BCE 是 Ivar Jacobson 在其著作 Object Oriented Software Engineering: A Use-Case Driven Approach 提出的

尽管这些架构在细节上有各种各样的不同,大叔认为是相似的,都有着相同的目标就是——关注点分离,通过关注点分离把软件分成若干层,系统都是这样的:

  1. 独立的框架。架构不依赖于功能丰富的软件库,把框架作为工具而不是系统的约束。
  2. 可测性. 商务逻辑可以不依赖TUI, 数据库, Web , 或其他外部元素就可以测试。
  3. 独立的UI. 无需改变系统的其他部分就可以轻松地改变,例如 一个 A Web UI 换成控制台UI,而无需改变业务逻辑。
  4. 独立的数据库.业务逻辑不与数据库绑定,可以在各种数据库间切换例如 Oracle 和SQL ,Mongo与 BigTable、 CouchDB等。
  5. 外部代理的独立性. 事实上,业务逻辑需要简化到无需知道外面的世界。

因此,大叔提出的简洁架构试图将这些架构集成为一种简单的表达形式。

这一架构工作的最高原则就是依赖原则。这一原则说明源代码依赖指向内部的,内圆不知道外圆的一切, 特别地,外圆中声明的东西不需要被内圆中的代码涉及,包括函数,类,变量以及其他的软件实体。同心圆代表了软件的不同领域。一般地,越深入负责,软件的层次越多。外圆代表机制,内圆代表策略。同样的,外圆中的数据格式也不应被内圆使用,尤其是那些被外圆中的框架所生成的数据格式,并不希望外圆影响到内圆。

实体 (Entities)

实体封装了企业级的业务逻辑。一个实体可以是一个带有方法的对象,或者一个数据结构和函数的集合,实体可以被企业内的多个应用使用的。如果没有企业只是写单个应用的话,这些实体就是应用的业务对象。他们在外部变化时改动最少,例如,不希望页面导航的改变影响到实体对象的改变或者安全性。应用的操作性改变不应该影响实体层。

用例 (Use cases)

这一层的软件包含了应用相关的特定业务逻辑,封装了所以的系统用例。这些用例编排了实体之间的数据流,目标是将实体指向企业层面的业务规则。同样不希望这一层影响到实体,也不希望这一层被外部元素所影响例如 数据库, UI, 或其他通用框架。然而,希望应用操作的改变影响这一层的用例,如果一个用例的实现细节改变了,这一层的一些代码一定受到影响。

接口适配器 (Interface Adapters)

该层的软件是一组适配器的集合,这些适配器将数据转换成用例和实体方便使用的格式,以及一些外部代理方便使用的格式例如数据库或者Web。例如,一个包含MVC架构的图形界面,Presenters, Views, 和 Controllers 都位于该层。models就像数据结构一些从controllers传递到use cases,然后从用例返回到presenters 和 views。

类似的,来自实体和用例的数据会被转换到驻留框架,例如数据库。这一层没有向内的代码来感知外部的数据库。如果数据库是一个SQL 数据库的话, 那么所有SQL被限制在该层,这一层中特殊的部分处理数据库。这一层中还有其他一些适配器转换外部服务的数据到内部使用的用例和实体。

框架与驱动(Frameworks and Drivers)

最外层油框架和工具组成,如数据库,Web框架等。 一般地,不需要写大量的代码就可以和内部的圆进行通信了。这一层细节密布,Web 是细节实现,数据是另一种细节,把他们保持在外可以减少伤害。

大叔的简洁架构只有四层么?绝对不是的,这些圆不过是示意而言,可以远多于4层的。但依赖原则总是适用的,最外圈总是底层的具体实现。

右下角的框图展示了是如何跨越边界的,描绘了Controllers 和Presenters 如何与下一层的用例通信。注意一下控制流,开始于controller, 穿过用例在presenter中执行。这也是源代码依赖,向内执行用例。这就是通常使用的DIP,在Java中,可以通过接口和继承关系来实现跨边界的控制流,动态的多态性可以跨越这一架构的所有边界。跨越边界的典型数据是简单的数据结构。可以使用基本结构或者简单的数据传输对象,或者函数的调用参数,重要的是相互隔离。例如,很多数据库框架都在查询时返回一个数据集, 最好不要让它跨边界传递,它违反了依赖原则即内圆知道了外圆的事情。

回顾

通过将软件分层,遵守依赖原则,形成内在的可测性,隔离外部的元素并具备可替代性,如此而已。

简洁架构更像是一种指导性的原则,核心同样是关注点分离和分层感知,没有摆脱企业级应用架构的经典观念。

如果联想一下复变函数中的保角变换,这 Clean Architecture 就会变成我们熟知的有趣模样了.......

原文发布于微信公众号 - 喔家ArchiSelf(wireless_com)

原文发表时间:2017-02-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

【计算机基本概念】中央处理器

中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control U...

3435
来自专栏IT大咖说

华为:既满足用户体验,又节省功耗的App应用设计开发方法

1727
来自专栏领域驱动设计DDD实战进阶

DDD实战进阶第一波(三):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架二)

了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的...

4146
来自专栏养码场

一位资深Java的阿里系公司实战面试经验,套路还是面试官的多

占小狼:一位奋斗在魔都的资深Java开发。去年6月在简书上发第一篇技术文章,已坚持发表76篇技术文章,粉丝数突破4000。

2267
来自专栏机器学习算法与Python学习

Python:10篇不可错过的~热文~》》真的很热》》

以下是精选了“ Python开发者” 5月份的10篇 Python 热文。其中有基础知识,项目实战等。 《Python 爬虫建站入门手记(1):环境搭建》 本文...

3233
来自专栏逍遥剑客的游戏开发

引擎工具开发的一些总结

2495
来自专栏Spark学习技巧

案例简介flink CEP

随着无处不在的传感器网络和智能设备不断收集越来越多的数据,我们面临着以近实时的方式分析不断增长的数据流的挑战。 能够快速响应不断变化的趋势或提供最新的商业智能可...

5662
来自专栏Java帮帮-微信公众号-技术文章全总结

Java面试复习大纲2.0(持续更新)

想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢?本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面...

5037
来自专栏程序员的碎碎念

数据挖掘敲门砖--Python爬虫入门

? WHAT 数据挖掘是一门综合的技术,随着Ai的兴起,在国内的需求日渐增大。 数据挖掘的职业方向通常有三个,顺便概要地提一下所需的技能(不仅于此) 数据分...

4898
来自专栏温安适的blog

3个面试中遇到的问题

6月是个忙碌的月份,结完婚,处理完家事,也换了份工作。以至于6月都没有写blog,今天闲来无事,将之前面试的问题,以及一些感悟分享给大家。

1763

扫码关注云+社区

领取腾讯云代金券