中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

規(guī)范模式-------FromABPDocument

    

成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),十載企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都數(shù)千家客戶提供網(wǎng)頁設(shè)計(jì)制作,網(wǎng)站開發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營銷型網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),同時(shí)也為不同行業(yè)的客戶提供成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選創(chuàng)新互聯(lián)建站。

介紹

規(guī)范模式是一種特定的軟件設(shè)計(jì)模式,通過使用布爾邏輯 (維基百科)將業(yè)務(wù)規(guī)則鏈接在一起,可以重新組合業(yè)務(wù)規(guī)則。

在實(shí)際中,它主要用于 為實(shí)體或其他業(yè)務(wù)對象定義可重用的過濾器。

在本節(jié)中,我們將看到需要規(guī)格模式。本節(jié)是通用的,與ABP的實(shí)現(xiàn)無關(guān)。

假設(shè)您有一種服務(wù)方法來計(jì)算客戶的總數(shù),如下所示:

 規(guī)范模式-------From ABP Document

public  class CustomerManager
{    public  int  GetCustomerCount()
    {        // TODO ... 
        return  0 ;
    }
}

 規(guī)范模式-------From ABP Document

 

您可能希望通過過濾器獲得客戶數(shù)量。例如,您可能會(huì)有高級(jí)客戶(其余額超過10萬美元),或者您可能想要通過 注冊年度過濾客戶。然后,您可以創(chuàng)建其他方法,如GetPremiumCustomerCount() GetCustomerCountRegisteredInYear(int year), GetPremiumCustomerCountRegisteredInYear(int year)等。由于您有更多的標(biāo)準(zhǔn),因此無法為每種可能性創(chuàng)建組合。

這個(gè)問題的一個(gè)解決方案是規(guī)范模式。我們可以創(chuàng)建一個(gè)獲取參數(shù)作為過濾器的方法

 規(guī)范模式-------From ABP Document

public class CustomerManager
{    private readonly IRepository<Customer> _customerRepository;    public CustomerManager(IRepository<Customer> customerRepository)
    {
        _customerRepository = customerRepository;
    }    public int GetCustomerCount(ISpecification<Customer> spec)
    {        var customers = _customerRepository.GetAllList();        var customerCount = 0;        
        foreach (var customer in customers)
        {            if (spec.IsSatisfiedBy(customer))
            {
                customerCount++;
            }
        }        return customerCount;
    }
}

 規(guī)范模式-------From ABP Document

 

因此,我們可以獲得任何對象作為實(shí)現(xiàn) ISpecification <Customer>接口的參數(shù),定義如下:

public interface ISpecification<T>{    bool IsSatisfiedBy(T obj);
}

 

 

我們可以與客戶一起致電IsSatisfiedBy,以測試該客戶是否有意。因此,我們可以使用相同的GetCustomerCount與不同的過濾器,而不改變方法本身。

雖然這個(gè)解決方案在理論上是相當(dāng)不錯(cuò)的,但應(yīng)該改進(jìn),以更好地在C#中工作。例如,它是沒有效率得到所有客戶提供從數(shù)據(jù)庫來檢查它們是否滿足給定的規(guī)格/條件。在下一節(jié)中,我們將看到ABP的實(shí)現(xiàn),克服了這個(gè)問題。

創(chuàng)建規(guī)范類

ABP定義了ISpecification界面,如下所示:

 規(guī)范模式-------From ABP Document

public interface ISpecification<T>{    bool IsSatisfiedBy(T obj);

    Expression<Func<T, bool>> ToExpression();
}

 規(guī)范模式-------From ABP Document

 

 

添加ToExpression()方法,該方法返回一個(gè)表達(dá)式,并用于更好地與IQueryable和 Expression樹的集成。因此,我們可以輕松地將規(guī)范傳遞給存儲(chǔ)庫,以在數(shù)據(jù)庫級(jí)別應(yīng)用過濾器。

我們通常從規(guī)范<T>類繼承,而不是直接實(shí)現(xiàn)ISpecification <T>接口。規(guī)范類自動(dòng)實(shí)現(xiàn)IsSatisfiedBy方法。所以,我們只需要定義ToExpression。我們來創(chuàng)建一些規(guī)范類:

 規(guī)范模式-------From ABP Document

//Customers with $100,000+ balance are assumed as PREMIUM customers.public class PremiumCustomerSpecification : Specification<Customer>{    public override Expression<Func<Customer, bool>> ToExpression()
    {        return (customer) => (customer.Balance >= 100000);
    }
}//A parametric specification example.public class CustomerRegistrationYearSpecification : Specification<Customer>{    public int Year { get; }    public CustomerRegistrationYearSpecification(int year)
    {
        Year = year;
    }    public override Expression<Func<Customer, bool>> ToExpression()
    {        return (customer) => (customer.CreationYear == Year);
    }
}

 規(guī)范模式-------From ABP Document

 

 

如你所見,我們只是實(shí)現(xiàn)了簡單的lambda表達(dá)式 來定義規(guī)范。讓我們使用這些規(guī)格來獲得客戶數(shù)量:

count = customerManager.GetCustomerCount(new PremiumCustomerSpecification());
count = customerManager.GetCustomerCount(new CustomerRegistrationYearSpecification(2017));

 

使用規(guī)范與存儲(chǔ)庫

現(xiàn)在,我們可以優(yōu)化 CustomerManager 在數(shù)據(jù)庫中應(yīng)用過濾器

 規(guī)范模式-------From ABP Document

public class CustomerManager
{    private readonly IRepository<Customer> _customerRepository;    public CustomerManager(IRepository<Customer> customerRepository)
    {
        _customerRepository = customerRepository;
    }    public int GetCustomerCount(ISpecification<Customer> spec)
    {        return _customerRepository.Count(spec.ToExpression());
    }
}

 規(guī)范模式-------From ABP Document

 

 

這很簡單 我們可以將任何規(guī)范傳遞給存儲(chǔ)庫,因?yàn)?nbsp;存儲(chǔ)庫可以使用表達(dá)式作為過濾器。在此示例中,CustomerManager是不必要的,因?yàn)槲覀兛梢灾苯邮褂镁哂幸?guī)范的存儲(chǔ)庫來查詢數(shù)據(jù)庫。但是認(rèn)為我們想對一些客戶執(zhí)行業(yè)務(wù)操作。在這種情況下,我們可以使用具有域服務(wù)的規(guī)范來指定客戶進(jìn)行工作。

撰寫規(guī)格

規(guī)格一個(gè)強(qiáng)大的功能是,它們可組合使用 AND,OR,不ANDNOT擴(kuò)展方法。例:

var count = customerManager.GetCustomerCount(new PremiumCustomerSpecification().And(new CustomerRegistrationYearSpecification(2017)));

 

 

我們甚至可以從現(xiàn)有規(guī)范中創(chuàng)建一個(gè)新的規(guī)范類:

 規(guī)范模式-------From ABP Document

public class NewPremiumCustomersSpecification : AndSpecification<Customer>{    public NewPremiumCustomersSpecification() 
        : base(new PremiumCustomerSpecification(), new CustomerRegistrationYearSpecification(2017))
    {
    }
}

 規(guī)范模式-------From ABP Document

 

 

規(guī)范Specification 類的一個(gè)子類,只有在兩個(gè)規(guī)范都滿足的時(shí)候才能滿足。那么我們可以像其他規(guī)格一樣使用NewPremiumCustomersSpecification:

var count = customerManager.GetCustomerCount(new NewPremiumCustomersSpecification());

 

 

討論

雖然規(guī)范模式比C#lambda表達(dá)式更早,但它通常與表達(dá)式進(jìn)行比較。一些開發(fā)者可能會(huì)認(rèn)為它不再需要,我們可以直接將表達(dá)式傳遞到存儲(chǔ)庫或域服務(wù),如下所示:

var count = _customerRepository.Count(c => c.Balance > 100000 && c.CreationYear == 2017);

 

 

由于ABP的存儲(chǔ)庫支持expessions,這是完全有效的用法。您不必在應(yīng)用程序中定義或使用任何規(guī)范,您可以使用表達(dá)式。那么說明什么呢?為什么和何時(shí)應(yīng)該考慮使用它們?

何時(shí)使用?

使用規(guī)格的一些好處:

  • Reusabe:認(rèn)為您需要在您的代碼庫中的許多地方使用PremiumCustomer過濾器。如果您使用表達(dá)式而不是創(chuàng)建規(guī)范,如果您以后更改“高級(jí)客戶”定義(例如,要將最終余額從100,000美元更改為25萬美元,并添加另一個(gè)條件,以成為3歲以上的客戶),會(huì)發(fā)生什么。如果您使用規(guī)范,您只需更改單個(gè)類。如果您使用(復(fù)制/粘貼)相同的表達(dá)式,則需要更改它們。

  • 可組合:您可以將多個(gè)規(guī)格來創(chuàng)建新的規(guī)范。這是另一種可重用性。

  • 命名:PremiumCustomerSpecification更好地解釋了意圖,而不是復(fù)雜的表達(dá)。因此,如果您的業(yè)務(wù)有意義的表達(dá)式,請考慮使用規(guī)范。

  • 可測試:一個(gè)規(guī)范是單獨(dú)(和容易)可測試的對象。

何時(shí)不使用?
  • 非業(yè)務(wù)表達(dá)式:您可以考慮不使用非業(yè)務(wù)相關(guān)表達(dá)式和操作的規(guī)范。

  • 報(bào)告:如果你只是創(chuàng)建一個(gè)報(bào)表,不要?jiǎng)?chuàng)建規(guī)范,而是直接使用IQueryable。實(shí)際上,您甚至可以使用簡單的SQL,Views或其他工具進(jìn)行報(bào)告。DDD不關(guān)心報(bào)告,并且從性能的角度來看,底層數(shù)據(jù)存儲(chǔ)的查詢優(yōu)勢可能很重要。

當(dāng)前名稱:規(guī)范模式-------FromABPDocument
轉(zhuǎn)載來于:http://www.rwnh.cn/article38/jepipp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化網(wǎng)站收錄、定制開發(fā)、建站公司、動(dòng)態(tài)網(wǎng)站微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
汉川市| 平遥县| 宁安市| 吐鲁番市| 蕉岭县| 图片| 鄂托克前旗| 龙泉市| 江门市| 保亭| 郸城县| 萨嘎县| 兴宁市| 延边| 临高县| 涿鹿县| 土默特左旗| 石嘴山市| 龙口市| 邵阳县| 绥江县| 金昌市| 辽中县| 大石桥市| 易门县| 旬邑县| 巫溪县| 永宁县| 青河县| 张北县| 仲巴县| 浑源县| 二手房| 罗定市| 怀集县| 牡丹江市| 蒙城县| 襄汾县| 黄龙县| 融水| 平阴县|