大話設計模式之模板方法模式(摘錄)

一、輝煌工程——製造悍馬

週三,9:00,我剛剛坐到位置上,打開電腦準備開始幹活。算法

 

     「小三,小三,叫一下其餘同事,到會議室,開會」,老大跑過來吼,帶着壞笑。還沒等你們坐穩,老大就開講了:架構

 

     「告訴你們一個好消息,昨天終於把牛叉模型公司的口子打開了,要咱們作悍馬模型,雖然是第一個車輛模型,可是咱們有能力、有信心作好,咱們必定要……(中間省略20分鐘的講話,若是你聽過領導人的講話,這個你應該可以續上)」ide

 

動員工做作完了,那就開始壓任務了。「此次時間是很是緊張的,只有一個星期的時間,小三,你負責在一個星期的時間把這批10萬車模(注:車模是車輛模型的意思,不是香車美女那個車模)建設完成…」測試

 

     「一個星期?這個……是真作不完,要作分析,作模板,作測試,還要考慮擴展性、穩定性、健壯性等,時間實在是太少了」還沒等老大說完,我就急了,再不急個人小命就折在上面了!this

 

     「那這樣,只作最基本的實現,不考慮太多的問題,怎麼樣?」老大又把我彈回去了。spa

 

     「只做基本實現?那……」設計

 

     唉,領導已經佈置任務了,那就開始死命地作吧,命苦不能怨政府,點背不能怪社會呀!而後就開始準備動手作,在作以前先介紹一下咱們公司的背景,咱們公司是作模型生產的,作過橋樑模型、建築模型、機械模型,甚至是一些政府、軍事的機密模型,這個不能細說,絕密。公司的主要業務就是把實物按照必定的比例縮小或放大,用於試驗、分析、量化或者是銷售,等等,上面提到的牛叉模型公司專門銷售車輛模型的公司,本身沒有生產企業,所有是代工。咱們公司是第一次從牛叉模型公司接單,那我怎麼着也要把活幹好,可時間有限,任務量又巨大,怎麼辦?code

 

     既然領導都說了,不考慮擴展性,那好辦,先按照最通常的經驗設計類圖,如圖1-1所示blog

圖1-1 悍馬車模型最通常的類圖繼承

 很是簡單的實現,悍馬車有兩個型號,H1和H2,按照需求,只須要悍馬模型,那好我就給你悍馬模型,先寫個抽象類,而後兩個不一樣型號的模型實現類,經過簡單的繼承就能夠實現業務要求。咱們先從抽象類編寫起,抽象悍馬模型如代碼清單10-1所示。

代碼清單1-1 抽象悍馬模型

public abstract class HanmaModel
    {
        public abstract void start();
        public abstract void alarm();
        public abstract void enginStart();
        public abstract void run();
    }
View Code

  在抽象類中,咱們定義了悍馬模型都必須具備的特質:可以啓動、中止,喇叭會響,引擎能夠轟鳴,並且還能夠中止,可是每一個型號的悍馬實現是不一樣的,H1型號的悍馬如代碼清單1-2所示。

代碼清單1-2 H1型號悍馬模型

public class HanmaH1Model : HanmaModel
    {
        public override void start()
        {
            Console.WriteLine("悍馬H1啓動!");
        }
        public override void alarm()
        {
            Console.WriteLine("悍馬H1鳴笛!");
        }
        public override void enginStart()
        {
            Console.WriteLine("悍馬H1發動機發出聲音!");
        }
        public override void stop()
        {
            Console.WriteLine("悍馬H1中止!");
        }
        public override void run()
        {
            this.start();
            this.alarm();
            this.enginStart();
            this.stop();
        }
    }
View Code

你們注意看run()方法,這是一個彙總的方法,一個模型生產成功了,總要拿給客戶檢測吧,怎麼檢測,「是騾子是馬,拉出去溜溜」,這就是一種檢驗方法,讓它跑起來!經過run()這樣的方法,把模型的全部功能都測試到了。

     H2型號悍馬如代碼清單1-3所示。

代碼清單1-3 H2型號悍馬模型

public class HanmaH2Mode:HanmaModel
    {
            public override void start()
            {
                Console.WriteLine("悍馬H2啓動!");
            }
            public override void alarm()
            {
                Console.WriteLine("悍馬H2鳴笛!");
            }
            public override void enginStart()
            {
                Console.WriteLine("悍馬H2發動機發出聲音!");
            }
            public override void stop()
            {
                Console.WriteLine("悍馬H2中止!");
            }
            public override void run()
            {
                this.start();
                this.alarm();
                this.enginStart();
                this.stop();
            }
    }
View Code

    好了,程序編寫到這裏,已經發現問題了,兩個實現類的run()方法都是徹底相同的,那這個run()方法的實現應該出如今抽象類,不該該在實現類上,抽象是全部子類的共性封裝。

     注意 在軟件開發過程當中,若是相同的一段代碼拷貝過兩次,就須要對設計產生懷疑,架構師要明確的說明爲何相同的邏輯要出現兩次或更屢次。

     好,問題發現了,咱們就須要立刻更改,修改後的類圖如圖1-2所示。

圖1-2 修正後的悍馬車模類圖

     注意抽象類HummerModel中的run()方法,由抽象方法變動爲實現方法,其源代碼如代碼清單10-4所示。

代碼清單1-4 修正後的抽象悍馬模型

public abstract class HanmaModel
    {
        public abstract void start();
        public abstract void alarm();
        public abstract void enginStart();
        public abstract void stop();
        public void run()
        {
            this.start();
            this.alarm();
            this.enginStart();
            this.stop();
        }
    }
View Code

在抽象的悍馬模型上已經定義了run方法的執行規則,先啓動,而後引擎馬上轟鳴,中間還要按一下喇叭,製造點噪聲(要不就不是名車了),而後停車,它的兩個具體實現類就不須要實現run方法了,只要把代碼清單1-二、1-3上的run()方法刪除便可,再也不贅述代碼。

public class HanmaH2:HanmaModel
    {
        public override void start()
        {
            Console.WriteLine("悍馬H2啓動!");
        }
        public override void alarm()
        {
            Console.WriteLine("悍馬H2鳴笛!");
        }
        public override void enginStart()
        {
            Console.WriteLine("悍馬H2發動機發出聲音!");
        }
        public override void stop()
        {
            Console.WriteLine("悍馬H2中止!");
        }
    }
public class HanmaH1:HanmaModel
    {
        public override void start()
        {
            Console.WriteLine("悍馬H1啓動!");
        }
        public override void alarm()
        {
            Console.WriteLine("悍馬H1鳴笛!");
        }
        public override void enginStart()
        {
            Console.WriteLine("悍馬H1發動機發出聲音!");
        }
        public override void stop()
        {
            Console.WriteLine("悍馬H1中止!");
        }
    }
View Code

     場景類實現的任務就是把生產出的模型展示給客戶,其源代碼如代碼清單10-5所示。

代碼清單1-5 場景類

class Program
    {
        static void Main(string[] args)
        {
            HanmaH1 h1 =new HanmaH1();
            h1.run();
            HanmaH2 h2 = new HanmaH2();
            h2.run();
            Console.ReadLine();
        }
    }
View Code

1.2 模板方法模式的定義

模板方法模式(Template Method Pattern)是如此的easy,以至讓你感受你已經可以掌握其精髓了。其定義以下:

     Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure。定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。

     模板方法模式的通用類圖如圖1-3所示。

圖1-3 修正後的悍馬車模類圖

     模板方法模式確實很是簡單,僅僅使用了Java的繼承機制,可是它是一個應用很是普遍的模式。其中,AbstractClass叫作抽象模板,它的方法分爲兩類:

  • 基本方法

     基本方法也叫作基本操做,是由子類實現的方法,而且在模板方法被調用。

  • 模板方法

     能夠有一個或幾個,通常是一個具體方法,也就是一個骨架,實現對基本方法的調度,完成固定的邏輯。

     注意爲了防止惡意的操做,通常模板方法都加上final關鍵字,不容許被覆寫。

相關文章
相關標籤/搜索