DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)
这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题。
大家都知道,聚合根、实体和值对象这些领域对象都自身处理自己的业务逻辑。在业务处理过程中,通常会有一些条件判断,当满足这些条件时,会进行不同的后续处理。在传统的实现中,可以通过If Else条件语句进行判断,但If Else语句在复杂领域中来检查是否满足一些业务条件存在以下的问题:
1. 无法很好的显示表达业务条件本身。
2. 无法对多个条件在不同需要的地方进行灵活的组合。
为了更好的组织业务逻辑中关于业务条件的判断,最佳实践方式是将业务条件拆分得足够细,并用语义化的方式表示。这样,在当前上下文中的领域对象就可以使用一个或多个业务条件的组合。
举个例子:酒店业务中,房间领域对象会处理预定房间的领域逻辑和退房的领域逻辑,在预定房间时,我们需要保证房间没有被其他人预定并且房间没有正在维护这两个业务条件同时满足;在退房时,我们需要保证房间里没有物品损坏或已经进行了损坏赔偿这两个业务条件中的任意一个。
要实现上述的需求,我们可以分别作出4个业务条件规则,然后在界限上下文任意要使用的地方进行灵活的组合。
1. 为了达到上述目的,我们首先要开发出业务条件的接口与条件的组合方式定义。
public interface ISpecification<T>
{
bool IsSatisfied(T entity);
}
该规约接口就定义了一个方法,传入某个领域对象,判断是否满足条件。
public class AndSpecification<T> : ISpecification<T>
{
private ISpecification<T> left;
private ISpecification<T> right;
public AndSpecification(ISpecification<T> left,ISpecification<T> right)
{
this.left = left;
this.right = right;
}
public bool IsSatisfied(T entity)
{
return this.left.IsSatisfied(entity)
&& this.right.IsSatisfied(entity);
}
}
该类实现了两个业务条件的与关系。
public class OrSpecification<T> : ISpecification<T>
{
private ISpecification<T> left;
private ISpecification<T> right;
public OrSpecification(ISpecification<T> left, ISpecification<T> right)
{
this.left = left;
this.right = right;
}
public bool IsSatisfied(T entity)
{
return this.left.IsSatisfied(entity)
|| this.right.IsSatisfied(entity);
}
}
该类实现了两个业务条件的或关系。
2. 在房间业务界限上下文中,分别实现4个业务条件规则。
//房间没有被其他人预定业务条件判断
public class RoomIsNotConfirmedByOtherSpecification : ISpecification<Room>
{
public bool IsSatisfied(Room entity)
{
return !entity.OtherConfirmed;
}
}
//房间没有被正在维护业务条件判断
public class RoomIsNotMaintenanceSpecification : ISpecification<Room>
{
public bool IsSatisfied(Room entity)
{
return !entity.Maintenancing;
}
}
//房间没有物品损坏条件判断
public class RoomIsNotAnythingBrokenSpecification : ISpecification<Room>
{
public bool IsSatisfied(Room entity)
{
return !entity.AnythingBroken;
}
}
//房间没有物品损坏条件判断
public class RoomHasBeenBrokenCompensateSpecification : ISpecification<Room>
{
public bool IsSatisfied(Room entity)
{
return entity.HasBeenCompensated;
}
}
3. 在房间领域对象的预定房间与退房的领域逻辑中,组合使用上述4个条件规则
//预定房间
public Room Reservation()
{
var roomisnotconfirmedspec = new RoomIsNotConfirmedByOtherSpecification();
var roomisnotmaintenancespec = new RoomIsNotMaintenanceSpecification();
var researvationrulespec = new AndSpecification<Room>(roomisnotconfirmedspec, roomisnotconfirmedspec);
if (researvationrulespec)
{
//进行后续业务处理
}
return this;
} //退房
public Room CheckOut()
{
var roomisnotanythingbrokenspec = new RoomIsNotAnythingBrokenSpecification();
var roomhasbeenbrokenspec = new RoomHasBeenBrokenCompensateSpecification();
var checkrulespec = new OrSpecification<Room>(roomisnotanythingbrokenspec, roomhasbeenbrokenspec);
if (checkrulespec)
{
//进行后续业务处理
}
return this;
}
当然如果要任意组合多个与、或业务条件,需要在规约上实现Or、And方法来形成链式调用,具体怎么实现?有了上面的思路,自己写代码试试吧。
QQ讨论群:309287205
DDD实战进阶视频请关注微信公众号:
DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)的更多相关文章
- DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述)
本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于 ...
- DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)
要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...
- DDD实战进阶第一波(三):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架二)
了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能 ...
- DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)
从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...
- DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇)
前面我们花了14篇的文章来给大家介绍经典DDD的概念.架构和实践.这篇文章我们来做一个完整的总结,另外生成一个Api接口文档. 一.DDD解决传统的开发的几大问题: 没有描述需求的设计模型:而是直接通 ...
- DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)
前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调 领域逻辑与仓储持久化. 首先大家需要明确的是,产品上下文 ...
- DDD实战进阶第一波(十二):开发一般业务的大健康行业直销系统(订单上下文POCO模型)
在本系列前面的文章中,我们主要讨论了产品上下文与经销商上下文相关的实现,大家对DDD的方法与架构已经有了初步的了解. 但是在这两个界限上下文中,业务逻辑很简单,也没有用到更多的值对象的内容.从这篇文章 ...
- DDD实战进阶第一波(四):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架三)
上一篇文章我们讲了经典DDD架构对比传统三层架构的优势,以及经典DDD架构每一层的职责后,本篇文章将介绍基础结构层中支持DDD的轻量级框架的主要代码. 这里需要说明的是,DDD轻量级框架能够体现DDD ...
- DDD实战进阶第一波(九):开发一般业务的大健康行业直销系统(实现经销商上下文仓储与领域逻辑)
上篇文章主要讲述了经销商上下文的需求与POCO对象,这篇文章主要讲述该界限上下文的仓储与领域逻辑的实现. 关于界限上下文与EF Core数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经 ...
随机推荐
- python入门(10)使用List和tuple
python入门(10)使用List和tuple list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可 ...
- OAuth2.0学习(1-12)开源的OAuth2.0项目和比较
OAuth2.0学习(2-1)OAuth的开源项目 1.开源项目列表 http://www.oschina.net/project/tag/307/oauth?lang=19&sort=t ...
- kafka---broker 保存消息
1 .存储方式 物理上把 topic 分成一个或多个 patition(对应 server.properties 中的 num.partitions=3 配置),每个 patition 物理上对应一个 ...
- windows系统设置虚拟机开机自启并运行虚拟系统
简述 很多用windows系统电脑开发的童鞋,会在自己电脑上装一个虚拟机,然后在装一个linux系统当作服务器来使用. 但每次电脑开机都要去重启一下虚拟机电源,实在是不划算.下面博主教大家在windo ...
- codeforces 798c Mike And Gcd Problem
题意: 给出一个数列,现在有一种操作,可以任何一个a[i],用a[i] – a[i+1]和a[i]+a[i+1]替代a[i]和a[i+1]. 问现在需要最少多少次操作,使得整个数列的gcd大于1. 思 ...
- Excel和Word 简易工具类,JEasyPoi 2.1.5 版本发布
Excel和Word 简易工具类,JEasyPoi 2.1.5 版本发布 摘要: jeasypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导 ...
- 列表(list)之一定义 添加 删除 排序 反转 索引等其他操作
1.定义: 创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可,序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. # 列表list1=[&q ...
- [LeetCode] Base 7 基数七
Given an integer, return its base 7 string representation. Example 1: Input: 100 Output: "202&q ...
- UVALive - 3882:And Then There Was One
约瑟夫环 f[i]表示有i个人先处理第k个人,最后被处理的人是谁 #include<cstdio> #include<cstdlib> #include<algorith ...
- NOIP提高组2010 乌龟棋
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点. 乌 ...