链接:http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
I've spoken several times about a specific type of architecture I call "Onion Architecture". I've found that it leads to more maintainable applications since it emphasizes separation of concerns throughout the system. I must set the context for the use of this architecture before proceeding. This architecture is not appropriate for small websites. It is appropriate for long-lived business applications as well as applications with complex behavior. It emphasizes the use of interfaces for behavior contracts, and it forces the externalization of infrastructure.
The diagram you see here is a representation of traditional layered architecture. This is the basic architecture I see most frequently used. Each subsequent layer depends on the layers beneath it, and then every layer normally will depend on some common infrastructure and utility services. The big drawback to this top-down layered architecture is the coupling that it creates. Each layer is coupled to the layers below it, and each layer is often coupled to various infrastructure concerns. However, without coupling, our systems wouldn't do anything useful, but this architecture creates unnecessary coupling.
我曾经在几次演讲中提到了一种特定的架构,名曰“洋葱架构” 。我发现它会产生更易维护的应用,因为它强调了整个系统的关注点分离。在继续之前,我必须为这种架构的应用设定上下文。这种架构不适用于小的web站点。它更适合于长生命周期的业务应用以及有复杂行为的应用。它强调了行为契约的接口化和基础设施外部化。您在这里看到的图是传统分层结构的表示形式。这是我所看到的最常用的基本架构。每个后续层依赖于它下面的层,然后每个层通常依赖于一些公共基础设施和工具服务。这种自顶向下的分层体系结构的最大缺点是它所创建的耦合性。每个层耦合到它下面的层,并且每个层常常耦合到各种基础设施关注点。虽然说没有耦合我们的系统就不能做任何有用的事情,但是这种体系结构会造成不必要的耦合。
The biggest offender (and most common) is the coupling of UI and business logic to data access. Yes, UI is coupled to data access with this approach. Transitive dependencies are still dependencies. The UI can't function if business logic isn't there. Business logic can't function if data access isn't there. I'm intentionally ignoring infrastructure here because this typically varies from system to system. Data access changes frequently. Historically, the industry has modified data access techniques at least every three years; therefore, we can count on needing to modify data access three years from now for any healthy, long-lived systems that's mission-critical to the business. We often don't keep systems up-to-date because it's impossible to do. If coupling prevents easily upgrading parts of the system, then the business has no choice but to let the system fall behind into a state of disrepair. This is how legacy systems become stale, and eventually they are rewritten.
最大的侵入(和最常见的)是UI和业务逻辑对数据访问的耦合。是的,UI通过这种方式耦合到数据访问。传递依赖仍然是依赖。如果业务逻辑不存在,UI就不能运行。如果数据访问不存在,业务逻辑就不能运行。我故意忽略基础设施,因为这通常会因系统而异。数据访问频繁更改。从历史上看,该行业至少每三年修改一次数据访问技术;因此,我们可以指望三年后,对任何一个对业务至关重要的健康的、长生命周期的系统都需要修改数据访问方式。我们无法进行系统更新,因为更新极其困难。如果耦合阻止了系统某部分的易升级性,那么企业别无选择,只能让系统落入到一个失修的状态。这就是遗留系统为何变得陈旧,并最终被重写的原因。
I propose a new approach to architecture. Honestly, it's not completely new, but I'm proposing it as a named, architectural pattern. Patterns are useful because it gives software professionals a common vocabulary with which to communicate. There are a lot of aspects to the Onion Architecture, and if we have a common term to describe this approach, we can communicate more effectively.
我提出了一种新的架构方法。老实说,它不是完全新的,但我建议将它命名为一种架构模式。模式之所以有用,是因为它给软件专业人员提供了一个通用的词汇表来进行交流。洋葱架构有很多方面,如果我们有一个共同的术语来描述这种方法,我们就能更有效地进行沟通。
The diagram to the left depicts the Onion Architecture. The main premise is that it controls coupling. The fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center. This architecture is unashamedly biased toward object-oriented programming, and it puts objects before all others.
In the very center we see the Domain Model, which represents the state and behavior combination that models truth for the organization. Around the Domain Model are other layers with more behavior. The number of layers in the application core will vary, but remember that the Domain Model is the very center, and since all coupling is toward the center, the Domain Model is only coupled to itself. The first layer around the Domain Model is typically where we would find interfaces that provide object saving and retrieving behavior, called repository interfaces. The object saving behavior is not in the application core, however, because it typically involves a database. Only the interface is in the application core. Out on the edges we see UI, Infrastructure, and Tests. The outer layer is reserved for things that change often. These things should be intentionally isolated from the application core. Out on the edge, we would find a class that implements a repository interface. This class is coupled to a particular method of data access, and that is why it resides outside the application core. This class implements the repository interface and is thereby coupled to it.
左边的图描述了洋葱架构。主要前提是它控制了耦合。基本原则是,所有代码都依赖于更为核心的层,不能依赖于核心之外的层。换句话说,所有的耦合都指向中心。这个架构有点无耻的偏向于面向对象编程,并将对象放在其他之前。
最中心的是领域模型,它代表了面向组织的真实模型的状态和行为组合。领域模型周围还有其他的具有更多行为的层。应用内核中的层数不是一成不变的,但请记住,领域模型是最中心的,因为所有的耦合都朝向中心,所以领域模型只耦合到自身。围绕领域模型的第一层通常是提供对象保存和检索行为的接口,称为仓库接口。然而对象保存行为不在应用内核中,因为它通常涉及数据库。只有接口在应用内核中。在边缘我们看到UI、基础结构和测试。外层是为经常变化的事物保留的。这些东西应该与应用内核隔离开来。在边缘,我们会找到一个实现仓库接口的类。这个类与特定的数据访问方法耦合,这就是它驻留在应用内核之外的原因。这个类实现了仓库接口,并因此与它相耦合。
The Onion Architecture relies heavily on the Dependency Inversion principle. The application core needs implementation of core interfaces, and if those implementing classes reside at the edges of the application, we need some mechanism for injecting that code at runtime so the application can do something useful.
洋葱架构很大程度上依赖于依赖倒置原则(DIP)。应用内核需要核心接口的实现,如果这些实现类驻留在应用程序的边缘,我们需要一些在运行时可注入该代码的机制,以便保证应用程序的可用性。
The database is not the center. It is external. Externalizing the database can be quite a change for some people used to thinking about applications as "database applications". With Onion Architecture, there are no database applications. There are applications that might use a database as a storage service but only though some external infrastructure code that implements an interface which makes sense to the application core. Decoupling the application from the database, file system, etc, lowers the cost of maintenance for the life of the application.
数据库不在内而在外。对于那些习惯于把应用程序看作“数据库应用程序”的人来说,将数据库外部化是一个很大的改变。有了洋葱架构,就没有了数据库应用程序。有些应用程序可能使用数据库作为存储服务,但只有一些实现了对应用内核有意义的接口的外部基础结构代码。将应用程序与数据库、文件系统等解耦,降低了应用程序的维护成本。
Alistair Cockburn has written a bit about Hexagonal architecture. Hexagonal architecture and Onion Architecture share the following premise: Externalize infrastructure and write adapter code so that the infrastructure does not become tightly coupled.
Alistair Cockbum写过六角架构。六角架构和洋葱架构共享如下前提:基础设施外部化,通过写适配代码将基础设施解耦。
I'll be writing more about the Onion Architecture as a default approach for building enterprise applications. I will stay in the enterprise system space and all discussion will reside in that context. This gets even more interesting when there are multiple processes making up a single software system.
我将撰写更多关于将洋葱架构作为构建企业应用默认方法的文章。我将停留在企业系统空间,所有讨论都限制在此上下文中。当多个进程组成一个单一软件系统的时候,这将变得更加有趣。The diagram to the left depicts the Onion Architecture. The main premise is that it controls coupling. The fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center. This architecture is unashamedly biased toward object-oriented programming, and it puts objects before all others.
In the very center we see the Domain Model, which represents the state and behavior combination that models truth for the organization. Around the Domain Model are other layers with more behavior. The number of layers in the application core will vary, but remember that the Domain Model is the very center, and since all coupling is toward the center, the Domain Model is only coupled to itself. The first layer around the Domain Model is typically where we would find interfaces that provide object saving and retrieving behavior, called repository interfaces. The object saving behavior is not in the application core, however, because it typically involves a database. Only the interface is in the application core. Out on the edges we see UI, Infrastructure, and Tests. The outer layer is reserved for things that change often. These things should be intentionally isolated from the application core. Out on the edge, we would find a class that implements a repository interface. This class is coupled to a particular method of data access, and that is why it resides outside the application core. This class implements the repository interface and is thereby coupled to it.