Clean_Achitecture_翻译

萌新翻译,勿喷
临时工出品,一切概不负责

原文戳这里

test

Over the last several years we’ve seen a whole range of ideas regarding the architecture of systems. These include:

过去几年,我们已经见到各种各样的设计到系统结构的思想,这些包括:

Hexagonal Architecture (a.k.a. Ports and Adapters) by Alistair Cockburn and adopted by Steve Freeman, and Nat Pryce in their wonderful book Growing Object Oriented Software
Onion Architecture by Jeffrey Palermo
Screaming Architecture from a blog of mine last year
DCI from James Coplien, and Trygve Reenskaug.
BCE by Ivar Jacobson from his book Object Oriented Software Engineering: A Use-Case Driven Approach

  • 六角结构 (出现在《Growing Obejct Oriented Software》)查看
  • 洋葱结构查看
  • 流结构查看
  • DCI结构(data数据,context场景,interaction交互)查看
  • BCE结构(Boundary-Control-Entity )查看

Though these architectures all vary somewhat in their details, they are very similar. They all have the same objective, which is the separation of concerns. They all achieve this separation by dividing the software into layers. Each has at least one layer for business rules, and another for interfaces.

这些结构除了某些细节上有所不同,都非常的相似。为了达成关系的分离,他们都采用了软件分层。每个都只有一个业务规则层,以及一些其它的接口。

Each of these architectures produce systems that are:

每个结构系统都是:

Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.
The diagram at the top of this article is an attempt at integrating all these architectures into a single actionable idea.

  • 无框架依赖。这些结构都不依赖与特定的库。这允许你把框架当工具用,而不是在限制约束下填充你的系统
  • 可测性。这些业务规则能够在没有界面,数据库,web服务器或者任何其它的外部元素的情况下被测试。
  • 无界面依赖。界面可以很容易的在不改动系统其它部分的情况进行改动。举个例子,在没有改动业务逻辑的情况下,一个web的界面可能被替换成控制台的界面。
  • CounchDB(面向文档的数据库).业务逻辑没有与数据库绑定
  • 无外部代理依赖。事实上,你的业务逻辑非常的简单,完全不知道外部的情况。

文章顶部的图片尝试集成这些结构为一个单独可行的想法。

The Dependency Rule

The concentric circles represent different areas of software. In general, the further in you go, the higher level the software becomes. The outer circles are mechanisms. The inner circles are policies.

这些同心的圆环代表软件的不同区域。通常来讲,越往里面去,软件的层级更高。外部的圆环是实现机制。内部的圆是原则。

The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.

这个结构能够正常运行的最根本原则是依赖原则。这个原则是:这些源码的只能向内依赖。任何内部的圆不了解外部的圆。尤其是,在外部申明的方法,类,变量等一切的软件实体不能把内部的圆用到。

By the same token, data formats used in an outer circle should not be used by an inner circle, especially if those formats are generate by a framework in an outer circle. We don’t want anything in an outer circle to impact the inner circles.

同样的,外部圆使用的数据格式也不能被内部的圆使用,尤其是外部圆通过框架产生来某种数据格式。我们不想外部圆的任何东西能够影线到内部的圆。

Entities

Entities encapsulate Enterprise wide business rules. An entity can be an object with methods, or it can be a set of data structures and functions. It doesn’t matter so long as the entities could be used by many different applications in the enterprise.

实体封装基本的企业业务逻辑。一个实体可以是一些方法,也可以是一组数据结构,或者一些功能。只要这些实体能够被企业中的任何一个应用使用可以了。

If you don’t have an enterprise, and are just writing a single application, then these entities are the business objects of the application. They encapsulate the most general and high-level rules. They are the least likely to change when something external changes. For example, you would not expect these objects to be affected by a change to page navigation, or security. No operational change to any particular application should affect the entity layer.

假如你没有企业,仅仅是写一个单应用程序。这些实体就是应用业务对象。它们是对一些当外部产生变化时,里面最不可能产生变化的最通用,最高级规则的封装。举个例子,你可能不希望这些对象被页面的导航栏,安全性等影线。没有操作能够影响到实体层

Use Cases

The software in this layer contains application specific business rules. It encapsulates and implements all of the use cases of the system. These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.

软件的这一层包含软件的特定业务逻辑。它封装和实现一些系统的用例。这些用例精心组织数据进出实体层,并且指挥实体层去实现用例。

We do not expect changes in this layer to affect the entities. We also do not expect this layer to be affected by changes to externalities such as the database, the UI, or any of the common frameworks. This layer is isolated from such concerns.

**我们不希望用例层的改变影响到实体层。我们同样不希望这一层被外部的像数据库,UI等影响。
这一次层是独立的。**

We do, however, expect that changes to the operation of the application will affect the use-cases and therefore the software in this layer. If the details of a use-case change, then some code in this layer will certainly be affected.

我们认为,无论如何,应用的操作改变将影响用例,最终会影响到软件的这一层。将如用例的细节发生了改变,这一层的一些代码是会有影线的。

Interface Adapters

The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web. It is this layer, for example, that will wholly contain the MVC architecture of a GUI. The Presenters, Views, and Controllers all belong in here. The models are likely just data structures that are passed from the controllers to the use cases, and then back from the use cases to the presenters and views.

在软件的这一层是一些适配器,它们将最适合用例和实体的数据格式转换为最适合外部代理(像数据库或者Web)最适用的格式。这一层将完成的包含GUI的MVC结构。Preservertes,Views,Controllers 都属于这里。Models更像是从Controllers传递到Use Cases,再从User Case返回到Presenters和Views 的数据结构

Similarly, data is converted, in this layer, from the form most convenient for entities and use cases, into the form most convenient for whatever persistence framework is being used. i.e. The Database. No code inward of this circle should know anything at all about the database. If the database is a SQL database, then all the SQL should be restricted to this layer, and in particular to the parts of this layer that have to do with the database.

Also in this layer is any other adapter necessary to convert data from some external form, such as an external service, to the internal form used by the use cases and entities.

Frameworks and Drivers.

The outermost layer is generally composed of frameworks and tools such as the Database, the Web Framework, etc. Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards.

This layer is where all the details go. The Web is a detail. The database is a detail. We keep these things on the outside where they can do little harm.

Only Four Circles?

No, the circles are schematic. You may find that you need more than just these four. There’s no rule that says you must always have just these four. However, The Dependency Rule always applies. Source code dependencies always point inwards. As you move inwards the level of abstraction increases. The outermost circle is low level concrete detail. As you move inwards the software grows more abstract, and encapsulates higher level policies. The inner most circle is the most general.

Crossing boundaries.(跨边界)

At the lower right of the diagram is an example of how we cross the circle boundaries. It shows the Controllers and Presenters communicating with the Use Cases in the next layer. Note the flow of control. It begins in the controller, moves through the use case, and then winds up executing in the presenter. Note also the source code dependencies. Each one of them points inwards towards the use cases.

在图的右下是一个怎么跨过圆的边界的例子。它展示了Controllers 和 Presenter与 处于下一层的用例层进行交互。注意控制流。它开始于Controller,移动到用例层,之后收尾运行在Presenter.也需要注意源码的依赖。每一个点展示泄漏了的用例层的内部情况。

We usually resolve this apparent contradiction by using the Dependency Inversion Principle. In a language like Java, for example, we would arrange interfaces and inheritance relationships such that the source code dependencies oppose the flow of control at just the right points across the boundary.

通常情况下,我们解决这种矛盾使用依赖倒转原则。在java语言中,我们可以通过接口和继承实现源代码的依赖反转控制流,仅仅正确的点通过边界。

For example, consider that the use case needs to call the presenter. However, this call must not be direct because that would violate The Dependency Rule: No name in an outer circle can be mentioned by an inner circle. So we have the use case call an interface (Shown here as Use Case Output Port) in the inner circle, and have the presenter in the outer circle implement it.

举个例子:考虑一种情况,用例需要调用Presenter.但是这种调用不能直接调用,因为它会违反没有外层能够影响内层的原则。因此,用例层可以调用接口(表现在这里就是用例输出口),Presenter和外层实现它。

The same technique is used to cross all the boundaries in the architectures. We take advantage of dynamic polymorphism to create source code dependencies that oppose the flow of control so that we can conform to The Dependency Rule no matter what direction the flow of control is going in.

这类似的计数被使用在这个结构的所有结构。我们利用动态的多态性去创造源代码依赖来反转控制流,这样,我们可以服从依赖原则,而不是关系控制流的去向。

What data crosses the boundaries.

什么样的数据来穿过边界。

Typically the data that crosses the boundaries is simple data structures. You can use basic structs or simple Data Transfer objects if you like. Or the data can simply be arguments in function calls. Or you can pack it into a hashmap, or construct it into an object. The important thing is that isolated, simple, data structures are passed across the boundaries. We don’t want to cheat and pass Entities or Database rows. We don’t want the data structures to have any kind of dependency that violates The Dependency Rule.

典型的,通过边界的是简单的数据结构体。你能使用基本的结构或者简单的数据传输对象。或者,数据可以简单是函数调用的参数。又或者你能够包装它到一个哈希Map或对象。最重要是这些都是独立的,简单的,数据体被传递通过数据边界。我们不想欺骗或者传递实体或者数据库行。我们不想数据的结构有任何的依赖违法依赖原则。

For example, many database frameworks return a convenient data format in response to a query. We might call this a RowStructure. We don’t want to pass that row structure inwards across a boundary. That would violate The Dependency Rule because it would force an inner circle to know something about an outer circle.

举个例子,很多的数据库框解会返回一个合适的数据格式来响应查询。我们可以叫它RowStructure.我们不想传递这个RowStructre到内部。这违法了原则,这将会强迫内层知道外层的细节。

So when we pass data across a boundary, it is always in the form that is most convenient for the inner circle.

因此,当我们跨边界传递数据时,它都是最适合内层圆的格式。

Conclusion (结论)

Conforming to these simple rules is not hard, and will save you a lot of headaches going forward. By separating the software into layers, and conforming to The Dependency Rule, you will create a system that is intrinsically testable, with all the benefits that implies. When any of the external parts of the system become obsolete, like the database, or the web framework, you can replace those obsolete elements with a minimum of fuss.

服从这些简单的规则不是很困难,但是将减少迭代的头痛。通过软件的分层,服从依赖原则,你将创建一个真正可测的系统。系统的外层部分像数据库或者Web框架,变的废弃,你能够已最小的代价简单的替换这些废弃的元素。

Robert Martin (Uncle Bob) is a Master Craftsman. He’s an award-winning author, renowned speaker, and has been an über software geek since 1970.

related posts
Loose Coupling in Go lang Javier Saldana
Mistaking Encapsulation for Abstraction Kevin Buchanan
Thinking Differently About the Single Responsibility Principle Cory Foy
NO DB Uncle Bob
Service Oriented Agony Uncle Bob
What Is Assumed When Deferring Database Decisions? Patrick Gombert
Concurrency Control Strategies for Secret Agents Kevin Buchanan
Decomposing Asynchronous Workers in Ruby Kevin Buchanan
Organizing Your Clojure Environment and Logs with Leiningen Kevin Buchanan
Take Pride in Your Legacy (Code) Ginny Hendry
more posts by this author
Future Proof
Agile is not now, nor was it ever, Waterfall.
VW
WATS Line 54
A Little Structure
Make the Magic go away.
The Little Singleton
The First Micro-service Architecture
Language Layers
Does organization matter?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值