日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

趣味编程:C#中Specification模式的实现

發布時間:2024/4/11 C# 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 趣味编程:C#中Specification模式的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天有朋友在問了我這么一個問題:怎么實現OrWhere的功能?我猜測,他的意思是要實現這樣的功能:

static IEnumerable<int> MorePredicate(IEnumerable<int> source) {return source(i => i > 0); // 或所有的正數 }static void Main(string[] args) {var array = Enumerable.Range(-5, 10).ToArray();var odd = array.Where(i => i % 2 != 0); // 排除所有偶數var oddOrPositive = MorePredicate(odd);foreach (var i in oddOrPositive){Console.WriteLine(i);} }

以上代碼應該輸出-5,-3,-1,1,2,3,4。但顯然,這段代碼是無法編譯通過,無法通過補充類庫來實現的。因為在Main方法中的Where過后,已經排除了所有的偶數,于是在接下來的代碼中是無法從新的序列中再次恢復元素的。

不過這個要求讓我想起了Specification模式。Specification模式的作用是構建可以自由組裝的業務邏輯元素。Specification類有一個IsSatisifiedBy函數,用于校驗某個對象是否滿足該Specification所表示的條件。多個Specification對象可以組裝起來,并生成新Specification對象,這便可以形成高度可定制的業務邏輯。例如,我們可以使用依賴注入(控制反轉)的方式來配置這個業務邏輯,以此保證系統的靈活性。

如果您點開上面那個Wikipedia的鏈接,就會發現這段描述大約是一個英譯中的練習。抄完了“定義”,再來看看同樣引自Wikipedia的UML圖:

一般來說,Specification模式則意味著實現這樣一個接口:

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

實現了ISpecification的對象則意味著是一個Specification,它可以通過與其他Specification對象的And,Or或對自身的取反來生成新的邏輯。為了方便這些“組合邏輯”的開發,我們還會準備一個抽象的CompositeSpecification類:

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

CompositeSpecification提供了構建復合Specification的基礎邏輯,它提供了And、Or和Not方法的實現,讓其他Specification類只需要專注于IsSatisfiedBy方法的實現即可。例如,以下便是三種邏輯組合的具體實現:

public class AndSpecification<T> : CompositeSpecification<T> {private ISpecification<T> m_one;private ISpecification<T> m_other;public AndSpecification(ISpecification<T> x, ISpecification<T> y){m_one = x;m_other = y;}public override bool IsSatisfiedBy(T candidate){return m_one.IsSatisfiedBy(candidate) && m_other.IsSatisfiedBy(candidate);} }public class OrSpecification<T> : CompositeSpecification<T> {private ISpecification<T> m_one;private ISpecification<T> m_other;public OrSpecification(ISpecification<T> x, ISpecification<T> y){m_one = x;m_other = y;}public override bool IsSatisfiedBy(T candidate){return m_one.IsSatisfiedBy(candidate) || m_other.IsSatisfiedBy(candidate);} }public class NotSpecification<T> : CompositeSpecification<T> {private ISpecification<T> m_wrapped;public NotSpecification(ISpecification<T> x){m_wrapped = x;}public override bool IsSatisfiedBy(T candidate){return !m_wrapped.IsSatisfiedBy(candidate);} }

于是,我們便可以使用Specification模式來處理剛才那位朋友的問題。例如,首先他需要排除所有的偶數,那么我們不妨實現一個OddSpecification:

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

自然,還有用于獲得所有正數的Specification類:

public class PositiveSpecification : CompositeSpecification<int> {public override bool IsSatisfiedBy(int candidate){return candidate > 0;} }

于是在使用時,我們會將其通過Or方法組合起來:

static ISpecification<int> MorePredicate(ISpecification<int> original) {return original.Or(new PositiveSpecification()); }static void Main(string[] args) {var array = Enumerable.Range(-5, 10).ToArray();var oddSpec = new OddSpecification();var oddAndPositiveSpec = MorePredicate(oddSpec);foreach (var item in array.Where(i => oddAndPositiveSpec.IsSatisfiedBy(i))){Console.WriteLine(item);} }

但是,您覺得這個做法怎么樣?我覺得過于殺雞用牛刀,高射炮打蚊子了。Specification模式雖然常用,但是用在這里太重量級了。如果我們為每一個函數都補充一個Specification類,至少會讓我感到厭倦。

以上的代碼其實轉載自Wikipedia詞條,不過我修改了一些命名,以及改寫成泛型版本。我們有理由推測,Wikipedia上是非常舊的內容,很可能是在C#只是1.0版本的時候編寫的代碼(或者說它為了“兼容”Java那種語言的實現方式)。那么在實際開發過程中,我們又該如何利用C#如今的強大特性來實現出更容易使用,甚至是更為“輕量級”的Specification模式呢?

此外,剛才又收到那位朋友的消息,他其實是想在使用LINQ to SQL時實現“可擴展的邏輯”。那么,對于他說的情況,我們又該如何應對呢?

總結

以上是生活随笔為你收集整理的趣味编程:C#中Specification模式的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。