CompositeSpecification 抽象基類
public abstract class CompositeSpecification<T> : ISpecification<T>
{
public abstract bool IsSatisfiedBy(T candidate);
public ISpecification<T> And(ISpecification<T> other)
=> new AndSpecification<T>(this, other);
public ISpecification<T> Or(ISpecification<T> other)
=> new OrSpecification<T>(this, other);
public ISpecification<T> Not()
=> new NotSpecification<T>(this);
}
三種邏輯組合實作
public class AndSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _one, _other;
public AndSpecification(ISpecification<T> x, ISpecification<T> y) { _one = x; _other = y; }
public override bool IsSatisfiedBy(T candidate) => _one.IsSatisfiedBy(candidate) && _other.IsSatisfiedBy(candidate);
}
public class OrSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _one, _other;
public OrSpecification(ISpecification<T> x, ISpecification<T> y) { _one = x; _other = y; }
public override bool IsSatisfiedBy(T candidate) => _one.IsSatisfiedBy(candidate) || _other.IsSatisfiedBy(candidate);
}
public class NotSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _wrapped;
public NotSpecification(ISpecification<T> x) { _wrapped = x; }
public override bool IsSatisfiedBy(T candidate) => !_wrapped.IsSatisfiedBy(candidate);
}
使用範例
var spec = new NameStartsWith("A").And(new AgeGreaterThan(18)).Not(new IsBanned());
bool ok = spec.IsSatisfiedBy(user);
優點
- 將複雜業務規則分解為小型、可測試、可組合的單元。
- 符合開放封閉原則:新增規則只需新增
ISpecification 實作,不修改現有程式碼。
- 語意清晰,程式碼可讀性高。