当前位置: 首页 > news >正文

干净的架构The Clean Architecture_软件架构系列

本文转载自:https://www.jdon.com/artichect/the-clean-architecture.html ,这个博客站很有历史了,博主经常翻译Github大牛的文章,值得墙裂推荐。

 


 

 

干净的架构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提出

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

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

  1. 独立的框架. 这样的架构并不依赖与应用软件的具体库包,这样可以将框架作为工具,而不必将你的系统都胡乱混合在一起。
  2. 可测试. 业务规则能够在没有UI和数据库 或Web服务器的情况下被测试。
  3. UI的独立性. UI改变变得容易,不必改变系统的其余部分,一个Web UI能被一个控制台或专门的图形UI替代, 这些读不必更改业务核心规则。
  4. 数据库的独立性. 你能够在Oracle或SQL Server Mongo, BigTable, CouchDB,或之间切换, . 你的业务规则不会和数据库绑定
  5. 独立的外部代理,其实你的业务规则可以对其外面的技术世界毫无所知,比如是否使用了MVC或DCI都可以不关心。

这种干净的架构图如下:

干净的架构

依赖规则Dependency Rule

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

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

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

实体Entities

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

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

用例Use Cases

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

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

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

接口适配器Interface Adapters

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

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

框架和驱动 

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

只有四个圈层吗? 

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

跨边界流程 

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

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

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

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

总结 

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

转载于:https://www.cnblogs.com/muyun/p/9418476.html

相关文章:

  • SEO优化:网站优化的swot介绍分析
  • Eclipse基金会发布Eclipse Photon IDE
  • win10下安装mysql5.7
  • 通过示例来学习ES2016, 2017, 2018的新特性
  • 从团队级到企业级 Worktile推动企业转型、升级
  • jupyter notebook常用快捷键
  • Java代码性能优化总结
  • SMSSDK合理运用好友关系的方法
  • Java Proxy Pattern(代理模式)
  • BZOJ1015 星球大战starwar
  • 教你找回 git stash 数据中的数据
  • 驱动移植过程中DMA内存相关接口替换
  • HBase二级索引实现方案
  • 前向星和链式前向星
  • 开源PaaS Rainbond v3.7.0-rc1版本更新,系统生产稳定性大幅提升
  • 【译】理解JavaScript:new 关键字
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • JavaScript的使用你知道几种?(上)
  • JS专题之继承
  • leetcode98. Validate Binary Search Tree
  • Mac转Windows的拯救指南
  • MD5加密原理解析及OC版原理实现
  • PHP CLI应用的调试原理
  • SAP云平台里Global Account和Sub Account的关系
  • SpingCloudBus整合RabbitMQ
  • 将回调地狱按在地上摩擦的Promise
  • 每天10道Java面试题,跟我走,offer有!
  • 如何合理的规划jvm性能调优
  • 设计模式(12)迭代器模式(讲解+应用)
  • 使用agvtool更改app version/build
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 整理一些计算机基础知识!
  • $.proxy和$.extend
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (1)STL算法之遍历容器
  • (12)目标检测_SSD基于pytorch搭建代码
  • (145)光线追踪距离场柔和阴影
  • (TOJ2804)Even? Odd?
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (五)Python 垃圾回收机制
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)人的集合论——移山之道
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • *p++,*(p++),*++p,(*p)++区别?
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .gitignore文件---让git自动忽略指定文件
  • .Net 6.0 处理跨域的方式
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .NET大文件上传知识整理
  • .NET的微型Web框架 Nancy
  • .net和jar包windows服务部署