模板模式(Template Pattern)

来源:互联网 发布:德力西插排怎么样知乎 编辑:程序博客网 时间:2024/06/05 21:53

模板模式:别给我打电话,我会打给你。


场景:使用模板模式实现泡茶和冲咖啡的两个类似行为。


//抽象基类作为模板

    //以作为咖啡因饮品作为茶与咖啡的泛化类    public abstract class CaffeineBeverage    {        //提供唯一的准备饮品的方法        public void prepareRecipe()        {            //流程模板:烧水,冲泡,入杯,加调料            boilWater();            brew();            pourInCup();            if (customerWantsCondiments())            {                addCondiments();            }        }        //抽象方法:冲泡        protected abstract void brew();         //抽象方法:加调料        protected abstract void addCondiments();        //公共方法:将水烧沸腾        void boilWater()        {            Console.WriteLine("将水烧至沸腾");        }        //公共方法:将饮料导入杯中        void pourInCup()        {            Console.WriteLine("将饮料导入杯中");        }        //钩子方法:用户是否想加入调料        protected virtual bool customerWantsCondiments()        {            return true;        }    }

//实现模板的具体类

    public class Coffee:CaffeineBeverage    {        protected override void brew()        {            Console.WriteLine("倒入速溶咖啡粉末,并搅拌");        }        protected override void addCondiments()        {            Console.WriteLine("加入奶精和方块糖");        }        //钩子函数实现:子类实现但仍然由父类去调用,而不是调用父类        protected override bool customerWantsCondiments()        {            string answer = getUserInput();            if (answer.Equals("y"))            {                return true;            }            else            {                return false;            }        }        private string getUserInput()        {            string answer = null;            Console.Write("您是否需要加入奶精和方块糖(y/n)?");            answer = Console.ReadLine();            return answer;        }    }

    public class Tea : CaffeineBeverage    {        protected override void brew()        {            Console.WriteLine("倒入茶叶,浸泡");        }        protected override void addCondiments()        {            Console.WriteLine("加入柠檬");        }        protected override bool customerWantsCondiments()        {            string answer = getUserInput();            if (answer.Equals("y"))            {                return true;            }            else            {                return false;            }        }        private string getUserInput()        {            string answer = null;            Console.Write("您是否需要加入柠檬(y/n)?");            answer = Console.ReadLine();            return answer;        }    }

测试用例:

        static void Main(string[] args)        {            CaffeineBeverage cafferneBeverage = null;            while (true)            {                Console.WriteLine("您需要一些咖啡因饮品,请选择具体饮品,按回车键确认:");                Console.WriteLine("1.一杯咖啡");                Console.WriteLine("2.一杯茶");                string answer = Console.ReadLine();                if (answer.Equals("1"))                {                    cafferneBeverage = new Coffee();                }                else if (answer.Equals("2"))                {                    cafferneBeverage = new Tea();                }                else                {                    return;                }                             cafferneBeverage.prepareRecipe();                Console.WriteLine("按您的要求,准备好了饮品!!\n");            }        }
测试结果:


总结:

1.“模板方法”定义了算法的步骤,把这些步骤的实现延迟到子类。

2.模板方法模式为我们提供了一种代码复用的重要技巧。

3.模板方法的抽象类可以定义具体方法、抽象方法和钩子。

4.抽象方法由子类实现。

5.钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。

6.好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。

7.你将在真实世界代码中看到模块方法模式的许多变体,不要期待他们全都是一眼就可以被你认出的。(如LIST的sort方法)

8.策略模式和模板方法模式都封装算法,一个用组合,一个用继承。

9.工厂方法是模板方法的一种特殊版本。

0 0
原创粉丝点击