设计模式之规格模式
时间:2022-07-23
本文章向大家介绍设计模式之规格模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
设计模式之规格模式
在计算机程序中, 规格模式是一种特殊的软件设计模式,业务规则可以使用布尔逻辑组成规则连而重新组合, 这种模式通常在领域驱动设计中使用。
规格模式描述的是一个业务规则可以和另外的业务规则聚合, 在这种模式中, 业务逻辑单元继承自可聚合的抽象规格基类类,该基类有一个返回布尔值的方法 IsSatisfiedBy
。 在初始化之后, 规格可以和其它规格进行逻辑组合, 使新的规格很容易维护, 实现高度自定义的业务逻辑。
规格模式的 UML 图如下:
实现代码如下:
public interface ISpecification<TTarget> {
bool IsSatisfiedBy(TTarget candidate);
ISpecification<TTarget> And(ISpecification<TTarget> specification);
ISpecification<TTarget> Or(ISpecification<TTarget> specification);
ISpecification<TTarget> Not(ISpecification<TTarget> specification);
}
上面是规格模式的接口定义, 通常会实现一个抽象的 CompositSpecification
做为基类, 代码如下:
public abstract class CompositSpecification<TTarget> : ISpecification<TTarget> {
public abstract bool IsSatisfiedBy(TTarget candidate);
public ISpecification<TTarget> And(ISpecification<TTarget> specification) {
return new AndSpecification<TTarget>(this, specification);
}
public ISpecification<TTarget> Or(ISpecification<TTarget> specification) {
return new OrSpecification<TTarget>(this, specification);
}
public ISpecification<TTarget> Not(ISpecification<TTarget> specification) {
return new NotSpecification<TTarget>(specification);
}
}
AndSpecification
实现两种规格通过逻辑与尽兴组合:
public class AndSpecification<TTarget> : CompositSpecification<TTarget> {
readonly ISpecification<TTarget> x;
readonly ISpecification<TTarget> y;
public AndSpecification(ISpecification<TTarget> x, ISpecification<TTarget> y) {
this.x = x;
this.y = y;
}
public override bool IsSatisfiedBy(TTarget candidate) {
return x.IsSatisfiedBy(candidate) && y.IsSatisfiedBy(candidate);
}
}
OrSpecification
实现两种规格通过逻辑或进行组合:
public class OrSpecification<TTarget> : CompositSpecification<TTarget> {
readonly ISpecification<TTarget> x;
readonly ISpecification<TTarget> y;
public OrSpecification(ISpecification<TTarget> x, ISpecification<TTarget> y) {
this.x = x;
this.y = y;
}
public override bool IsSatisfiedBy(TTarget candidate) {
return x.IsSatisfiedBy(candidate) || y.IsSatisfiedBy(candidate);
}
}
NotSpecification
实现规格的逻辑否:
public class NotSpecification<TTarget> : CompositSpecification<TTarget> {
readonly ISpecification<TTarget> x;
public NotSpecification(ISpecification<TTarget> x) {
this.x = x;
}
public override bool IsSatisfiedBy(TTarget candidate) {
return !x.IsSatisfiedBy(candidate);
}
}
至此, 规格模式就基本上实现了, 不过实际使用中, 通常会实现一个范型的规格模式作为入口, 代码如下:
public class ExpressionSpecification<TTarget> : CompositSpecification<TTarget> {
readonly Func<TTarget, bool> expression;
public ExpressionSpecification(Func<TTarget, bool> expression) {
this.expression = expression;
}
public override bool IsSatisfiedBy(TTarget candidate) {
return expression(candidate);
}
}
现在看一个实际的例子, 我们有一些手机, 代码如下:
var mobiles = new List<Mobile>() {
new Mobile(MobileBrand.Apple, MobileType.Smart),
new Mobile(MobileBrand.Samsung, MobileType.Smart),
new Mobile(MobileBrand.Samsung, MobileType.Basic)
};
使用规格模式选出所有的智能手机, 代码如下:
var smartSpecification = new ExpressionSpecification<Mobile>(
mobile => mobile.Type == MobileType.Smart
);
// find all smart mobiles;
var smartMobiles = mobiles.FindAll(
mobile => smartSpecification.IsSatisfiedBy(mobile)
);
使用两种规格模式进行逻辑与组合, 选出品牌是 Apple 的智能手机, 代码如下:
var appleSpecification = new ExpressionSpecification<Mobile>(
mobile => mobile.Brand = MobileBrand.Apple
);
// find all apple smart mobiles;
var andSpecification = new AndSpecification<Mobile>(
smartSpecification, appleSpecification
);
var appleSmartMobiles = mobiles.FindAll(
mobile => andSpecification.IsSatisfiedBy(mobile)
);
值得一提的是, .NET 3.5 之后引入的 Linq 就是基于规格模式的, 可以说是规格模式的典范。
- 双拼域名lanben.com以三万元成交
- 动手写个数字输入框3:痛点——输入法是个魔鬼
- Thinking in React Implemented by Reagent
- ssm整合Redis
- 前端魔法堂——调用栈,异常实例中的宝藏
- 开启MySQL的binlog日志
- C#解析JSON
- 动手写个数字输入框1:input[type=number]的遗憾
- 小猪农场获百万天使轮,六声域名源自运营主体
- Intellij idea 的maven项目自动下载jar包
- python3和python2共存
- 揭密微信跳一跳小游戏那些外挂
- 特斯拉出现人才流失潮,竟因为一些工程师认为Autopilot自动驾驶技术并不安全
- 微信又更新了,这次放出年度大招!新变化让不少人拍手叫好!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法