首页 > 代码库 > 设计模式------模板方法模式

设计模式------模板方法模式

模板方法模式定义了一个操作中的算法的骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

结构图:


AbstractClass是抽象模板,定义并实现一个模板方法,这个模板方法一般是一个具体方法,它给出一个顶级逻辑的骨架。

ConcreteClass是具体模板,实现父类所定义的一个或多个抽象方法,每一个AbstractClass可以有任意多个ConcreteClass,每一个ConcreteClass都可以给出顶级逻辑的组成步骤。

上面说得比较官方,下面我们通过一个具体的例子来理解一下。


大家都经历了无数次的考试,对这个我们都不太喜欢的过程也很清楚。首先由出题老师选好考题,然后整理成一套试卷(一个word)。

一.      选择题(每题一分,共10分)

1.      复制的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+L d.ctrl+D

答案: 

2.      全选的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+L d.ctrl+D

答案: 

3.      粘贴的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+V d.ctrl+D

答案:

 ……

这套试卷就是一个抽象模板,它给出试卷的骨架,考生试卷之间相同的部分都包含到这部分中。然后用它去打印n多份试卷,发给每个同学,所以大家的试题和卷头都是一样的,来自于一个模板。试卷是用来考试的,需要填写答案。由于考生给出的答案不尽相同,编码时把答题写成一个虚方法Answer,让继承它的子类去重写。

我们拿到试卷后,就开始埋头苦“做”,在答题位置写上自己的答案,其实就是重写Answer,给出抽象方法的不同实现。考试时间到,监考老师收起考生的试卷。考生的试卷就是具体模板,继承抽象模板。

学生甲的试卷:

一.          选择题(每题一分,共10分)

1.      复制的快捷键是a.ctrl+A  b.ctrl+C  c.ctrl+L d.ctrl+D

答案:b 

2.      全选的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+L d.ctrl+D

答案:c 

3.      粘贴的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+V d.ctrl+D

答案:c

    ……

学生乙的试卷:

一.          选择题(每题一分,共10分)

1.      复制的快捷键是a.ctrl+A  b.ctrl+C  c.ctrl+L d.ctrl+D

答案:b 

2.      全选的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+L d.ctrl+D

答案:c 

3.      粘贴的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+V d.ctrl+D

答案:a

    ……

分析了半天,接下来展示代码。

class TestPaper
        {
            public void TestQuestion1()
            {
                Console.WriteLine("\n复制的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+L  d.ctrl+D");
                Console.WriteLine("答案:" + Answer1());
            }
           
            public void TestQuestion2()
            {
                Console.WriteLine("\n全选的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+L  d.ctrl+D");
                Console.WriteLine("答案:" + Answer2());
            }
           
            public void TestQuestion3()
            {
                Console.WriteLine("\n粘贴的快捷键是【】a.ctrl+A  b.ctrl+C  c.ctrl+V  d.ctrl+D");
                Console.WriteLine("答案:" + Answer3());
            }
            protected virtual string Answer1()
            {
                return "";
            }

            protected virtual string Answer2()
            {
                return "";
            }

            protected virtual string Answer3()
            {
                return "";
            }
        }
        //学生甲的试卷
        class TestPaperA:TestPaper
        {
            protected override string Answer1()
            {
                return "b";
            }
            protected override string Answer2()
            {
                return "c";
            }
            protected override string Answer3()
            {
                return "c";
            }
        }
        //学生乙的试卷
        class TestPaperB : TestPaper
        {
            protected override string Answer1()
            {
                return "b";
            }
            protected override string Answer2()
            {
                return "c";
            }
            protected override string Answer3()
            {
                return "a";
            }
        }

客户端:

static void Main(string[] args)
        {
            Console.WriteLine("\n学生甲抄的试卷:");
            TestPaper studentA = new TestPaperA();
            studentA.TestQuestion1();
            studentA.TestQuestion2();
            studentA.TestQuestion3();

            Console.WriteLine("\n学生乙抄的试卷:");
            TestPaper studentB = new TestPaperB();
            studentB.TestQuestion1();
            studentB.TestQuestion2();
            studentB.TestQuestion3();
        }

显示:


最后我们小结一下。纵观上面的小例子,就是有一个过程需要执行,这个过程包括一系列步骤,整个过程从高层次看是一样的,但是每个步骤的具体细节不一样。模板方法模式就是把不变的搬到超类中,从而去除子类中的重复代码,提供一个代码复用平台。在软件公司中,一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法;而将这些基本法方法总汇起来的方法叫做模版方法。