Introduction to Domain Driven Design

The famous modeling expert Eric Evans published his most influential and famous book in 2004: Domain-Driven Design – Tackling Complexity in the Heart of Software. (Domain Driven Design-The Way to Deal with the Core Complexity of Software)

The way of dealing with complex software can be roughly divided into three methods, abstraction, divide and conquer and knowledge.

  • Abstraction: abstract complex problems into simple ones
  • Divide and conquer: Divide complex issues into multiple small issues and deal with them separately.
  • Knowledge: How to abstract and divide and conquer is more reasonable. DDD

DDD core

  • Unified language: Software developers/users all use the same language, that is, the cognition of a certain concept and noun is unified.
  • Domain-oriented: Think about problems in terms of domains, not modules.
  • In order to achieve these two cores, a key role is needed, a domain expert. He is responsible for the problem domain and the problem-solving domain. He should be familiar with what problems, technical terms, and relationships need to be solved by the product being developed. In general, the closest person to this role is the product manager.

How to implement a unified language

  • common language

A common language is the language that can easily, clearly and accurately describe the meaning and rules of the business that is reached through team communication.

The universal language is the unified language of the team. No matter what role you assume in the team, a unified language is used for communication in the software life cycle of the same field.

Nouns in the common language can name domain objects, such as users/orders. The verb means an action or event, such as user logged in/order paid, etc.

Based on it, more readable code can be developed, and business requirements can be more accurately translated into code design.

  • Bound Context

Used to determine the boundary of the domain where the semantics are located. Communicate in a unified language within a unified domain boundary.

It is used to encapsulate common language and domain objects, provide a context environment, ensure that some terms, business-related objects, etc. (universal language) in the domain have an exact meaning, and prevent puns.

The theoretical upper bound context is the boundary of microservices. Bounded context is the main basis for microservice design and splitting.

The realm can be divided into multiple sub-areas. A domain is equivalent to a problem domain, and the process of dividing the domain into subdomains is the process of dividing big problems into small problems.

  • The universal language defines the meaning of the context, and the bounded context defines the domain boundary
  • Implementation process: event storm> domain (user) story analysis> extraction of domain objects> domain objects and code model mapping> code realization

What is the field of noodles

Programming ideas

  1. Process-oriented POP: Consider the steps to solve the problem, and realize the steps to solve the problem. Deal with problems top-down.
  2. Object-oriented OOP: The problematic transaction is broken down into multiple objects, and the objects handle their own affairs. Domain-oriented-consider internally, discover commonalities, define aggregate root objects, and provide services externally. Deal with the problem abstractly.
  3. Service-oriented SOA: Starting from the user's business, business functions are regarded as loosely coupled services. Microservices are a service-oriented extension
  4. Aspect-oriented AOP: From the perspective of classes, abstract common functions.
  5. Component-oriented COP: EJB components

benefit

  1. Because everyone uses a unified set of common language, the communication cost will be greatly reduced, and will not be considered as B when discussing A.
  2. It is good for the user who uses the product. He can have a unified and smooth experience during the continuous update of the product. Users do not have to complain about why the previous data is not used after saving every time the software is updated.
  3. Each team can more clearly define the concepts in its own domain in its context, because the context is the solution system of the domain;
  4. When there is an interaction between bounded contexts, the consistency of the team and the context can ensure that we have a clear docking team and dependent upstream and downstream.
  5. Domain-oriented product development helps us deeply analyze the internal logic of the product, focus on solving the core problems of the current product, instead of redundantly making many functional modules, (avoid changing the product logic based on user/operation feedback, After going online, users don’t use it, and users complain about their needs.)

Difficulty

  1. Too few landing practices and too few best practices mean that we can refer to fewer materials and take a greater risk of project failure.
  2. A lot of new concepts and terms have emerged, such as aggregate roots, value objects, hexagonal architecture, CQRS (separation of responsibilities for commands and queries), event-driven concepts, etc.
  3. It requires us to spend a lot of time and energy in domain modeling, and it may also lead to a situation where the effort is not proportional to the benefit. Because the division of the boundary context is a test of the architect's business level. If the business model is not well identified, then the model will be corrupted in the iterative process.
  4. DDD is a set of ideas, a set of domain modeling design, and a set of use in a specific context. All different plans need to be designed in different teams, and he needs to implement them in accordance with the actual situation of the team in order to achieve the effect.

The composition of modern Internet production and research teams is generally marketing/operations, products, UI interaction, front-end, back-end, and testing. The division of labor of these roles is to separate the various processes of a product development and launch, and then each process has a dedicated person responsible, which can effectively improve production efficiency. This set of processes is a standard assembly line operation.

The advantages of this are undoubted, and the disadvantages are also obvious. Each person only focuses on his own piece and ignores the whole.

Common tools

  1. flow chart
  2. Timing diagram
  3. Entity relationship diagram (ER model)
  4. Use case diagram
  5. UML diagram (domain modeling)

Domain model

Software development is generally divided into waterfall type and agile type.

  • Waterfall: The project manager analyzes the overall production requirements, and the developers carry out development.
  • Agile: It also requires a lot of analysis, fine business modules, iterates in small steps, and is delivered periodically. Agile is to embrace change, which may generate a large number of requirements or business model changes, which will bring considerable maintenance costs.
  • DDD: Iterative design with smaller granularity. The domain model is a carrier that can accurately reflect a certain knowledge element in the domain, transforming professional knowledge into a domain model, and designing code on top of it.

Blood loss model

class User{

String id;

String name;

Integer age;

Getter/Setter..

}

There is only one domain object, and Service is responsible for all operations, including storage.

Service>Domain entity

Anemia model

class UserDao {

    @Autowired

    JdbcTemplate jdbcTemplate;

    public void updateName(String name,String id){

        jdbcTemplate.excute("update user u set u.name = ? where id=?",name,id);

    }

}

class UserService{

    @Autowired

    UserDao userDao;

    void updateName(String name,String id){

        userDao.updateName(name,id);

    }

}

The persistence logic is implemented in Dao, and the Service is responsible for the business.

Service>DAO>Domain entity

Hyperemia model

interface UserRepository extends JpaRepository<User,String>{

    //springdata-jpa automatically extends the save findOne findAll method

}

class UserService{

    @Autowoird

    UserRepository userRepository;

    void updateName(String name,String id){

        User user = userRepository.findOne(id);

        user.setName(name);

        userRepository.save(user);

    }

}

On the basis of the anemia model, an additional Domain layer is added and Dao is put into the Domain. Service does not need to care about database operations, only the domain object itself. Repository mode is here, shielding the realization of the database.

Service> Domain > DAO

Bloating model

void updateName(String name,String id){

    User user = new User(id);

    user.setName(name);

    user.save();

}

Based on the congestion model, Service and Domain are merged closely.

Domain > Dao

Design Patterns

Traditional model

  • MVC 

User interface>service>dao>model

Data-driven development of ER diagrams, data-oriented programming, when service business increases, dao loses its clear meaning, which is called amnesia caused by anemia

  • DDD model

User interface>application>domain>infrastucture

User interface: user display and user instructions

应用层:协调应用活动,不包含业务逻辑,不保留业务对象,只保存任务进度。

领域层:领域信息/业务对象状态,将业务状态和信息委托给基础层

基础层:支撑库,对业务数据持久化,和用户展示库等。

 

概念定义

  • 领域:包括问题域和解系统,限界上下文
  • 实体:当一个对象由其标识(而不是属性)区分时,这种对象称为实体(Entity)。
  • 值对象:当一个对象用于对事务进行描述而没有唯一标识时,它被称作值对象(Value Object)。
  • 聚合根:Aggregate(聚合)是一组相关对象的集合,作为一个整体被外界访问,聚合根(Aggregate Root)是这个聚合的根节点。
  • 领域服务Services:一些重要的领域行为或操作,可以归类为领域服务。
  • 领域事件DE:领域事件是对领域内发生的活动进行的建模。
  • 资源库(Repositories):springdata中的xxxRepository就是基于ddd的充血模型
  • 模块(Moudles):一种控制限界上下文的手段,一般尽用一个模块来表示一个领域量的限界上下文。在工程中开源用包的方式,如com.公司名.组织架构.业务.上下文.*

设计领域模型的一般步骤如下:

  1. 根据需求划分出初步的领域和限界上下文,以及上下文之间的关系;
  2. 进一步分析每个上下文内部,识别出哪些是实体,哪些是值对象;
  3. 对实体、值对象进行关联和聚合,划分出聚合的范畴和聚合根;
  4. 为聚合根设计仓储,并思考实体或值对象的创建方式;
  5. 在工程中实践领域模型,并在实践中检验模型的合理性,倒推模型中不足的地方并重构。

扩展

CQRS模式

CQRS — Command Query Responsibility Segregation,命令查询的责任分离模式,将系统中的操作分为两类,即「命令」(Command) 与「查询」(Query)。

  • 命令:是对会引起数据发生变化操作的总称,即我们常说的新增,更新,删除这些操作,都是命令。
  • 查询:即不会对数据产生变化的操作,只是按照某些条件查找数据。

核心思想

是将这两类不同的操作进行分离,然后在两个独立的「服务」中实现。这里的「服务」一般是指两个独立部署的应用。在某些特殊情况下,也可以部署在同一个应用内的不同接口上。

Command 与 Query 对应的数据源也应该是互相独立的,即更新操作在一个数据源,而查询操作在另一个数据源上。看到这里,你可能想到一个问题,既然数据源进行了分离,如何做到数据之间的同步呢?让我们接着往下看。

CQRS 的架构图

 

有点类似「读写分离」

六边形架构

传统MVC架构分为表现层、业务逻辑层、数据访问层,各层相互依赖,无法单独调整某一层。

六边形架构又称为端口-适配器。六边形架构将系统分为内部(内部六边形)和外部,内部代表了应用的业务逻辑,外部代表应用的驱动逻辑、基础设施或其他应用。内部通过端口和外部系统通信,端口代表了一定协议,以API呈现。一个端口可能对应多个外部系统,不同的外部系统需要使用不同的适配器,适配器负责对协议进行转换。这样就使得应用程序能够以一致的方式被用户、程序、自动化测试、批处理脚本所驱动,并且,可以在与实际运行的设备和数据库相隔离的情况下开发和测试。

 

六边形体系结构基于三个原则和技术:

  1. 明确区分应用程序,域和基础设施。
  • 应用程序:与外部交互,路由、api、序列化等。
  • 域:纯粹的业务逻辑代码。
  • 基础设施:需要实现业务逻辑的支持环节,比如数据入库、第三方功能等。
  1. 依赖关系从应用程序和基础结构到域:域不依赖外部。
  2. 使用端口和适配器隔离边界,
  • 端口:域定义端口
  • 适配器:链接域的端口与外部交互适配处理。

总结

框架易学,思想难学

如果单从研发角度考虑DDD,开发进行领域建模,然后遵从康威定律,将软件架构设计映射到业务模型中。

康威定律:任何组织在设计一套系统(广义概念上的系统)时,所交付的设计方案在结构上都与该组织的沟通结构保持一致。

参考:

  1. 领域驱动设计:软件核心复杂性应对之道,Eric Evans
  2. 浅析DDD(领域驱动设计),https://www.jianshu.com/p/b6ec06d6b594
  3. 领域驱动设计在互联网业务开发中的实践,https://tech.meituan.com/2017/12/22/ddd-in-practice.html
  4. DDD 中的那些模式 — CQRS,https://zhuanlan.zhihu.com/p/115685384
  5. DDD术语-通用语言、限界上下文,https://www.cnblogs.com/junzi2099/p/13682028.html
  6. 领域驱动模型(DDD)在美团外卖活动管理业务的应用,https://www.jianshu.com/p/fb319d7674ff
  7. 「首席架构师看应用架构」六边形架构:三个原则和一个实现示例,https://baijiahao.baidu.com/s?id=1662240769613294810&wfr=spider&for=pc

 

 

Guess you like

Origin blog.csdn.net/lizz861109/article/details/112952918