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数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经 ...
随机推荐
- SpringCloud的服务消费者 (一):(rest+ribbon)访问注册的微服务
采用Ribbon或Feign方式访问注册到EurekaServer中的微服务.1.Ribbon实现了客户端负载均衡,Feign底层调用Ribbon2.注册在EurekaServer中的微服务api,不 ...
- 由路由器AP隔离引起的WEB服务不能访问的问题
最近在自己的电脑上运行了一个Web服务,发现它只能被本机访问,无法在同一个局域网的其它设备访问. 于是在网上搜索了各种资料,通通都是在操作系统层面来分析解决问题的. 而我怎么尝试都不成功的情况下,差点 ...
- flask 视图函数的使用
flask框架 视图函数当中 各种实用情况简单配置 1 建立连接 2 路由参数 3 返回网络状态码 4 自定义错误页面 5 重定向 6 正则url限制 和 url 优化 7 设置和获取cookie # ...
- transition和animation做动画(css动画二)
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! translate:平移:是transform的一个属性: transform:变形:是一个静态属性,可以 ...
- [LeetCode] Convert BST to Greater Tree 将二叉搜索树BST转为较大树
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original B ...
- 微信小程序开发•模块化
微信小程序的MINA框架,其实是许多前端开发技术的组合.这篇文章中,我们来简单地讨论一下模块化. 1.模块化标准 玩前端的同学大部分都知道模块化的几个标准,CommonJs / AMD / CMD.这 ...
- CLR-2-2-引用类型和值类型
引用类型和值类型,是一个老生常谈的问题了.装箱拆箱相信也是猿猿都知,但是还是跟着CLR via C#加深下印象,看有没有什么更加根本和以前被忽略的知识点. 引用类型: 引用类型有哪些这里不过多赘述,来 ...
- 【luoguP4006 清华集训2017】小Y和二叉树
题目描述 小 Y 是一个心灵手巧的 OIer,她有许多二叉树模型. 小 Y 的二叉树模型中,每个结点都具有一个编号,小 Y 把她最喜欢的一个二叉树模型挂在了墙上,树根在最上面,左右子树分别在树根的左下 ...
- 计蒜客NOIP2017提高组模拟赛(四)day1
T1:小X的质数 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小 X 认为,质数是一切自然数起源的地方. 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因数的 ...
- 网络基础-再议TCP
以前只是知道3次握手和4次挥手,但是对于其在连接和断开时的各个状态却不是很懂,今天就来看一下握手和挥手时的状态转换图: 1.三次握手和四次挥手时的状态转换图: 实线表示应用程序: 应用层首先发SYN的 ...