模板方法模式

1.定义

Define the sleleton 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.(定义一个操作中的算法的框架,而将一些具体的步骤延迟至子类中。使得子类可以不改变一个算法结构即可重定义该算法的某些特定步骤。)

模板方法模式非常简单,仅仅使用了.NET的继承机制,但它是一个应用非常广泛的模式。

2.代码实现

    abstract class AbstractClass
    {
        /// <summary>
        /// 基本方法,由子类实现
        /// </summary>
        protected abstract void DoSomeThing();

        protected abstract void DoAnyThing();

        /// <summary>
        /// 模板方法
        /// </summary>
        public void TemplateMethod()
        {
            DoSomeThing();

            DoAnyThing();
        }
    }


    class ConcreteClass1 : AbstractClass
    {
        protected override void DoSomeThing()
        {
            Console.WriteLine("ConcreteClass1 DoSomeThing");
        }

        protected override void DoAnyThing()
        {
            Console.WriteLine("ConcreteClass1 DoAnyThing");
        }
    }

    class ConcreteClass2 : AbstractClass
    {
        protected override void DoSomeThing()
        {
            Console.WriteLine("ConcreteClass2 DoSomeThing");
        }

        protected override void DoAnyThing()
        {
            Console.WriteLine("ConcreteClass2 DoAnyThing");
        }
    }

3.模板方法模式的优点

(1)封装不变部分,扩展可变部分

把认为是不变部分的算法封装到父类实现,而可变部分的则可以通过继承来继续扩展。

(2)提取公共部分代码,便于维护

(3)行为由父类控制,子类实现

4.钩子方法模板方法模式

也就是说外界条件改变,影响到模板方法的执行,由子类的一个方法返回值决定公共部分的执行结果。用文字不太好表达,直接用代码描述会更加容易理解。

    abstract class AbstractClass
    {
        /// <summary>
        /// 基本方法,由子类实现
        /// </summary>
        protected abstract void DoSomeThing();

        protected abstract void DoAnyThing();

        protected abstract bool IsRunAnyThing();
       
        /// <summary>
        /// 模板方法
        /// </summary>
        public void TemplateMethod()
        {
            DoSomeThing();

            if (IsRunAnyThing())
            {
                DoAnyThing();
            }
        }
    }

    class ConcreteClass1 : AbstractClass
    {
        protected override void DoSomeThing()
        {
            Console.WriteLine("ConcreteClass1 DoSomeThing");
        }

        protected override void DoAnyThing()
        {
            Console.WriteLine("ConcreteClass1 DoAnyThing");
        }

        protected override bool IsRunAnyThing()
        {
            return true;
        }
    }

    class ConcreteClass2 : AbstractClass
    {
        protected override void DoSomeThing()
        {
            Console.WriteLine("ConcreteClass2 DoSomeThing");
        }

        protected override void DoAnyThing()
        {
            Console.WriteLine("ConcreteClass2 DoAnyThing");
        }

        protected override bool IsRunAnyThing()
        {
            return false;
        }
    }