ドメインのマイクロサービスアーキテクチャ設計の基礎は、駆動設計(転載)

DDDは、以前のマイクロ・サービスよりも10年の「デビュー」、ソフトウェアの設計思想のこれら二つの「親しい友人」は殺すと恋にどのように?

背景

マイクロサービスは現在、サービス指向(トピックを言及していないが、業界で最も人気のある比較がモノリシック(シングルユース)は、いわゆるされており、より多くの10年前よりも内のシステムの数が多い、SOAに基づいている誰もが、ソフトウェアのR&Dではないと言うことができますアーキテクチャ)、新しいマイクロアーキテクチャの標準規格として、分散システムをベースとし、SOAは何が違いのポイントとは?その設計方針の本質的な違いの嘘は、マイクロサービスは、デザインを分散化され、SOAは設計の中心を形成する「統合」されます。

 

 

また、私は以下の違いのマイクロサービスとSOAのポイントではないと信じています:

CI / CD:継続的インテグレーション、連続展開自体と俊敏性、DevOpsチームが絡み合っている、CI \ CDソフトウェア工学の分野を好む、サービスを行うためのマイクロは何も;
コンテナベースまたは仮想マシン:ドッカー、仮想マシン、物理マシンそれは関係なく、マイクロサービスの、物理的なメディアの実装です。
マイクロ周囲の生態系サービス:などのロギングプラットフォーム、コールチェーンシステムとして?より多くの研究開発が効率化のために、自己駆動力、アーキテクチャに関係なく、どの方法を使用すること自体は、
通信プロトコル:推奨マイクロプロトコル・サービスは、RESTfulな場合、従来のSOAはSOAPです。しかし、また、たくさんあるマイクロサービスを実装するための軽量RPCフレームワークダボ、スリフト、gRPCに基づいて、春のクラウドフレームワークの中でも、RPCコードの行動の模倣に装う標準のRESTfulなAPIを持っていますが、これらのプロトコルはマイクロサービスアーキテクチャを区別していませんそして、SOAのアーキテクチャ間のコア差は、
当然のことながら、ソフトウェア工学(DevOpsチーム)、インフラ(コンテナ化)、ソフトウェア開発モデル(アジャイル開発)はマイクロサービスアーキテクチャの普及を促進するために好ましい変化します。マイクロサービスアーキテクチャはまた、セグメンテーションの本質を反映している「マイクロ」である建築様式、建築のコンセプトです。マイクロサービスが証明した実際の着陸の過程で、セグメンテーションが間違っている場合は、あなたのようなマイクロとの利点の「低カップリング、自律性、メンテナンスの容易さ」サービスのコミットメントを取得し、また、より多くの単一のアーキテクチャ以上を持つことができませんトラブル。それでは、どのようセグメンテーションを行いますか?ドメイン駆動設計・キューブ・モデル:実際には、ない新しい方法論が、多くの年で設計方法を調達しているが、それらはまた、マイクロサービスアーキテクチャモデルや設計基準として呼ばれています。

ドメイン駆動設計

2004年に、エリック・エヴァンスは、ドメイン駆動設計(ドメイン駆動設計、DDD)を納入しました。ドメインは、ソフトウェア設計の分野では、理論的な説明を先駆的に行わドリブンドメインに」デザインはエリック・エヴァンスのドメイン駆動設計の公表の著作から、10年以上にわたり周りされている本を主導、DDDは夕暮れ期間に呼び出すことができますA。残念ながら、海外のソフトウェア有名と実績のある設計手法のサークル、国内の技術スタッフのほとんどが、プロジェクトの実践に適用されることがありません、知りません。熱風マイクロサービス業界を吹くまでは、ドメイン駆動設計は粘り強い成長、そのデザインとオープン設計手法となっているので、ドメイン駆動設計にドメイン駆動設計ではなく、マイクロ省サービスの価値を再発見しているようです国内での人気は決してが、しかし、彼らは偉大な価値を果たしています。マイクロサービスは、ドメイン駆動設計のみビジョンの公共分野に表示されるようになったので、表面には、本当にそれがあります。

ドメイン駆動設計を意味

もちろん、ドメイン駆動設計は「特効薬」ではない、その意味を学び、適用する「万能薬」のすべての難病を解決することはできませんです。

ソフトウェア設計モデル駆動型アプローチの完全なセットは、あなたのデザインのアイデアをより明確に、より多くの標準化設計プロセスにすることができ、それは戦術的なデザインへの戦略的からあなたの設計仕様のプロセスを与えることができ、ソフトウェアプロジェクトの複雑さを簡素化するために、
A ;種類思考や概念の道の複雑な操作を扱うソフトウェアプロジェクト、配信アイテムの速度に適用することができ
アーキテクチャとモデルの開発を促進するために、缶のヘルプ開発者がエレガントなソフトウェアシステムを作成することを原則とパターンからのグループ派生慎重にシステムアーキテクチャ設計、オブジェクト指向設計とチームメンバーの建築設計能力の能力を改善するのに役立つの進化を扱う時に特に優れ、研磨、
ドメイン駆動設計とマイクロサービスアーキテクチャ自然試合、両方の新しいプロジェクトにおけるマイクロサービスアーキテクチャの設計、またはマイクロサービスの設計に単一のアーキテクチャから進化システムは、ドメイン駆動設計の建築の原則に従うことができます。
もちろん、フィールドドライブは、私たちに収穫の多くをもたらすことができますが、あなたはいくつかの種類の次のような状況に属している場合は、ドメイン駆動設計を学習する必要はありません。

あなたは努力の建築家であり、優雅なソフトウェアアーキテクチャを設計することができるならば
、あなたが効率的なコーディングのプログラマーであり、単にコードを書くために下に取得したい場合は
「あなたはフロントエンドの設計者であれば、そして最初の「ユーザーエクスペリエンスを追求しますアイデアは、
あなたがソフトウェアシステムを担当している場合には複雑ではありません、そして第二に、あなたは簡単に3を維持することができます

DDDの重要な概念

ソフトウェアシステムの誕生は、それは我々が直面する問題を解決するためにでなければなりません。例えば、同社は、製品のオンライン販売、電気の供給システムの誕生を販売する目的のために、オンラインで製品を販売することを望んで、財政的・物的資源の多くを費やす、ラインを使用して製品を販売しています。ソフトウェアプロジェクトの開始点は、ある目的は、通常は設定されているか、最初の問題は解決することが明らかに我々は何をする必要がありますか。例えば、電力供給、フォーラム、決済プラットフォーム。

以下の分野からは、問題のドメイン、これらの単語のドメインモデル、デザイン、ドライブとの接触角の意味は、DDDは、ソフトウェア開発に統合する方法を説明します。ドメイン駆動設計が何であるかを理解するために、我々は最初のフィールドが何であるかを理解する必要があり、どのようなデザインで、運転しているものを、どのようなドライブ何を。

エリア/サブエリア(ドメイン/サブドメイン)は何ですか

特定の問題に関連した知識と行動のエリア。このエリアはアカウントを持っています限り、コレクション、支払い、リスクコントロールと他のコアセクターを覚えているでしょうとして例えば、決済プラットフォームは、特定の領域に属しています。フィールドシステムと同じコアビジネスを持っているので、解決すべき彼らの問題の本質は同じです。基本的には問題領域として理解することができるフィールド限り、同じフィールド、同じドメイン上の問題。だから、限り、我々はそれが属するシステムの分野を特定してきたように、システムのコアビジネスは、すなわち、重要な問題を解決すること、国境問題の範囲は、基本的に決めます。

日々の開発では、我々は通常、大規模なソフトウェアシステムは、いくつかのサブシステムに分割されます。この分割は、アーキテクチャの考慮に基づいてされる可能性があるだけでなく、インフラストラクチャをベースとすることができます。DDDでは、我々は(業務上の)システムがフィールドに基づいてされる分割します。例えば、上記の支払いプラットフォームはフィールドであり、アカウントはサブフィールドと比較して、などのコレクション、支払いを、入金されます。フィールドは、多くのサブフィールドの集まりによって形成されています。

もちろん、問題が巻き起こっています:

どのような概念は、内部のサブシステムでモデル化すべきか?
時々概念モデリングは、システムBでモデル化、Aが可能であるサブフィールドに見出すことができる合理的です。
どのようにする必要があり、様々なサブシステム間の統合?
クライアントは、単純なように、サーバーを呼び出すように一つは、これは単純ではないことを言うかもしれませんか?問題は、2つのシステム、ほとんど注目の間に2つのシステム間の変換のさまざまな分野に関連する統合インフラストラクチャの概念とは、これらの概念は慎重に良いドメインモデルを作成し、当社の汚染ということです。
DDD、上記課題を解決するための標準的な方法は、制限されたコンテキスト(有界コンテキスト)とコンテキスト・マップです。フィールド/サブドメインでは、我々はこの境界では、概念上のフィールド境界を作成し、任意のドメインにのみ正確な意味の内側の境界線に特定を表すオブジェクト。この境界は、有界コンテキストと呼ばれます。コンテキストとゲージのフィールドは、1対1の関係を持っています。物理的なレベルから、それは究極のゲージのコンテキストはJAR / WARファイル、あるいはすべてのパッケージ内のオブジェクトの可能です。しかし、技術自体は、コンテキストを有界境界点に使用されていません。

 

 

図は、「駆動設計を達成するためのフィールド。」より引用します 一般的に、フィールドと一つだけ問題の核心は、我々はこのエリアコール「コアドメイン。」コアドメイン、サブドメイン共通では、支持サブドメインをカーディングしながら、サブドメインの間の関係を説明するためにそれを使用し、「有界コンテキスト」との関係サブドメインを規定します。コンテキスト境界は単にサブアセンブリまたはモジュールとして理解することができます。

(デザイン)デザインとは何ですか

DDDは、メインの設計モデルのデザインを指します。DDDはモデルの領域を強調し、ソフトウェアベースのモデル駆動型開発の開発のアイデアであるシステムの中核である、ドメインモデルは、プラットフォーム全体のコアバリューです。各フィールドは、対応するドメインモデルを持っている、ドメインモデルは、責任あるビジネス上の問題を解決することができます。だから、ドメインモデルのデザインと建築デザインは等しく重要です。

運転は何である(駆動)

国境地域でのDDDは常に問題の核心(コア懸念)フィールドを解析します。そして、対応するフィールドモデルの設計、実装コードのフィールドは、モデルによって駆動します。周辺部に属しているものをデータベース設計、永続化技術これらはDDDのコアではありません。データベース駆動型開発の考え方とは対照的に、2つの原則を覚えておく必要性を駆動:

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

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万+

おすすめ

転載: blog.csdn.net/sunct/article/details/90208337