网站制作自学网,wordpress 内容 主题,百度做网站的服务合同,wordpress 无法安装主题写出高质量软件是困难和复杂的#xff1a;不仅仅是为了满足需求#xff0c;还应该是健壮的#xff0c;可维护的#xff0c;可测试的#xff0c;并且足够灵活以适应成长和变化。这就是洋葱架构出现的原因#xff0c;它代表一组优秀的开发实践#xff0c;用来开发任何的软…写出高质量软件是困难和复杂的不仅仅是为了满足需求还应该是健壮的可维护的可测试的并且足够灵活以适应成长和变化。这就是洋葱架构出现的原因它代表一组优秀的开发实践用来开发任何的软件应用都是一个不错的方式。
洋葱架构也成为整洁架构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:这是实现所有细节的地方UIToolsFrameworks等。 下面用一张更生动图来辅助说明它的原理 依赖原则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跨平台或扫描二维码关注