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

趣味編程:C# Specification 模式實戰(上)—— 從標準實現到輕量級委托版本

     編輯:關於C#

標準 Specification 模式回顧

傳統做法需為每個業務規則建立類別(OddSpecification, PositiveSpecification...),並透過 AndSpecification, OrSpecification, NotSpecification 組合,代碼冗長。

輕量級重構:委托注入

Specification 核心只是 IsSatisfiedBy 邏輯,可用 Func<T,bool> 直接注入:

public class Specification<T> : ISpecification<T> {
    private readonly Func<T, bool> _predicate;
    public Specification(Func<T, bool> predicate) => _predicate = predicate;
    public bool IsSatisfiedBy(T candidate) => _predicate(candidate);
}

擴展方法實現組合邏輯

public static class SpecificationExtensions {
    public static ISpecification<T> And<T>(
        this ISpecification<T> a, ISpecification<T> b) =>
        new Specification<T>(c => a.IsSatisfiedBy(c) && b.IsSatisfiedBy(c));

    public static ISpecification<T> Or<T>(...) => ... // 類似
    public static ISpecification<T> Not<T>(...) => ... // 類似
}

更極致:直接用委托型別

public delegate bool Spec<T>(T candidate); // 或直接用 Func<T,bool>

public static class SpecExtensions {
    public static Spec<T> And<T>(this Spec<T> a, Spec<T> b) 
        => c => a(c) && b(c);
    public static Spec<T> Or<T>(this Spec<T> a, Spec<T> b) 
        => c => a(c) || b(c);
    public static Spec<T> Not<T>(this Spec<T> a) 
        => c => !a(c);
}

使用示範

var odd = new Spec<int>(i => i % 2 == 1);
var oddAndPositive = odd.Or(i => i > 0); // 組合

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

優缺點權衡

維度獨立類別委托版本
邏輯內聚高分散
靜態可配置性佳(可序列化型別名)差
編碼便利性繁瑣極簡
生命週期陷阱明顯易察覺隱蔽(閉包捕獲)

下篇預告

委托版無法直接用於 LINQ to SQL,下篇將解決表達式樹組合問題。

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