今天有朋友在問了我這麼一個問題:怎麼實現OrWhere的功能?我猜測,他的意思是要實現這樣的功能:
static IEnumerable<int> MorePredicate(IEnumerable<int> source)
{
return source.OrWhere(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();
}