洋葱架构简介——分离是为了更好的结合

2023-11-06 17:58

本文主要是介绍洋葱架构简介——分离是为了更好的结合,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写出高质量软件是困难和复杂的:不仅仅是为了满足需求,还应该是健壮的,可维护的,可测试的,并且足够灵活以适应成长和变化。这就是洋葱架构出现的原因,它代表一组优秀的开发实践,用来开发任何的软件应用都是一个不错的方式。

洋葱架构,也成为整洁架构(The Clean Architecture),用来构建具有如下特点的系统:

1.    独立的Frameworks
2.    可测试
3.    独立的UI
4.    独立的数据库
5.    独立的任意外部服务(代理)

看到这张图,你应该能理解为什么称其为洋葱架构了:D, 没错,这就是它的原理图。注意,并不是只能使用4个圆环,重点在于这里的依赖原则:代码依赖是从外向内的,内环中的代码不应该知道外环中的任何东西。

这里有一些相关的词汇可以帮助更好的理解和熟悉这种方式:

  Entities:应用的业务对象。

  Use Casess: Use Casess协调(Orchestrate)数据从Entities的流入和流出,也被称为Interactors。

  Interface Adapters:这个Adapter集为Use Casess和Entities把数据转换为方便使用的格式(如渲染展示在页面上),Presenters和Controllers属于这里。

  Frameworks and Drivers:这是实现所有细节的地方:UI,Tools,Frameworks等。

 

下面用一张更生动图来辅助说明它的原理:

依赖原则(The dependency rules)

上面的同心圆代表软件的不同部分。总得来说,越往里面,代码级别越高。外层的圆是(实现)机制,而内层的圆是原则(Policies)。

让这个架构起作用的最主要原则是依赖原则。这个原则要求源码依赖只能指向内部。内部的圆不能知道外圆的任何事情。一般来说,外圆的声明(包括方法、类、变量或任何软件实体)不能被内圆引用。

同样的,外圆使用的数据格式不能被内圆使用,尤其是外圆中的Framework产生的格式。我们不想让外圆的任何东西影响内圆。

 

越往里面抽象级别越高,最外层的圆是低级别的具体细节。越往里面内容越抽象,并且封装更高级别的原则(Policies)。最里面的圆是最通用的。

Entities

Entities封装了企业级的业务规则。一个Entity可以是一个带方法的对象,也可以是一个数据结构和方法集。Entities可以被用于企业的其他应用。

如果你没有加入企业,而是仅仅在写一个简单的应用,那么这些Entities就是这个应用的业务对象。它们封装了最通用、最上层的原则。它们是最不容易改变的,即使外部的东西改变了。例如,你不想让这些对象受到页面导航、安全的影响。应用的任何操作变化都不应该影响Entities Layer。

Use Casess

这一层包含了应用特有的业务规则。它封装和实现了系统的所有用例。这些用例协调数据从entities的流入和流出,并且指导entities使用它们的企业级业务规则来达到用例的目标。

我们不希望这一层的改变影响到Entities,同时也不希望这一层被外层的改变影响,如外层的数据库,UI或者任何Frameworks的改变,这一层独立于这些关注点。

当然,我们确实期望应用的操作变化影响用例层。如果一个用例的细节改变,那么这一层的部分代码确实会受到影响。

Interface Adapters

这一层包含一个adapters set(数据适配器集),它们把适用于Use Casess和entities的数据转换为适用于外部服务(external agency,如Database或Web)的格式。 例如,这一层可以完全包括GUI的MVX架构,Presenters, Views和Controllers都属于这里。Models可能仅仅是从Controllers传到Use Casess的数据结构,然后从Use Casess返回给Presenters和Views。

 

这一层的数据会被转换,从适用于entities和Use Casess的格式转换到适用于所使用的持久化框架的格式(如数据库)。这个圆以内的代码不应该知道关于数据库的任何东西。如果是一个SQL数据库,那么所有的SQL应该被限制到这一层,并且通常来说是被限制到层中跟数据库有关的部分。

 

同样,这一层也需要一些其他必要的Adapter来把外部的数据格式(如来自于外部服务的格式),转换为适用于Use Casess和entities的格式。

 

Frameworks and Drivers.

最外面的一层通常由Frameworks和Tools组成,如Database,Web Framework等。一般来说,除了用于和内层圆交互的连接代码,你不会在这一层写很多代码。

 

这一层是实现所有细节的地方。Web和Database都是需要实现的细节。我们把这些东西放在外面以减轻来自于它们的伤害(即减轻对他们的依赖)。

 

跨界

 

在图的右下角是一个我们应该如何跨界的例子。它展示了Controllers、Presenters与下一层的Use Casess的交互。注意控制的流向,它开始于Controller,经过Use Casess,最终在Presenter中执行。同时也请注意Source Code依赖,它们每一个都指向内部的Use Casess。

 

我们通常用依赖倒置原则来解决这个明显的矛盾。比如,在Java这样的语言里,我们可以使用接口和继承关系在合适的地方让源码依赖与控制流反向来跨界。

 

例如,假设Use Cases需要访问Presenter,当然,不能是直接访问,不然会违反依赖原则,所以我们让内圆的Use Cases访问一个接口(如图中的Use Cases output port),然后外圆的Presenter实现这个接口。

在这个架构中,同样的技术也被用于跨越其他的边界。我们利用运行时多态来创建与控制流相反的SourceCode依赖以满足依赖原则,无论控制流是如何流向的。

 

通常跨界的数据都是简单的数据结构。你可以使用简单的结构或数据传输对象(Data Transfer Object)。这个数据可以简单的是方法调用的参数,你也可以把它包装到一个HashMap或者一个对象。最重要的是独立的、简单的数据结构才能跨越边界。不要投机取巧,如传输Entites或者Database rows。我们不想让这个数据结构有任何违反依赖原则的依赖。

 

例如,很多的数据库框架对于query返回一个方便的数据格式,我们可以称之为Row Structure,我们不想向内部传递这个row structure。这会让内圆知道外圆的内容而违反了依赖原则。

 

所以,我们应该以最适用于内圆使用的格式来传递跨界的数据。

 

总结

满足这些简单的原则并不难,并且会减少项目进程中很多头疼的问题。通过把软件分成几层,并且满足依赖原则,你将会创建一个本身就可测试的系统,同时还有其他的好处。当系统的任何外层部分(如Database,Web 框架)废弃的时候,你可以轻松的替换这些废弃的元素。

代码实践可以参考:https://github.com/android10/Android-CleanArchitecture/releases

本文大部分内容译自The-Clean-Architecture,其中加入了自己学习该架构时的理解,如有意见和建议,欢迎交流!

原文地址:http://www.cnblogs.com/oxgen/p/7171165.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

这篇关于洋葱架构简介——分离是为了更好的结合的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/358151

相关文章

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【Tools】AutoML简介

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 AutoML(自动机器学习)是一种使用机器学习技术来自动化机器学习任务的方法。在大模型中的AutoML是指在大型数据集上使用自动化机器学习技术进行模型训练和优化。

利用命令模式构建高效的手游后端架构

在现代手游开发中,后端架构的设计对于支持高并发、快速迭代和复杂游戏逻辑至关重要。命令模式作为一种行为设计模式,可以有效地解耦请求的发起者与接收者,提升系统的可维护性和扩展性。本文将深入探讨如何利用命令模式构建一个强大且灵活的手游后端架构。 1. 命令模式的概念与优势 命令模式通过将请求封装为对象,使得请求的发起者和接收者之间的耦合度降低。这种模式的主要优势包括: 解耦请求发起者与处理者