NLayerAppV3--DDD之领域层
回顾:NLayerAppV3是一个使用.net 2.1实现的经典DDD的分层架构的项目。
NLayerAppV3是在NLayerAppV2的基础上,使用.net core2.1进行重新构建的;它包含了开发人员和架构师都可以重用的DDD层。
Github地址:https://github.com/cesarcastrocuba/nlayerappv3
上一篇,介绍了NLayerAppV3项目Infrastructure(基础设施层)的Cross-Cutting部分,文章地址:https://www.cnblogs.com/net-yuan/p/NLayerAppV3-Infrastructure_CrossCutting.html
NLayerAppV3的基础结构层一共分为两个部分。处理数据相关的基础组件Data和Cross-Cutting的基础组件。
处理数据相关的基础组件Data主要包含UOW和仓储的实现;
Cross-Cutting的基础组件目前主要包含数据适配器、国际化、验证;
这篇本来应该介绍Infrastructure(基础设施层)的Data部分。
可是仓储的具体实现是放在基础结构层的,而仓储的接口则是放在领域模型层的。
所以,我们就先介绍领域层Domain。
NLayerAppV3项目的Domain(领域层)分为两个部分:Seedwork和BoundedContext
Seedwork部分定义了实体的契约、实体的基类、值对象的基类、仓储的契约、UOW的契约、规约等。
BoundedContext部分定义了聚合相关,聚合、值对象、规约的具体实现、仓储的契约、领域服务等。
以下描述引用自何老大的博文:
聚合包装一组高度相关的对象,作为一个数据修改的单元。
聚合最外层的对象称为聚合根,它是一个实体。聚合根划分出一个清晰的边界,聚合根外部的对象,不能直接访问聚合根内部对象,如果需要访问内部对象,必须首先访问聚合根,再导航到聚合的内部对象。
聚合代表很强的包含关系,聚合内部的对象脱离了聚合,应该是毫无意义的,或不是你真正关注的,它是聚合的一个组成部分,这与UML中的组成聚合概念相近。
有关聚合的相关知识可以查看何老大的博文 https://www.cnblogs.com/xiadao521/p/4141904.html
以BankAccount聚合来看,BankAccount是聚合根,包含卡号BankAccountNumber这样的值对象,BankAccountNumber由国家或者地区银行编号、检查位等构成;Balance金额、Locked是否锁定、Customer用户实体、BankAccountActivity账户活动的集合等等、还包含锁定、解锁、存款等行为。这是一个充血的模型。
BankAccountFactory是创建聚合BankAccount的工厂,它负责创建BankAccount。
BankAccountSpecifications封装了BankAccount的查询规约
public static class BankAccountSpecifications
{
/// <summary>
/// Specification for bank accounts with number like to <paramref name="ibanNumber"/>
/// </summary>
/// <param name="ibanNumber">The bank account number</param>
/// <returns>Associated specification</returns>
public static ISpecification<BankAccount> BankAccountIbanNumber(string ibanNumber)
{
Specification<BankAccount> specification = new TrueSpecification<BankAccount>(); if (!String.IsNullOrWhiteSpace(ibanNumber))
{
specification &= new DirectSpecification<BankAccount>((b) => b.Iban
.ToLower()
.Contains(ibanNumber.ToLower()));
} return specification;
}
}
IBankAccountRepository提供了BankAccount的仓储契约
IBankTransferService提供了转账的领域服务契约,有一个转账方法
void PerformTransfer(decimal amount, BankAccount originAccount, BankAccount destinationAccount);
BankTransferService实现了IBankTransferService
实现了转账领域服务的逻辑。
public void PerformTransfer(decimal amount, BankAccount originAccount, BankAccount destinationAccount)
{
if (originAccount != null && destinationAccount != null)
{
var messages = LocalizationFactory.CreateLocalResources(); if (originAccount.BankAccountNumber == destinationAccount.BankAccountNumber) // if transfer in same bank account
throw new InvalidOperationException(messages.GetStringResource(LocalizationKeys.Domain.exception_CannotTransferMoneyWhenFromIsTheSameAsTo)); // Check if customer has required credit and if the BankAccount is not locked
if (originAccount.CanBeWithdrawed(amount))
{
//Domain Logic
//Process: Perform transfer operations to in-memory Domain-Model objects
// 1.- Charge money to origin acc
// 2.- Credit money to destination acc //Charge money
originAccount.WithdrawMoney(amount, string.Format(messages.GetStringResource(LocalizationKeys.Domain.messages_TransactionFromMessage), destinationAccount.Id)); //Credit money
destinationAccount.DepositMoney(amount, string.Format(messages.GetStringResource(LocalizationKeys.Domain.messages_TransactionToMessage), originAccount.Id));
}
else
throw new InvalidOperationException(messages.GetStringResource(LocalizationKeys.Domain.exception_BankAccountCannotWithdraw));
}
}
参考: dax.net https://www.cnblogs.com/daxnet/archive/2011/06/07/2074451.html
何镇汐 https://www.cnblogs.com/xiadao521/p/4141904.html
NLayerAppV3--DDD之领域层的更多相关文章
- [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)
一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...
- Java开发架构篇:DDD模型领域层决策规则树服务设计
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一章节介绍了领域驱动设计的基本概念以及按照领域驱动设计的思想进行代码分层,但是仅 ...
- DDD~领域层
回到目录 再论Domain与Infrastructure 在面向领域的设计中,领域层(Domain)实现上是位于最底层的,其它层有对它的引用,包括基础设施层(Infrastructure)也是去引用领 ...
- 【DDD】领域驱动设计实践 —— UI层实现
前面几篇blog主要介绍了DDD落地架构及业务建模战术,后续几篇blog会在此基础上,讲解具体的架构实现,通过完整代码demo的形式,更好地将DDD的落地方案呈现出来.本文是架构实现讲解的第一篇,主要 ...
- 【DDD】领域驱动设计实践 —— Application层实现
本文是DDD框架实现讲解的第二篇,主要介绍了DDD的Application层的实现,详细讲解了service.assemble的职责和实现.文末附有github地址.相比于<领域驱动设计> ...
- 【DDD】领域驱动设计实践 —— Domain层实现
本文是DDD框架实现讲解的第三篇,主要介绍了DDD的Domain层的实现,详细讲解了entity.value object.domain event.domain service的职责,以及如何识别出 ...
- DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)
从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...
- ABP领域层
1.实体Entites 1.1 概念 实体是DDD(领域驱动设计)的核心概念之一. 实体是具有唯一标识的ID且存储在数据库总.实体通常被映射成数据库中的一个表. 在ABP中,实体继承自Entity类. ...
- 我的“第一次”,就这样没了:DDD(领域驱动设计)理论结合实践
写在前面 插一句:本人超爱落网-<平凡的世界>这一期,分享给大家. 阅读目录: 关于DDD 前期分析 框架搭建 代码实现 开源-发布 后记 第一次听你,清风吹送,田野短笛:第一次看你,半弯 ...
随机推荐
- Sorting(好题)
Sorting https://www.zhixincode.com/contest/21/problem/I?problem_id=324 题目描述 你有一个数列a_1, a_2, \dots, a ...
- 虚拟机安装Centos6.5服务器系统
前言: 工作需要,研究Linux数日,写下此教程,意在给其他初学者参考学习,亦是给自己留作备用.好记性不如烂笔头,毕竟只是偶尔使用,留下教程,以备不时之需. 对于学习研究Linux的新手,个人推荐VM ...
- 300最长上升子序列 · Longest Increasing Subsequence
[抄题]: 往上走台阶 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的. 样例 给出 [5,4,1,2,3],LIS 是 [1,2 ...
- centos7装NVIDIA显卡驱动
一.系统及显卡 系统:centos7.5 64位 显卡:gtx 1060 前几天主要是有一个人脸识别的项目测试,需要用到显卡去测试性能,然后装显卡的过程折腾了一下,特此记录. 二.安装过程 1. 下载 ...
- [leetcode]426. Convert Binary Search Tree to Sorted Doubly Linked List二叉搜索树转有序双向链表
Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers ...
- SSH三大框架的关系、使用到的jar包、配置文件图解
- struts框架问题四之获取到值栈的对象
4. 问题四 : 如何获得值栈对象 * 获得值栈对象 有三种方法 * ValueStack vs1 = (ValueStack) ServletActionContext.getRequest().g ...
- mysql中float、double、decimal三种类型,以及数值产生误差的原因
单精度浮点数用4字节(32bit)表示浮点数,采用IEEE754标准的计算机浮点数,在内部是用二进制表示的,如:7.22用32位二进制是表示不下的,所以就导致不精确了,存取会出现误差. mysql中f ...
- Linux tcpdump命令
一.简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据 ...
- Santa Claus and a Place in a Class
/* Santa Claus is the first who came to the Christmas Olympiad, and he is going to be the first to t ...