Micro Services Architecture Design Basics of Domain Driven Design (reprint)

DDD earlier than micro-services "debut" ten years, how these two "close friends" of software design philosophy is in love with killing?

background

Micro service can now say that no one is software R & D does not mention the topic, but the industry's most popular comparison are so-called Monolithic (single use), and a large number of systems in more than ten years ago, have been based on SOA (service-oriented architecture) based distributed systems, then serving as the new micro-architecture standards and SOA What is the difference point? The essential difference lies in its design principles, micro service is decentralized design, SOA is "integrated" form the center of the design;

 

 

In addition, I believe that the following is not a micro-services and SOA point of difference:

CI / CD: continuous integration, continuous deployment itself and agility, DevOps are intertwined, CI \ CD prefer areas of software engineering, micro nothing to do with the service;
container-based or virtual machine: Docker, virtual machines, physical machines It is an implementation of the physical media, regardless of the micro-services;
micro surrounding ecosystem services: such as logging platform, call chain system? More research and development is itself self-driving force for efficiency, regardless of which way the use of architecture;
communication protocols: Recommended micro protocol service is RESTful, traditional SOA is SOAP. However, based on lightweight RPC framework Dubbo, Thrift, gRPC to implement micro services are also a lot; in Spring Cloud framework will also have Feign standard RESTful API into an imitation of the behavior of RPC code, these protocols are not distinguish micro Services Architecture and core difference between SOA architecture;
of course, software engineering (DevOps), infrastructure (containerized), software development model (agile development) changes favorable to promote the popularity of micro-services architecture. The micro-service architecture is an architectural style, architecture concept, which is "micro" It also reflects the essence of the segmentation. In the course of the actual landing micro services proved, if segmentation is wrong, you can not get "low coupling, autonomy, ease of maintenance" service commitment of the advantages of micro and the like, and also have more than a single architecture trouble. So how do segmentation? In fact, not a new methodology, but have raised design method in many years, they are also called as micro-services architecture model or design basis: Domain-Driven Design and cube model.

Domain-Driven Design

In 2004, Eric Evans delivered a Domain Driven Design (Domain Driven Design, DDD). Domain Driven Design has been around for more than a decade, from the published writings of Eric Evans' Domain Driven Design, "a book on Domain Driven done pioneering theoretical explanations, in the field of software design, DDD can be called into the twilight period a. Unfortunately, the circle of foreign software renowned and proven design methodologies, most of the domestic technical staff but do not know, have never applied to the project practice. Until blowing hot air micro-services industry, it seems to have rediscovered the value of domain-driven design, not micro-saving services to the domain-driven design, because the domain-driven design has been tenacious growth, its design and open design methodology Although never popular in the country, but they play a great value. On the surface really it is because micro-services, domain-driven design only began to appear in the public field of vision.

Meaning domain driven design

Of course, domain-driven design is not a "silver bullet", can not solve all the incurable diseases of "panacea" to learn and apply its meaning is:

A complete set of software design model-driven approach, to simplify the complexity of software projects, it can give you the design specification process from strategic to tactical design, can make your design ideas more clearly, more standardized design process;
a kind of way of thinking and concepts can be applied to software projects dealing with complex operations, the speed of delivery items;
a group derives from the principles and patterns that can help developers create elegant software system, to promote the developer of architecture and models carefully polished, especially good at dealing with the evolution of the system architecture design, help to improve the ability of object-oriented design and architectural design capabilities of team members;
domain-driven design and micro-services architecture natural match, both the design of micro-services architecture in a new project, or the system evolved from a single architecture to the micro-service design, you can follow the architectural principles of domain-driven design.
Of course, the field drive can bring us a lot of harvest, but if you belong to the following situations of some kind, then you do not need to learn a domain-driven design:

If you are the architect of endeavor, and be able to design elegant software architecture
if you are efficient coding programmers, and just want to get down to write the code
if you are a front-end designers, and pursuing "user experience first ' idea
if you are responsible for the software system is not complicated, and second, you can easily maintain three

The key concept of DDD

The birth of a software system, it must be in order to solve a problem we encountered. For example, a company has been selling products using the line, spend a lot of financial and material resources, hoping to sell their products online, for the purposes of selling products online sales, then the birth of a electricity supplier system. Objectives are usually set up or initial problem to be solved is the starting point of a software project, clearly what we need to do. For example, a power supplier, a forum, a payment platform.

From the field below, the problem domain, the domain model, design, drive and contact angle meaning of these words to describe how DDD is integrated into the software development. To understand what is domain-driven design, we must first understand what the field is, what is design and what is driving, what drives what.

What are the areas / sub-areas (Domain / Subdomain)

Areas of knowledge and behavior related to a specific problem. For example, payment platform belongs to specific areas, as long as this area will have an account, will remember, collection, payment, risk control and other core sectors. So, with a field system have the same core business, the nature of their problem to be solved is the same. Essentially a field that can be understood as a problem domain, as long as the same field, the problem on the same domain. So, as long as we have identified areas of the system it belongs, and that the system's core business, namely to resolve key issues, the scope of the border issue would basically decided.

In the daily development, we usually use a large software system is split into several sub-systems. This division is likely to be based on consideration of architecture, but also may be based infrastructure. In DDD, we divide the system is based on the field (on business) is. For example, the above mentioned payment platform is a field, and the account will be credited, collection, payment, etc., compared with sub-fields. Field is formed by a gathering of many sub-field.

Of course, the problem has cropped up:

What concepts should be modeled in which subsystems inside?
Sometimes a conceptual modeling may be found in the sub-field A is possible, also modeled in the system B are reasonable.
How should the integration between the various subsystems?
One might say that this is not simple, like the client calls the server so simple? The problem is that the concept of integrated infrastructure and related to different areas of translation between the two systems between the two systems, a little attention, these concepts will pollute our carefully create good domain model.
DDD, the standard method for solving the above problems, is bounded context (Bounded Context) and a context map. In a field / sub-domain, we will create a field boundary on a concept, in this boundary, any domain objects only represent specific to the inner border of the exact meaning. This boundary will be called bounded context. Context and gauge fields have a one to one relationship. From the physical level, it is an ultimate gauge context can be a Jar / War files, or even all of the objects in a Package. However, the technology itself is not used to border points bounded context.

 

 

The figure quoted from "field to achieve driven design." Typically, a field and only one core issue, we call this area "the core domain." In the core domain, subdomain common, while carding support subdomains, defines a "bounded context" and its relationship subdomain, use it to illustrate the relationship between sub-domains. Context boundaries can be simply understood as a sub-assembly or module.

What is the design (Design)

DDD refers to the design of the main design model. DDD is a software-based model-driven development development ideas, highlighting areas of the model is the core of the system, the domain model is the core value of the entire platform. Each field has a corresponding domain model, domain model can solve business problems responsible. So domain model design and architectural design are equally important.

What is driving (Driven)

DDD in border areas always analyze the core issue (core concern) field. Then the corresponding field model design, implementation code field driven by the model. The database design, persistence technology these are not the core of DDD, what belongs to the periphery. In contrast to the idea of ​​a database-driven development, driving need to remember two principles:

领域驱动领域模型设计
领域模型驱动代码实现
领域驱动设计的最大价值是让我们告别从面向过程式的思想(天马星空,想到哪写到哪)转化为基于系统化的模型驱动思维。我们脑补一下软件开发中的常规心路历程:

1、设计表结构
2、写代码(代码写的很冗余,不够抽象)
3、维护代码(适应业务变化)
4、遇到困难(数据结构设计不合理、代码到处冗余、改BUG引入新BUG、新人看代码和无字天书一般)
5、愈发难以维护,开始重构(理论上在老基础上改的技术债务堪比重新开发)
6、重构完成,新系统上线(兼容历史数据、数据迁移、新老系统并行,等等出发点考虑,其实本质上只是做了代码重构)
7、重复执行3-6步......

DDD的分层架构

四层架构

Eric Evans在《领域驱动设计-软件核心复杂性应对之道》这本书中提出了传统的四层架构模式,在后来演进过程中出现了五层架构和六层架构,,如下图所示:

 

 

User Interface:用户界面层/展示层,负责与用户交互。包含显示信息、解释用户命令等;
Application:应用层,用来协调用户与各应用以及各应用之间的交互。不包含业务逻辑、不保存业务对象的状态;
Domain:领域层/模型层,负责表达业务概念,业务状态信息以及业务规则。包含领域模型、领域信息、业务对象的状态。领域层是业务软件的核心;
Infrastructure:基础设施层,为其他各层提供技术能力。包括为应用层传递消息、为领域层提供持久化机制、为用户界面层绘制屏幕组件等等。基础设施层还能够通过架构框架来支持四个层次间的交互模式。

六边形架构

随着后续的演进,出现了一种改进分层架构的方法,即Robert C. Martin提出的依赖倒置原则(Dependency Inversion Principle,DIP)。它通过改变不同层之间的依赖关系达到改进目的。

高层模块不应该依赖于底层模块,两者都应该依赖于抽象
抽象不应该依赖于细节,细节应该依赖于抽象
根据该原则的定义,DDD分层架构中的低层组件应该依赖于高层组件提供的接口,即无论高层还是低层都依赖于抽象,整个分层架构好像被推平了,再向其中加入了一些对称性,就出现了一种具有对称性特征的六边形架构风格。六边形架构是Alistair Cockburn在2005年提出的,其本质是倡导不同的客户通过「平等」的方式与系统交互,通过不断的扩展适配器转化成系统API所理解的参数来达到每种特定的输出,而每种特定的输出都有适配器完成相应的转化功能。

 

 

聚合:
一组具有内聚关系的相关对象的集合;
– 是一个修改数据的最小原子单元;
– 聚合通常使用id访问;
实体(Entity):表示具有生命周期并且会在其生命周期中发生改变的东西。含有VO、具有identity的特性,通常具有生命周期的概念 JPA tag @Entity;
值对象(Value Object):表示起描述性作用的并且可以相互替换的概念。类似于pojo,不可变immutable,可在不同模型中传递,Spring tag @value;
领域事件(Domain Event):所有的领域对象的跨聚合变更需要以事件方式进行通知和记录,聚合内的酌情考虑;
工厂(Factory):负责所有对象的生成和组装;
领域服务(Domain Service):纯技术层面的服务,例如日志,或者是跨聚合的编排服务,通常是Spring Component;
资源层(Repository):类似于DAO层,Spring JPA, Hibernate之类 @CRUDRepository;
防腐层:并非是系统间的消息传递机制,它的职责更具体的是指将某个模型或者契约中的概念对象及其行为转换到另一个模型或者契约中;

贫血模型VS充血模型

读完上面的两种分层架构方式,可能很多人会有疑问,这些是什么?为什么我之前一直都没听到过这种分法?确实是这样,DDD和面向对象、设计模式等等理论有千丝万缕的联系,如果不熟悉OOA、OOD,那么DDD可能也会理解不了。因为我们大部分从开发生涯开始之初接触的都是「Action层、Service层、Dao层、DB层」这样的MVC分层理论。并且在21中设计模式中,「行为型」的设计模式,我们几乎没有什么机会使用,导致这些问题的原因是J2EE经典分层的开发方式是「贫血模型」。

Martin Fowler(对,就是提出微服务的那位大牛)曾经提出了两种开发方式,即:

以「贫血模型」为基础的「事务脚本」的开发方式
以「充血模型」为基础的「领域驱动」的开发方式

贫血模型

贫血模型是指对象只用于在各层之间传输数据使用,只有数据字段和Get/Set方法,没有逻辑在对象中。而「事务脚本」可以理解为业务是由一条条增删改查的SQL组织而成,是面向过程的编程。

充血模型是面向对象设计的本质,一个对象是拥有状态和行为的。将大多数业务逻辑和持久化放在领域对象中,业务逻辑只是完成对业务逻辑的封装、事务、权限、校验等的处理。

举例,用户管理模块大概是这样的两种实现:

// 贫血模型下的实现
public class User{
private Integer id;
private String name;
...
// 省略get/set方法

}

public class UserManager{
public void save(User user){

    // 持久化操作....

}

}

// 保存用户的操作可能是这样
userManager.save(user);
// 充血模型下的实现
public class User{
private Integer id;
private String name;
...
// 省略get/set方法

public void save(){

    // 持久化操作....

}

}

// 保存用户的操作可能是这样
user.save();
Martin Fowler定义的「贫血模型」是反模式,面对简单的小系统用事务脚本方式开发没问题;稍微大一些的系统使用事务脚本方式会扩大维护成本,业务逻辑、各种状态散布在大量的函数中,哪怕就是要用户对象中增加一个字段,可能都会涉及到几个类的调整......

希望领域对象能够准确地表达出业务意图,但是多数时候,我们所看到的却是充满getter和setter的领域对象,此时的领域对象已经不是领域对象了,反模式的贫血对象了。其实在贫血模型和充血模型模型之外,还有失血模型和胀血模型,但后者两个基本是实际开发中不会去使用,因为走的是两个极端。

总结

本文宏观角度介绍了领域驱动设计,那么微服务和DDD是什么关系呢?其实在2015年的一次演讲中,DDD的提出者Eric Evans表达了对微服务技术的热爱与支持,认为微服务是让DDD落地的好工具。因为DDD和微服务其本质是降低软件项目的复杂性,而DDD是一种设计理念/设计方法,DDD需要有强制性的原则做保障,否则不同的领域对象终究会混在一起。而微服务本身的一些限制,以及大家都能理解微服务的实施前提和首要条件,会在实现上给DDD增加了一些原则限制。DDD和微服务的不一定要同时使用落地,但是如果将DDD和微服务(两个相差十岁的软件设计方法)结合一起,那么Martin Fowler和Eric Evans两位布道师是会很赞同的。



作者:heishaovvv
链接:https://www.jianshu.com/p/18e6640ef204
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

发布了178 篇原创文章 · 获赞 28 · 访问量 8万+

Guess you like

Origin blog.csdn.net/sunct/article/details/90208337