首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

趣味編程:C# 中 Specification 模式初探—— 從 OrWhere 需求說起

     編輯:關於C#

觸發需求

朋友想實現 source.OrWhere(i => i > 0),但在 LINQ 中 Where 後序列已過濾,無法「補回」被排除元素。這啟發我引入 Specification 模式。

Specification 模式定義

將業務規則封裝為可組合對象:

public interface ISpecification<T> {
    bool IsSatisfiedBy(T candidate);
    ISpecification<T> And(ISpecification<T> other);
    ISpecification<T> Or(ISpecification<T> other);
    ISpecification<T> Not();
}

標準實現結構

public abstract class CompositeSpecification<T> : ISpecification<T> {
    public abstract bool IsSatisfiedBy(T candidate);
    public ISpecification<T> And(ISpecification<T> o) => new AndSpecification<T>(this, o);
    public ISpecification<T> Or(ISpecification<T> o) => new OrSpecification<T>(this, o);
    public ISpecification<T> Not() => new NotSpecification<T>(this);
}

public class AndSpecification<T> : CompositeSpecification<T> { ... }
public class OrSpecification<T> : CompositeSpecification<T> { ... }
public class NotSpecification<T> : CompositeSpecification<T> { ... }

具體規則實現

public class OddSpecification : CompositeSpecification<int> {
    public override bool IsSatisfiedBy(int c) => c % 2 != 0;
}
public class PositiveSpecification : CompositeSpecification<int> {
    public override bool IsSatisfiedBy(int c) => c > 0;
}

組合使用

var odd = new OddSpecification();
var oddOrPositive = odd.Or(new PositiveSpecification());

foreach (var i in Enumerable.Range(-5, 10).Where(x => oddOrPositive.IsSatisfiedBy(x)))
    Console.WriteLine(i); // -5 -3 -1 1 2 3 4

反思與展望

標準實現「殺雞用牛刀」,每個規則一個類別太重。C# 擁有委托、擴展方法、Lambda、表達式樹等強大特性,能否實現更輕量、更原生的版本?且朋友真實場景是 LINQ to SQL,需表達式樹組合。請見上/下兩篇參考答案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved