`
zzmccnu
  • 浏览: 75865 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

架构整洁之道(转载)

阅读更多

 

架构整洁之道

这篇文章是翻译(Uncle Bob Martin)的文章。原文在这:http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html。这篇文章作者尝试使用简单的观点将各种架构的共通之处和最终目标说清楚。全文要说清楚的就是一件事“如何写出整洁的架构”。作者希望在架构系统的时候只需要秉持最简单的两个观点(分层和依赖规则)开发,就能开发出干净整洁的系统架构。

以下是译文

clip_image001

 

过去几年间有许多关于系统架构的观点。比如:

1 六角架构(Hexagonal Architecture )。 这种架构是由Alistair Cockburn提出的,并由Steve Freeman和Nat Pryce在他们的书《Growing Object Oriented Software 》中提到。

2 洋葱架构(Onion Architecture )。提出者是Jeffrey Palermo。

3 尖叫架构(Screaming Architecture)。提出者是Uncle 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必须能非常容易独立地修改。而不能在改变UI的同时需要改变系统其他部分。比如当把系统的UI从Web UI改成控制台UI,你并不需要改变任何业务逻辑的代码。

4 与数据库的分离。

能很方便地在Oracle,SQL Server,Mongo DB,BigTable,CouchDB或者其他数据库中进行切换和改变。业务逻辑决不能依赖这些数据库。

5 与外部结构的分离。

系统的业务逻辑并不需要知道任何外部的结构。

 

文章最上面的图就是将所有这些架构进行统一概括,提取出统一的观点。

依赖规则(The Dependency Rule)

同心圆代表的是不同层级的软件代码。通常当你更深一步思考构造你的系统的时候,你的系统就会在更高的层级。最外层的圈代表的是机制级别的系统。最内层的代表的是策略级别的系统。

最重要的一条规则是依赖规则(The Dependency Rule)。这条规则说的是:代码依赖只能使由外向内。换句话说,内层结构的代码不能包含有任何外层结构的信息。尤其是一些外层结构的名称不应该被内层结构的代码提到,比如函数名,类名,变量名,或者其他的系统实体的名称。

同样的,外层的数据结构不应该被内层代码使用,特别是那些由外部框架生成的数据结构。我们并不希望外部结构的任何东西会影响到内部结构。

实体层(Entities)

实体是用来封装公司的业务规则的。一个实体可以是一个带方法的对象,也可以是一些数据结构和函数。只要实体能被公司的不同业务逻辑部件使用,实体的具体表现形式是无所谓的。

或许你并不是想写公司级的架构,而只是想写一个简单的应用,那么这里实体就是指的应用的业务逻辑对象。它们封装了最通用的规则,并且当外部环境变化的时候,这些实体是最不需要被变化的。举例来说,比如在增加翻页需求或者是安全需求的时候,这些实体是最不应该被改变的。没有任何具体的应用需要改变实体层。

用户实例层(Use Cases)

这一层的软件结构包含了具体的应用业务逻辑。它实现了所有的用户实例。这些用户的实例由流入实体的数据流和流出实体的数据流实现,这些用户实例使得内层的实体能依靠实体内定义的业务逻辑规则来完成系统的用户需求。

我们不希望用户实例层的任何改变会影响到实体层。我们同样也不希望用户实例层会被外部的结构层,比如UI、数据库或者任何公共的框架,的改变而影响。这层应该是独立于这些概念的。

当然,必然发生的是应用的业务逻辑被修改会影响到用户实例层的代码和结构。如果用户的需求改变了,这层的部分当然会被修改。

接口适配层(Interface Adapters)

这一层的软件结构的目的就是进行数据的转换,将便于用户实例和实体层操作的数据结构变化成为最便于外部结构(比如数据库或者Web)操作的数据结构。比如GUI的MVC结构,表现器、视图器、控制器都是属于这个结构的。这层很可能是通过控制器将数据结构传给用户实例层,并且返回数据给表现器,视图器。

数据在这层会被转换,将便于实体层和用户实例层使用的数据转化成为持久层能使用的数据,比如数据库。这一层的代码并不需要知道任何数据库的信息。如果数据库是SQL数据库,那么,所有的SQL语言应当在这层被限制使用,特别是在这一层中与数据库有交互的代码部分。

当一些外部的服务需要与用户实例层和实体层进行交互的时候,这时候需要的数据转换也理所当然地放在这一层了。

框架和驱动层(Frameworks and Drivers)

最外层是由框架和使用工具组成的。比如数据库,Web框架等。通常你并不需要写很多代码就能达到与内层进行交互的行为。

这层表达的是所有的数据应该具体最终到达的地方。Web是数据的最终到达地,数据库也是数据的最终到达地。我们把这些东西放在最外层,它们几乎对整个系统的架构造不成什么影响。

 

只有四层?

答案是否定的。这个分层模型是纲要性的。在具体实现中,你会发现你可能需要到比四层更多的层级。并没有任何规定说你必须只能实现这四个层级。但是,依赖规则(The Dependency Rule)是必须遵守的:代码依赖只能使由外向内。越向内,抽象程度越高,越向外,细节信息越多。当你越向内设计的时候,你需要设计越高层面的策略。内部层级比外部层级更抽象。

跨层调用

图片的右下角是一个如何跨层调用的例子。它演示了控制器和表现器如何和用户实例层进行交互。注意下流向,从控制器开始,通过用户实例层,然后向上执行到表现器。这里也需要注意它们的代码依赖,必须是向内依赖的。

我们通常使用依赖倒置原则(Dependency Inversion Principle)来处理这种情况。比如在JAVA中,我们会使用接口或者继承关系来保证代码会在制定的地方依赖倒置。

举例说明,假设用户实例需要调用表现器。但是这种调用是违背了依赖规则的:外部的逻辑名称不应该被内部提到。所以我们让用户实例层调用一个接口(这里叫做用户实例输出端口Use Case Output Port),然后让表现层在外部实现这个接口。

相同的方法可以使用在架构的所有跨层调用上。因此实际上我们能使用多种形式的代码依赖达到我们能让控制流按照依赖规则的反方向流动。

什么数据能跨层调用?

一般跨层调用的数据是简单的数据结构。你可以使用数据结构或者是简单的数据传输流,又或者可以通过函数的参数来进行传递。你也可以将数据封装到一个hashmap结构,或者一个对象中。数据传输最重要的事情是无依赖,简单。我们并不希望跨层传递的数据是实体,或者是数据表的行数据,理由是我们不希望数据有任何形式的违反依赖规则。

例如,许多数据库框架对query查询返回行结构,我们叫它RowStructure。我们并不希望将这个RowStructure传递给内层结构,因为这个违反了依赖规则,它会强制让内层结构了解外层的结构。

总结

遵守这些简单的规则并不难,但是它们会解决你很多头疼的问题。将系统分层,遵守依赖规则,你就会自然写出可测试的系统了,所有附带的好处也会实现了。当任何外部的系统是独立的,比如数据库、web框架,你就能以最小的代价将它们进行替换。

作者简介

clip_image002

Robert C. Martin (Uncle Bob) , 8th Light公司的Master Craftsman, 获奖作家,著名的演说家,uber software geek。

它的著作有:

Designing Object Oriented c++ Applications using the Booch Method

Patterns Languages of Program Design 3(程序设计的模式语言)

More c++ Gems

Extreme Programming in Practice(解析极限编程)

Agile Software Development: Principles, Patterns, and Practices(敏捷软件开发:原则、模式与实践)

uml for java Programmers(UML:JAVA程序员指南)

Clean Code (代码整洁之道)

The Clean Coder(编码整洁之道:专业程序员的行为准则)

分享到:
评论

相关推荐

    整洁的架构

    整洁架构的特点之一就是将系统分解为不同的层次或层,每一层都有明确的职责和约束。这些层次通常包括: 1. 实体层(Entities):这是业务规则的中心。实体层包含了业务的核心模型,这些模型可以被多个不同的应用...

    读书笔记:学习《架构整洁之道》.zip

    读书笔记:学习《架构整洁之道》

    读书笔记:《架构整洁之道》读书笔记.zip

    读书笔记:《架构整洁之道》读书笔记

    读书笔记:《架构整洁之道》一书中的 Hunt the Wumpus 游戏.zip

    读书笔记:《架构整洁之道》一书中的 Hunt the Wumpus 游戏

    企业IT架构转型之道.pdf

    企业IT架构转型之道.pdf 企业IT架构转型之道是阿里巴巴中间件首席架构师钟华(花名:古谦)在2015年底启动的中台战略中台炮火群。该战略旨在提高企业的核心竞争力,通过提质转型、降本增效,提高业务快速响应和创新...

    IT架构转型之道《kindel适用.mobi格式》

    该资源支持kindel设备,.mobi格式。很好的一本书。开拓架构理解思路。

    企业IT架构转型之道.pdf_it_QI_中间件_

    《企业IT架构转型之道》是针对现代企业信息技术架构变革的一份深度研究报告,尤其强调了中间件在其中的关键作用。这份资料出自阿里巴巴,以其在中台战略上的实践为背景,揭示了如何通过中间件技术实现企业的高效运营...

    测试架构师修炼之道:从测试工程师到测试架构师1

    【测试架构师修炼之道:从测试工程师到测试架构师1】这本书主要探讨了软件测试工程师如何进行职业规划,以及如何成长为一名优秀的测试架构师。书中通过两个面试故事引入了核心议题,即测试的核心并不仅限于业务知识...

    整洁架构模式详细介绍文档

    整洁架构介绍, 该文档详细介绍了整洁架构模式。

    软件开发+架构基础+代码整洁之道

    ### 软件开发+架构基础+代码整洁之道 #### 一、引言 随着软件项目的日益复杂化,保持代码的整洁与可维护性成为软件工程师必须面对的重要问题。本书《软件开发+架构基础+代码整洁之道》旨在帮助开发者理解和实践高...

    企业IT架构转型之道V3.0.pptx

    企业IT架构转型之道V3.0.pptx

    《企业IT架构转型之道》读书笔记.pdf

    《企业IT架构转型之道》是阿里巴巴中间件研发团队成员钟华所著的一本书,主要探讨了阿里巴巴的中台战略思想及其在实际架构中的应用。这本书分为三大部分,共计11章,精炼成52页的内容,旨在帮助企业理解并实施IT架构...

    藏经阁-企业IT架构转型之道.pdf

    "藏经阁-企业IT架构转型之道.pdf" 该资源主要讲述了企业IT架构转型的重要性和方法,作者以阿里巴巴集团的中台战略为例,介绍了中台架构的价值和实施方法。中台架构是一种新的企业IT架构模式,它可以帮助企业快速...

    软件平台架构设计与技术管理之道.docx

    "软件平台架构设计与技术管理之道" 本文总结了软件平台架构设计与技术管理之道的重要性、架构设计要点、架构设计目标与原则、技术管理的关键作用等知识点。 一、软件平台架构设计的重要性 软件平台架构设计是指...

    软件平台架构设计与技术管理之道.pptx

    《软件平台架构设计与技术管理之道》是一本深入探讨软件平台构建与管理的权威之作,由知名专家李中华撰写。本书以清晰的思维导图、详细的摘要和丰富的实践案例,全面解析了软件平台架构设计的核心理念和技术管理的...

    软件架构之道——我所理解的软件架构_软件架构之道_

    本文将深入探讨“软件架构之道”,解析架构思维、架构的本质、思维方法、常见误区、核心理念以及修炼方法,以期帮助读者更好地理解和实践软件架构。 首先,我们需要了解什么是“架构思维”。架构思维是一种高层次的...

    微软软件架构师的修炼之道

    "微软软件架构师的修炼之道"是一个专注于培养这一专业能力的主题,它涵盖了架构师的角色定义、成长路径、技能需求以及在微软环境中的实践。 首先,我们来理解“何谓架构师”。软件架构师并非只是编写代码的工程师,...

    企业IT架构转型之道.pptx

    企业IT架构转型之道.pptx

    企业层面的架构设计力提升之道-温昱

    【企业层面的架构设计力提升之道】是温昱在2009年软件大会上发表的演讲主题,这个主题深入探讨了如何在企业层面上提升架构设计能力,这对于任何规模的企业,尤其是快速发展或转型中的IT组织来说,都是至关重要的。...

Global site tag (gtag.js) - Google Analytics