跳转到内容

User:Viztor/域驱动开发

维基百科,自由的百科全书

域驱动开发 (英语:Domain-driven design,缩写 DDD)是一种 软件的开发 的模式,通过不断变化的 model 层。[1] 采用�此种设计的前提是:

  • 把项目的主要重点放在核心域和域逻辑;
  • 把复杂的设计放在域界的模型上;
  • 发起一个创造性的合作之间的技术和 域界专家 以迭代地完善的概念模式,解决特定领域的问题。

该词是由 埃里克*埃文斯 (Eric Evans) 在其同名书中创造。[2]

概念[编辑]

有以下概念:

上下文
词或句子出现的位置。
一类知识 (ontology),影响,或活动。软件使用的场景。
模型
一类描述域的不同方面并可用于解决相关问题的系统化的抽象。
统一术语
一种团队成员使用,为了描述域模型而构造的语言。

战略[编辑]

模式在战略领域驱动的设计和它们之间的关系

Ideally, it would be preferable to have a single, unified model. While this is a noble goal, in reality it typically fragments into multiple models. It is useful to recognize this fact of life and work with it.

Strategic Design is a set of principles for maintaining model integrity, distillation of the Domain Model and working with multiple models.

Bounded context[编辑]

Multiple models are in play on any large project. Yet when code based on distinct models is combined, software becomes buggy, unreliable, and difficult to understand. Communication among team members becomes confusing. It is often unclear in what context a model should not be applied.

Therefore: Explicitly define the context within which a model applies. Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside.

Continuous integration[编辑]

When a number of people are working in the same bounded context, there is a strong tendency for the model to fragment. The bigger the team, the bigger the problem, but as few as three or four people can encounter serious problems. Yet breaking down the system into ever-smaller contexts eventually loses a valuable level of integration and coherency.

Therefore: Institute a process of merging all code and other implementation artifacts frequently, with automated tests to flag fragmentation quickly. Relentlessly exercise the ubiquitous language to hammer out a shared view of the model as the concepts evolve in different people’s heads.

Context map[编辑]

An individual bounded context leaves some problems in the absence of a global view. The context of other models may still be vague and in flux.

People on other teams won’t be very aware of the context bounds and will unknowingly make changes that blur the edges or complicate the interconnections. When connections must be made between different contexts, they tend to bleed into each other.

Therefore: Identify each model in play on the project and define its bounded context. This includes the implicit models of non-object-oriented subsystems. Name each bounded context, and make the names part of the ubiquitous language. Describe the points of contact between the models, outlining explicit translation for any communication and highlighting any sharing. Map the existing terrain.

基础[编辑]

In the book Domain-Driven Design, a number of high-level concepts and practices are articulated, such as ubiquitous language meaning that the domain model should form a common language given by domain experts for describing system requirements, that works equally well for the business users or sponsors and for the software developers. The book is very focused on describing the domain layer as one of the common layers in an object-oriented system with a multilayered architecture. In DDD, there are artifacts to express, create, and retrieve domain models:

Entity
An object that is not defined by its attributes, but rather by a thread of continuity and its identity.
Example: Most airlines distinguish each seat uniquely on every flight. Each seat is an entity in this context. However, Southwest Airlines, EasyJet and Ryanair do not distinguish between every seat; all seats are the same. In this context, a seat is actually a value object.
Value Object
An object that contains attributes but has no conceptual identity. They should be treated as immutable.
Example: When people exchange business cards, they generally do not distinguish between each unique card; they only are concerned about the information printed on the card. In this context, business cards are value objects.
Aggregate
A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
Example: When you drive a car, you do not have to worry about moving the wheels forward, making the engine combust with spark and fuel, etc.; you are simply driving the car. In this context, the car is an aggregate of several other objects and serves as the aggregate root to all of the other systems.
Domain Event
A domain object that defines an event (something that happens). A domain event is an event that domain experts care about.
Service
When an operation does not conceptually belong to any object. Following the natural contours of the problem, you can implement these operations in services. See also Service (systems architecture).
Repository
Methods for retrieving domain objects should delegate to a specialized Repository object such that alternative storage implementations may be easily interchanged.
Factory
Methods for creating domain objects should delegate to a specialized Factory object such that alternative implementations may be easily interchanged.

局限[编辑]

In order to help maintain the model as a pure and helpful language construct, the team must typically implement a great deal of isolation and encapsulation within the domain model. Consequently, a system based on Domain-driven Design can come at a relatively high cost. While Domain-driven Design provides many technical benefits, such as maintainability, Microsoft recommends that it be applied only to complex domains where the model and the linguistic processes provide clear benefits in the communication of complex information, and in the formulation of a common understanding of the domain.[3]

与其它概念的关系[编辑]

Object-oriented analysis and design
Although, in theory, the general idea of DDD need not be restricted to object-oriented approaches, in practice DDD seeks to exploit the powerful advantages that object-oriented techniques make possible. These include entities/aggregate roots as receivers of commands/method invocations and the encapsulation of state within foremost aggregate roots and on a higher architectural level, bounded contexts. The reader should be aware that object orientation is not exclusive to OO-only languages, but can be a part of functional programming, also. Applying commands/method invocations to an entity or aggregate root can be seen as an application of a function to a data structure where the result of the function application is an identical data structure with different data and/or version (especially version if optimistic concurrency is used). In dynamic languages such as Ruby or Smalltalk, object instances can be queried on whether they support a method (by name and/or signature), which is similar to how a statically typed language might choose to use an inversion of control container (or a service bus, or a service locator) to support runtime lookup of the objects – services – that support a given protocol/method/command (see CQRS further down).
Model-driven engineering (MDE)
Model-driven architecture (MDA)
While DDD is compatible with MDA, the intent of the two concepts is somewhat different. MDA is concerned more with the means of translating a model into code for different technology platforms than with the practice of defining better domain models.
POJOs and POCOs
POJOs and POCOs are technical implementation concepts, specific to Java and the .NET framework respectively. However, the emergence of the terms POJO and POCO reflect a growing view that, within the context of either of those technical platforms, domain objects should be defined purely to implement the business behaviour of the corresponding domain concept, rather than be defined by the requirements of a more specific technology framework.
The naked objects pattern
Based on the premise that if you have a good enough domain model, the user interface can simply be a reflection of this domain model; and that if you require the user interface to be a direct reflection of the domain model then this will force the design of a better domain model.[4]
Domain-specific modeling (DSM)
DSM is DDD applied through the use of Domain-specific languages.
Domain-specific language (DSL)
DDD does not specifically require the use of a DSL, though it could be used to help define a DSL and support methods like domain-specific multimodeling.
Aspect-oriented programming (AOP)
AOP makes it easy to factor out technical concerns (such as security, transaction management, logging) from a domain model, and as such makes it easier to design and implement domain models that focus purely on the business logic.
Command Query Responsibility Segregation (CQRS)
CQRS is an architectural pattern for separation of reads from writes, where the former is a Query and the latter is a Command. Commands mutate state and are hence approximately equivalent to method invocation on aggregate roots/entities. Queries query state but do not mutate it. CQRS is a derivative architectural pattern from the design pattern called Command and Query Separation (CQS) which was coined by Meyer. While CQRS does not require DDD, domain-driven design makes the distinction between commands and queries, explicit, around the concept of an aggregate root. The idea is that a given aggregate root has a method that corresponds to a command and a command handler invokes the method on the aggregate root. The aggregate root is responsible for performing the logic of the operation and yielding either a number of events or a failure (exception or execution result enumeration/number) response OR (if Event Sourcing (ES) is not used) just mutating its state for a persister implementation such as an ORM to write to a data store, while the command handler is responsible for pulling in infrastructure concerns related to the saving of the aggregate root's state or events and creating the needed contexts (e.g. transactions).
Event Sourcing (ES)
An architectural pattern which warrants that your entities (as per Eric Evans’ definition) do not track their internal state by means of direct serialization or O/R mapping, but by means of reading and committing events to an event store. Where ES is combined with CQRS and DDD, aggregate roots are responsible for thoroughly validating and applying commands (often by means having their instance methods invoked from a Command Handler), and then publishing a single or a set of events which is also the foundation upon which the aggregate roots base their logic for dealing with method invocations. Hence, the input is a command and the output is one or many events which are transactionally (single commit) saved to an event store, and then often published on a message broker for the benefit of those interested (often the views are interested; they are then queried using Query-messages). When modeling your aggregate roots to output events, you can isolate the internal state event further than would be possible when projecting read-data from your entities, as is done in standard n-tier data-passing architectures. One significant benefit from this is that tooling such as axiomatic theorem provers (e.g. Microsoft Contracts or CHESS) are easier to apply, as the aggregate root comprehensively hides its internal state. Events are often persisted based on the version of the aggregate root instance, which yields a domain model that synchronizes in distributed systems around the concept of optimistic concurrency.

工具[编辑]

采用 DDD 并不依赖于特定的工具。然而,也有许多开源的工具和框架可用,包括:

参见[编辑]

参考文献[编辑]

外部链接[编辑]

[[Category:软件结构]] [[Category:軟體設計]] [[Category:软件开发哲学]]