设计模式-规约模式C#版
规约模式的使用场景就是规则,业务规则的碎片化。
业务规则的组合是不固定的,需要做成很容易组合,也很容易拆散的方式,规约模式是一个选择。
下面的例子是一个书店中,用户租书的场景。
需要判断用户的最大租书数和用户的状态,需要同时满足这两个要求,才可以继续租书。最大租书数和状态这两个规则拆散开来,在需要的时候再进行组合。不需要组合的地方,就单独使用这些规则。
针对一个实体有不同的规则,把这些规则碎片化,随意组合和拆散,这样就构成了规约模式。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DomainModel.Model { /// <summary> /// 规约模式 /// </summary> /// <typeparam name="T"></typeparam> public interface ISpecification<T> { bool IsSatisfiedBy(T entity); /// <summary> /// 与规约 /// </summary> /// <param name="specification"></param> /// <returns></returns> ISpecification<T> And(ISpecification<T> specification); /// <summary> /// 或规约 /// </summary> /// <param name="specification"></param> /// <returns></returns> ISpecification<T> Or(ISpecification<T> specification); /// <summary> /// 非规约 /// </summary> /// <returns></returns> ISpecification<T> Not(); } public class Customer { private ISpecification<Customer> _hasReachedMax; private ISpecification<Customer> _active; public Customer(ISpecification<Customer> hasReachedMax, ISpecification<Customer> active) { this._hasReachedMax = hasReachedMax; this._active = active; } public int TotalRentNumber { get; set; } public bool Active { get { return true; } } public bool CanRent() { var specification = this._hasReachedMax.Not().And(this._active.Not()); return specification.IsSatisfiedBy(this); } } public class HasReachedMaxSpecification : CompositeSpecification<Customer> { public override bool IsSatisfiedBy(Customer entity) { return entity.TotalRentNumber >= 6; } } public class CustomerActiveSpecification : CompositeSpecification<Customer> { public override bool IsSatisfiedBy(Customer entity) { return entity.Active; } } /// <summary> /// 组合规约 /// </summary> /// <typeparam name="T"></typeparam> public abstract class CompositeSpecification<T> : ISpecification<T> { public abstract bool IsSatisfiedBy(T entity); public ISpecification<T> And(ISpecification<T> specification) { return new AndSpecification<T>(this, specification); } public ISpecification<T> Not() { return new NotSpecification<T>(this); } public ISpecification<T> Or(ISpecification<T> specification) { throw new NotImplementedException(); } } public class AndSpecification<T> : CompositeSpecification<T> { private ISpecification<T> _left; private ISpecification<T> _right; public AndSpecification(ISpecification<T> left, ISpecification<T> right) { this._left = left; this._right = right; } public override bool IsSatisfiedBy(T entity) { return this._left.IsSatisfiedBy(entity) && this._right.IsSatisfiedBy(entity); } } public class OrSpecification<T> : CompositeSpecification<T> { private ISpecification<T> _left; private ISpecification<T> _right; public OrSpecification(ISpecification<T> left, ISpecification<T> right) { this._left = left; this._right = right; } public override bool IsSatisfiedBy(T entity) { return this._left.IsSatisfiedBy(entity) || this._right.IsSatisfiedBy(entity); } } public class NotSpecification<T> : CompositeSpecification<T> { private ISpecification<T> _inner; public NotSpecification(ISpecification<T> inner) { this._inner = inner; } public override bool IsSatisfiedBy(T entity) { return !this._inner.IsSatisfiedBy(entity); } } }
参考文献
1.走向.NET架构设计—第五章—业务层模式,原则,实践(前篇)