干净的架构The Clean Architecture

英文原版地址

这是著名软件大师Bob大叔提出的一种架构,也是当前各种语言开发架构。干净架构提出了一种单向依赖关系,从而从逻辑上形成一种向上的抽象系统。

我们经常听说过如下各种架构:

六边形架构Hexagonal Architecture (也称为 端口和适配器) 这是由Alistair Cockburn 提出,被Steve Freeman和 Nat Pryce在他们的书籍Growing Object Oriented Software中采取的。

Onion Architecture 作者Jeffrey Palermo

Screaming Architecture Bob大叔

DCI 由James Coplien和Trygve Reenskaug推动

BCE Ivar Jacobson在他的书籍Object Oriented Software Engineering: A Use-Case Driven Approach提出

虽然这些架构在细节上都略有不同,但他们都非常相似。它们都具有相同的目标,那就是分离关注。他们都通过软件分层来实现这种分离。至少有一个层代表业务规则,而另一个层用于接口。

这些架构产生的系统特点是:

独立的框架. 这样的架构并不依赖与应用软件的具体库包,这样可以将框架作为工具,而不必将你的系统都胡乱混合在一起。

可测试. 业务规则能够在没有UI和数据库 或Web服务器的情况下被测试。

UI的独立性. UI改变变得容易,不必改变系统的其余部分,一个Web UI能被一个控制台或专门的图形UI替代, 这些读不必更改业务核心规则。

数据库的独立性. 你能够在Oracle或SQL Server Mongo, BigTable, CouchDB,或之间切换, . 你的业务规则不会和数据库绑定

独立的外部代理,其实你的业务规则可以对其外面的技术世界毫无所知,比如是否使用了MVC或DCI都可以不关心。

这种干净的架构图如下:

依赖规则Dependency Rule

上图中同心圆代表各种不同领域的软件。一般来说,越深入代表你的软件层次越高。外圆是战术实现机制,内圆的是战略核心策略。

使此体系架构能够工作的关键是依赖规则。这条规则规定源代码只能向内依赖,在最里面的部分对外面一点都不知道,也就是内部不依赖外部,而外部依赖内部。这种依赖包含代码名称,或类的函数,变量或任何其他命名软件实体。

同样,在外面圈中使用的数据格式不应被内圈中使用,特别是如果这些数据格式是由外面一圈的框架生成的。我们不希望任何外圆的东西会影响内圈层。

实体Entities

实体封装的是企业业务规则,一个实体能是一个带有方法的对象,或者是一系列数据结构和函数,只要这个实体能够被不同的应用程序使用即可。

如果你没有编写企业软件,只是编写简单的应用程序,这些实体就是应用的业务对象,它们封装着最普通的高级别业务规则,你不能希望这些实体对象被一个页面的分页导航功能改变,也不能被安全机制改变,操作实现层面的任何改变不能影响实体层,只有业务需求改变了才可以改变实体。

用例Use Cases

在这个层的软件包含应用指定的业务规则,它封装和实现系统的所有用例,这些用例会混合各种来自实体的各种数据流程,并且指导这些实体使用企业规则来完成用例的功能目标。

我们并不期望改变这层会影响实体层. 我们也不期望这层被更外部如数据库 UI或普通框架影响,这层也是因为关注而外部分离的。

我们期望应用层面的技术操作都不能影响用例层,如果需求中用例发生改变,这个层的代码才会发生改变。

接口适配器Interface Adapters

这一层的软件基本都是一些适配器,主要用于将用例和实体中的数据转换为外部系统如数据库或Web使用的数据,在这个层次,可以包含一些GUI的MVC架构,表现视图 控制器都属于这个层,模型Model是从控制器传递到用例或从用例传递到视图的数据结构。

通常在这个层数据被转换,从用例和实体使用的数据格式转换到持久层框架使用的数据,主要是为了存储到数据库中,这个圈层的代码是一点和数据库没有任何关系,如果数据库是一个SQL数据库, 这个层限制使用SQL语句以及任何和数据库打交道的事情。

框架和驱动Frameworks and Drivers.

最外面一圈通常是由一些框架和工具组成,如数据库Database, Web框架等. 通常你不必在这个层不必写太多代码,而是写些胶水性质的代码与内层进行粘结通讯。这个层是细节所在,Web技术是细节,数据库是细节,我们将这些实现细节放在外面以免它们对我们的业务规则造成影响伤害。

只有四个圈层吗?

这个圆圈图是示意性的。您可能会发现您需要的不仅仅是这四个。也没有规定说你必须始终只有这四个。然而,依赖规则始终适用。源代码的依赖关系总是由外向内。当你越向内时,抽象水平越高。而最外面的一圈是低层次的具体细节。当你越向内时软件变得越为抽象,封装了更高层次的策略。

跨边界流程

在图的右下方是我们如何越过圆边界的例子。它显示控制器和界面之间是如何和用例进行通信的。注意控制流程。它开始于控制器,通过用例,然后在界面处执行。还要注意源代码的依赖关系。他们中的每一个点都是指向内部用例。我们通常使用依赖注入来实现这种依赖。

那么数据如何跨层流动呢?

通常跨层的数据是简单的数据结构。如果你喜欢你可以使用基本结构或简单的数据传输对象DTO。或可以函数可以调用数据参数。或者你可以打包到哈希表中,或为它建构一个对象。最重要是跨层传递是孤立的、 简单的数据结构。

我们不想让这个数据结构是一个实体或数据库记录,因为我们不希望它们有任何的依赖关系,这会违反了依赖规则。例如,许多数据库框架在查询响应中返回一个方便的数据格式。我们可能会要求这对这个记录重构,因为我们不想要跨层向内传递数据库记录。这就违反了依赖规则,它会迫使内圈要知道关于外圈的东西。所以当我们跨层传递数据,它总是以对内圈最方便的形式。

总结

符合这些简单的规则将会节省您大量的头痛开发。通过将软件分离到各种层,并符合依赖规则,这样您创建一个系统本质上是可测试,这意味着很多好处。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容