規約模式的使用場景就是規則,業務規則的碎片化。
業務規則的組合是不固定的,需要做成很容易組合,也很容易拆散的方式,規約模式是一個選擇。
下面的例子是一個書店中,用戶租書的場景。
需要判斷用戶的最大租書數和用戶的狀態,需要同時滿足這兩個要求,才可以繼續租書。最大租書數和狀態這兩個規則拆散開來,在需要的時候再進行組合。不需要組合的地方,就單獨使用這些規則。
針對一個實體有不同的規則,把這些規則碎片化,隨意組合和拆散,這樣就構成了規約模式。
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); } } }
本文出自 “突破中的IT結構師” 博客,請務必保留此出處http://virusswb.blog.51cto.com/115214/1020667
查看本欄目