欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net行為型設(shè)計(jì)模式之模板方法模式(Template?Method)

 更新時(shí)間:2022年05月26日 09:13:57   作者:springsnow  
這篇文章介紹了.Net行為型設(shè)計(jì)模式之模板方法模式(Template?Method),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、動(dòng)機(jī)(Motivate)

“模板方法”,就是有一個(gè)方法包含了一個(gè)模板,這個(gè)模板是一個(gè)算法。在我們的現(xiàn)實(shí)生活中有很多例子可以拿來(lái)說(shuō)明這個(gè)模式,就拿吃餃子這個(gè)事情來(lái)說(shuō),要想吃到餃子必須經(jīng)過(guò)三步,第一步是“和面”,第二步是“包餡”,第三步是“煮餃子”,這三步就是一個(gè)算法,我們要想吃到不同的面和餡的餃子,對(duì)這三步中的任意一步就行操作就可以,也可以完全定義這三步

在軟件構(gòu)建過(guò)程中,對(duì)于某一項(xiàng)任務(wù),它常常有穩(wěn)定的整體操作結(jié)構(gòu),但各個(gè)子步驟卻有很多改變的需求,或者由于固有的原因(比如框架與應(yīng)用之間的關(guān)系)而無(wú)法和任務(wù)的整體結(jié)構(gòu)同時(shí)實(shí)現(xiàn)。如何在確定穩(wěn)定操作結(jié)構(gòu)的前提下,來(lái)靈活應(yīng)對(duì)各個(gè)子步驟的變化或者晚期實(shí)現(xiàn)需求?

二、意圖(Intent)

定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類(lèi)中。Template Method使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。                                 ——《設(shè)計(jì)模式》GoF

三、結(jié)構(gòu)圖

四、模式的組成

模板方法模式參與者:

(1)、抽象類(lèi)角色(AbstractClass):定義一個(gè)模板方法(TemplateMethod),在該方法中包含著一個(gè)算法的骨架,具體的算法步驟是PrimitiveOperation1方法和PrimitiveOperation2方法,該抽象類(lèi)的子類(lèi)將重定義PrimitiveOperation1和PrimitiveOperation2操作。

(2)、具體類(lèi)角色(ConcreteClass):實(shí)現(xiàn)PrimitiveOperation1方法和PrimitiveOperation2方法以完成算法中與特定子類(lèi)(Client)相關(guān)的內(nèi)容。

在模板方法模式中,AbstractClass中的TemplateMethod提供了一個(gè)標(biāo)準(zhǔn)模板,該模板包含PrimitiveOperation1和PrimitiveOperation2兩個(gè)方法,這兩個(gè)方法的內(nèi)容Client可以根據(jù)自己的需要重寫(xiě)。

五、模板方法模式的具體實(shí)現(xiàn)

下面以生活中吃餃子為例來(lái)實(shí)現(xiàn)模板方法模式。在現(xiàn)實(shí)生活中,做餃子的步驟都大致相同,如果我們針對(duì)每種餃子的做法都定義一個(gè)類(lèi),這樣在每個(gè)類(lèi)中都有很多相同的代碼,為了解決這個(gè)問(wèn)題,我們一般的思路肯定是把相同的部分抽象出來(lái)到抽象類(lèi)中去定義,具體子類(lèi)來(lái)實(shí)現(xiàn)具體的不同部分,這個(gè)思路也正式模板方法的實(shí)現(xiàn)精髓所在,具體實(shí)現(xiàn)代碼如下:

static void Main(string[] args)
{
    //現(xiàn)在想吃綠色面的,豬肉大蔥餡的餃子
    AbstractClass fan = new ConcreteClass1();
    fan.EatDumplings();

    Console.WriteLine();
    //過(guò)了段時(shí)間,我開(kāi)始想吃橙色面的,韭菜雞蛋餡的餃子
    fan = new ConcreteClass2();
    fan.EatDumplings();
}


//該類(lèi)型就是抽象類(lèi)角色--AbstractClass,定義做餃子的算法骨架,這里有三步驟,當(dāng)然也可以有多個(gè)步驟,根據(jù)實(shí)際需要而定
public abstract class AbstractClass
{
    //該方法就是模板方法,方法里面包含了做餃子的算法步驟,模板方法可以返回結(jié)果,也可以是void類(lèi)型,視具體情況而定
    public void EatDumplings()
    {
        MakingDough();//和面
        MakeDumplings();//包餡
        BoiledDumplings();  //煮餃子
        Console.WriteLine("餃子真好吃!");
    }

    public abstract void MakingDough();//要想吃餃子第一步肯定是“和面”---該方法相當(dāng)于算法中的某一步
    public abstract void MakeDumplings();//要想吃餃子第二部是“包餃子”---該方法相當(dāng)于算法中的某一步
    public abstract void BoiledDumplings(); //要想吃餃子第三部是“煮餃子”---該方法相當(dāng)于算法中的某一步
}

//該類(lèi)型是具體類(lèi)角色--ConcreteClass,我想吃綠色面皮,豬肉大蔥餡的餃子
public sealed class ConcreteClass1 : AbstractClass
{
    public override void MakingDough()  //要想吃餃子第一步肯定是“和面”---該方法相當(dāng)于算法中的某一步
    {
        Console.WriteLine("在和面的時(shí)候加入芹菜汁,和好的面就是綠色的");//我想要面是綠色的,綠色健康嘛,就可以在此步定制了
    }

    public override void MakeDumplings()//要想吃餃子第二部是“包餃子”---該方法相當(dāng)于算法中的某一步
    {
        Console.WriteLine("農(nóng)家豬肉和農(nóng)家大蔥,制作成餡");//我想吃豬肉大蔥餡的,在此步就可以定制了
    }

    public override void BoiledDumplings()//要想吃餃子第三部是“煮餃子”---該方法相當(dāng)于算法中的某一步
    {
        Console.WriteLine("用我家的大鐵鍋和大木材煮餃子");//我想吃大鐵鍋煮的餃子,有家的味道,在此步就可以定制了
    }
}

//該類(lèi)型是具體類(lèi)角色--ConcreteClass2,我想吃橙色面皮,韭菜雞蛋餡的餃子
public sealed class ConcreteClass2 : AbstractClass
{
    public override void MakingDough()//要想吃餃子第一步肯定是“和面”---該方法相當(dāng)于算法中的某一步
    {
        Console.WriteLine("在和面的時(shí)候加入胡蘿卜汁,和好的面就是橙色的");//我想要面是橙色的,加入胡蘿卜汁就可以。在此步定制就可以了。
    }

    public override void MakeDumplings()    //要想吃餃子第二部是“包餃子”---該方法相當(dāng)于算法中的某一步
    {
        Console.WriteLine("農(nóng)家雞蛋和農(nóng)家韭菜,制作成餡");    //我想吃韭菜雞蛋餡的,在此步就可以定制了
    }

    public override void BoiledDumplings()//要想吃餃子第三部是“煮餃子”---該方法相當(dāng)于算法中的某一步
    {
        Console.WriteLine("可以用一般煤氣和不粘鍋煮就可以");   //此處沒(méi)要求
    }
}

六、模板方法模式的實(shí)現(xiàn)要點(diǎn):

Template Method模式是一種非常基礎(chǔ)性的設(shè)計(jì)模式,在面向?qū)ο笙到y(tǒng)中有著大量的應(yīng)用。它用最簡(jiǎn)潔的機(jī)制(虛函數(shù)的多態(tài)性)為很多應(yīng)用程序框架提供了靈活的擴(kuò)展,是代碼復(fù)用方面的基本實(shí)現(xiàn)結(jié)構(gòu)。除了可以靈活應(yīng)對(duì)子步驟的變化外,“Don't call me, let me call you(不要調(diào)用我,讓我來(lái)調(diào)用你)”的反向控制結(jié)構(gòu)是Template Method的典型應(yīng)用。

1、模板方法模式適用情形:

(1)、一次性實(shí)現(xiàn)一個(gè)算法的不變部分,并將可變的行為留給子類(lèi)來(lái)實(shí)現(xiàn)。
(2)、各子類(lèi)中公共的行為應(yīng)被提取出來(lái)并集中到一個(gè)公共父類(lèi)中以避免代碼重復(fù)。
(3)、控制子類(lèi)擴(kuò)展。模板方法只允許在特定點(diǎn)進(jìn)行擴(kuò)展,而模板部分則是穩(wěn)定的。

2、模板方法模式特點(diǎn):

(1)、TemplateMethod模式是一種非?;A(chǔ)性的設(shè)計(jì)模式,在面向?qū)ο笙到y(tǒng)中大量應(yīng)用。它用最簡(jiǎn)潔的機(jī)制(基礎(chǔ)、多態(tài))為很多應(yīng)用程序框架提供了靈活的擴(kuò)展點(diǎn),是代碼復(fù)用方面的基本實(shí)現(xiàn)結(jié)構(gòu)。
(2)、在具體實(shí)現(xiàn)方面,被TemplateMethod調(diào)用的虛方法可以具有實(shí)現(xiàn),也可以沒(méi)有任何實(shí)現(xiàn)(抽象方法或虛方法)。但一般推薦將它們?cè)O(shè)置為protected方法使得只有子類(lèi)可以訪問(wèn)它們。
(3)、模板方法模式通過(guò)對(duì)子類(lèi)的擴(kuò)展增加新的行為,符合“開(kāi)閉原則”。

七、.NET 中模板模式的實(shí)現(xiàn)

這種模式在控件設(shè)計(jì)中大量的用到,比如:控件有自己的生命周期,Page對(duì)象也有自己的生命周期,Application應(yīng)用對(duì)象也有自己的生命周期,這個(gè)生命周期里面的每個(gè)階段其實(shí)就是模板方法里面包含的每個(gè)步驟,這些階段步驟會(huì)被一個(gè)方法包含著,這個(gè)方法就是“模板方法”。讓我們?cè)僬f(shuō)說(shuō)控件吧,因?yàn)閷?xiě)好的控件,可能需要被開(kāi)發(fā)人員自定義,那么在控件里我們已經(jīng)定義好了控件呈現(xiàn)、動(dòng)作的骨架,但是有些自定義的需求,需要延遲到擴(kuò)展控件的開(kāi)發(fā)人員來(lái)決定。    
當(dāng)我們?cè)谧鯳indows應(yīng)用程序的時(shí)候,就會(huì)使用Windows控件,那Windows控件是如何顯示在Windows Form 上的呢,就需要一個(gè)OnPaint方法把控件畫(huà)出來(lái),這里OnPaint是一個(gè)虛方法的子步驟,這就是一個(gè)Template Method設(shè)計(jì)模式。如果我們不去重寫(xiě)這個(gè)OnPaint方法,它就有一個(gè)基本的默認(rèn)實(shí)現(xiàn),畫(huà)一個(gè)空窗體。這里我們并沒(méi)有調(diào)用OnPaint方法,而是Application的Run會(huì)進(jìn)入Windows的消息循環(huán)結(jié)構(gòu),Paint就是一個(gè)消息。當(dāng)我們移動(dòng)一下窗口都會(huì)導(dǎo)致Paint事件的發(fā)生,并導(dǎo)致OnPaint函數(shù)的調(diào)用,這就是一種反向調(diào)用。當(dāng)然,還有很多其他的子步驟可以提供擴(kuò)展點(diǎn),例如OnClose等,很多以O(shè)n開(kāi)頭的全部都是Template Method模式的虛方法。 這個(gè)里面內(nèi)容很復(fù)雜,它并不是用一個(gè)Template Method在里面調(diào)用所有的子步驟方法,它實(shí)際上是把整體的Template Method方法置于了一個(gè)消息循環(huán)的結(jié)構(gòu)里面,我們可以把消息循環(huán)的結(jié)構(gòu)看做模板方法里面的TemplateMethod公有非虛方法。

到此這篇關(guān)于.Net行為型設(shè)計(jì)模式之模板方法模式(Template Method)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論