1. 程式人生 > >C#/.NET 模板模式——兩個例項程式碼

C#/.NET 模板模式——兩個例項程式碼

C# 模板模式——兩個例項程式碼

在模板模式(Template Pattern)中,一個抽象類公開定義了執行它的方法的方式/模板。它的子類可以按需要重寫方法實現,但呼叫將以抽象類中定義的方式進行。這種型別的設計模式屬於行為型模式。


介紹

**意圖:**定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

**主要解決:**一些方法通用,卻在每一個子類都重新寫了這一方法。

**何時使用:**有一些通用的方法。

**如何解決:**將這些通用演算法抽象出來。

**關鍵程式碼:**在抽象類實現,其他步驟在子類實現。

**應用例項: **
1、在造房子的時候,地基、走線、水管都一樣,只有在建築的後期才有加壁櫥加柵欄等差異。
2、西遊記裡面菩薩定好的 81 難,這就是一個頂層的邏輯骨架。
3、spring 中對 Hibernate 的支援,將一些已經定好的方法封裝起來,比如開啟事務、獲取 Session、關閉 Session 等,程式設計師不重複寫那些已經規範好的程式碼,直接丟一個實體就可以儲存。

優點:
1、封裝不變部分,擴充套件可變部分。
2、提取公共程式碼,便於維護。
3、行為由父類控制,子類實現。

**缺點:**每一個不同的實現都需要一個子類來實現,導致類的個數增加,使得系統更加龐大。

使用場景:


1、有多個子類共有的方法,且邏輯相同。
2、重要的、複雜的方法,可以考慮作為模板方法。

實現

我們將建立一個定義操作的 Game 抽象類,其中,模板方法不能被重寫。Cricket 和 Football 是擴充套件了 Game 的實體類,它們重寫了抽象類的方法。

namespace 模板模式
{
    /// <summary>
    /// 步驟 1
    ///建立一個抽象類,它的模板方法不能被重寫。
    /// </summary>
    public abstract class Game
    {
        public abstract void initialize();
        public abstract void startPlay();
        public abstract void endPlay();

        //模板
        public void play()
        {

            //初始化遊戲
            initialize();

            //開始遊戲
            startPlay();

            //結束遊戲
            endPlay();
        }
    }
    /// <summary>
    /// 步驟 2
    ///建立擴充套件了上述類的實體類
    /// </summary>
    public class Cricket : Game
    {
        public override void endPlay() {
            Console.WriteLine("Cricket Game Finished!");
        }

        public override void initialize() {
            Console.WriteLine("Cricket Game Initialized! Start playing.");
        }

        public override void startPlay() {
            Console.WriteLine("Cricket Game Started. Enjoy the game!");
        }
    }

    public class Football : Game
    {
        public override void endPlay()
        {
            Console.WriteLine("Football Game Finished!");
        }

        public override void initialize()
        {
            Console.WriteLine("Football Game Initialized! Start playing.");
        }

        public override void startPlay()
        {
            Console.WriteLine("Football Game Started. Enjoy the game!");
        }
    }

    /// <summary>
    /// 步驟 3
    ///使用 Game 的模板方法 play() 來演示遊戲的定義方式。
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Cricket();
            game.play();
            Console.WriteLine("");
            game = new Football();
            game.play();
            Console.ReadKey();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TemplateMethodPattern
{
    /// <summary>
    /// 1  抽象方法/虛方法/普通方法
    /// 2  模板方法設計模式
    /// 3  鉤子方法
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("歡迎來到.net高階班公開課之設計模式特訓,今天是Eleven老師為大家帶來的模板方法模式");
                //MethodTest.Show();

                //Client client = new Client();
                //client.Query(387, "天道無情", "123456");
                {
                    Client client = new ClientCurrent();
                    client.Query(387, "天道無情", "123456");
                }
                {
                    Client client = new ClientRegular();
                    client.Query(448, "一點半", "000000");
                }
                {
                    Client client = new ClientVip();
                    client.Query(259, "Gain", "251146");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
    /// <summary>
    /// 銀行客戶端
    /// </summary>
    public abstract class Client
    {
        public void Query(int id, string name, string password)
        {
            if (this.CheckUser(id, password))
            {
                double balance = this.QueryBalance(id);
                double interest = this.CalculateInterest(balance);
                this.Show(name, balance, interest);
            }
            else
            {
                Console.WriteLine("賬戶密碼錯誤");
            }
        }

        public bool CheckUser(int id, string password)
        {
            return DateTime.Now < DateTime.Now.AddDays(1);
        }

        public double QueryBalance(int id)
        {
            return new Random().Next(10000, 1000000);
        }

        /// <summary>
        /// 活期  定期  利率不同
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public abstract double CalculateInterest(double balance);

        public virtual void Show(string name, double balance, double interest)
        {
            Console.WriteLine("尊敬的{0}客戶,你的賬戶餘額為:{1},利息為{2}",
                name, balance, interest);
        }
        //private void Show(string name, double balance, double interest)
        //{
        //    Console.WriteLine("尊貴的{0} vip客戶,您的賬戶餘額為:{1},利息為{2}",
        //        name, balance, interest);
        //}

    }
	/// <summary>
	/// VIP
	/// </summary>
	public class ClientVip : Client
	{
	    /// <summary>
	    /// 活期  定期  利率不同
	    /// </summary>
	    /// <param name="balance"></param>
	    /// <returns></returns>
	    public override double CalculateInterest(double balance)
	    {
	        return balance * 0.005;
	    }
	
	    public override void Show(string name, double balance, double interest)
	    {
	        Console.WriteLine("尊貴的{0} vip客戶,您的賬戶餘額為:{1},利息為{2}",
	            name, balance, interest);
	    }
	}
    public class ClientRegular : Client
    {
        /// <summary>
        /// 活期  定期  利率不同
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public override double CalculateInterest(double balance)
        {
            return balance * 0.003;
        }
    }

}