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 前期分析 框架搭建 代码实现 开源-发布 后记 第一次听你,清风吹送,田野短笛:第一次看你,半弯 ...
随机推荐
- 第五章 二叉树(e5)重构
- python之递归锁【Rlock】
# 递归锁:就是一把锁中还有一把小锁,比如学校的大门口有一个大锁,学校里的 #每个教室也有一把小锁,以后所有的锁都用rlock就可以了,不要用lock,尤其是多层锁的时候,必须要用递归锁 import ...
- springboot的yaml基础语法与取值,配置类,配置文件加载优先级
1.基本语法k:(空格)v:表示一对键值对(一个空格必须有):以空格的缩进来控制层级关系:只要是左对齐的一列数据,都是同一个层级的属性和值也是大小写敏感: server: port: 8081 pat ...
- 如何进入/home/user/.wine
命令行输入 :cd /home/user/.wine/drive_c/windows/fonts /home是linux的用户目录,/user是用户名/.wine是隐藏目录,凡是以.开头的都是隐藏目录 ...
- php的无刷新实现方法
方法一: 我们通过http的204状态码,页面不跳转. 1.html代码如下: <!DOCTYPE HTML> <html lang="zh-CN"> &l ...
- JFinal WEB MVC和Struts简要对比
JFinal遵循COC原则,零配置,无xml,而struts需要配置来支持action.result.interceptor配置与使用. JFinal开发效率非常之高,相对Struts开发效率能提升五 ...
- Jmeter的一个jmx文件(备忘)
<?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1. ...
- 获得iframe 高度 ,各种浏览器
function fuFunctiondan(){ var frm=$("#z_div"); var iframeHeight=0; if (navigator.userAgent ...
- mysql 1045 access denied for user********
另一个方法Windows: 1. 管理员登陆系统,停止mysql服务或者结束mysqld-nt进程2. 进入命令行,来到mysql的安装目录.假设安装目录为 d:/mysql/ , CMD进入命令行3 ...
- 2018.09.25 51nod1597 有限背包计数问题(背包+前缀和优化)
传送门 dp好题. 我认为原题的描述已经很清楚了: 你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少. 两种方案不同当且仅当存在至少一个数i满足第i种 ...