大话设计模式之模板方法模式(Darren)

来源:互联网 发布:win10系统java环境变量 编辑:程序博客网 时间:2024/05/18 02:12

大家晚上好,又在每天的这个时候和大家分享学习成果了:

之前我写了:简单工厂模式,策略模式,单一职责原则,开放封闭原则,依赖倒转原则,装饰模式,代理模式,抽象工厂模式,原型模式,今天来讲一下设计模式之模板方法模式.

在编程过程中也许大家都会遇到重复的代码,然而重复对于我们来说就是:

重复=易错+难改,而模板方法模式就是帮助我们去减少这些重复的代码。

为了更好的了解模板方法模式

先看看我写的一个事例   模拟学员考试答题

 /// <summary>    /// 考试试题类    /// </summary>    public class TestPaper    {        public void TestPaper1()        {            Console.WriteLine("三国出现在那个朝代之后【】A汉   B唐   C隋   D晋");        }        public void TestPaper2()        {            Console.WriteLine("西游记是谁的作品?【】A罗贯中   B施耐庵   C曹雪芹  D韩寒");        }        public void TestPaper3()        {            Console.WriteLine("汉朝重建都到覆灭,经历的多少年?【】  A1000  B500  C400  D300");        }    }    /// <summary>    /// 具体的学生A答题    /// </summary>    public class TestPaperA : TestPaper    {               public new void TestPaper1()        {            base.TestPaper1();            Console.WriteLine("答案A");        }        public new void TestPaper2()        {            base.TestPaper2();            Console.WriteLine("答案b");        }        public new void TestPaper3()        {            base.TestPaper3();            Console.WriteLine("答案c");        }    }    /// <summary>    /// 具体学生B答题    /// </summary>    public class TestPaperB : TestPaper    {        public new void TestPaper1()        {            base.TestPaper1();            Console.WriteLine("答案c");        }        public new void TestPaper2()        {            base.TestPaper2();            Console.WriteLine("答案b");        }        public new void TestPaper3()        {            base.TestPaper3();            Console.WriteLine("答案d");        }    }

 

分发段收费方式

既然上面我们用了继承,并且肯定了这个继承有意义,就应该要成为子类的模板,所有的重复代码都应该上升到父类中去,而不是让每个子类都去重复。

这几个类大家一看都知道是做什么的,貌似用了继承就感觉不错了,但是仔细看一下TestPaperA和TestPaperB两个类,还是有很多的冗余代码,比如base.T.....,Console.WriteLine("答案:");

当我们要完成在某一个细节层次一致的一个过程或者一系列的步骤,但其个别步骤在其更详细的层次上不同时,我们通常考虑用模板方法来处理

我们可以通过模板方法来达到更进一步的优化

 

 /// <summary>    /// 考试试题类    /// </summary>    public class TestPaper    {        public void TestPaper1()        {            Console.WriteLine("三国出现在那个朝代之后【】A汉   B唐   C隋   D晋");            Console.WriteLine("答案:" + Answer1());        }        public virtual string Answer1()        {            return "";        }        public void TestPaper2()        {            Console.WriteLine("西游记是谁的作品?【】A罗贯中   B施耐庵   C曹雪芹  D韩寒");            Console.WriteLine("答案:" + Answer2());        }        public virtual string Answer2()        {            return "";        }        public virtual string Answer3()        {            return "";        }        public void TestPaper3()        {            Console.WriteLine("汉朝重建都到覆灭,经历的多少年?【】  A1000  B500  C400  D300");            Console.WriteLine("答案:" + Answer3());        }    }    /// <summary>    /// 具体的学生A答题    /// </summary>    public class TestPaperA : TestPaper    {        public override string Answer1()        {            return "A";        }        public override string Answer2()        {            return "B";        }        public override string Answer3()        {            return "C";        }    }    /// <summary>    /// 具体学生B答题    /// </summary>    public class TestPaperB : TestPaper    {        public override string Answer1()        {            return "B";        }        public override string Answer2()        {            return "D";        }        public override string Answer3()        {            return "C";        }    }


 

代码结构图

和上一次代码比较,这一次有很大的改进吧,几乎没有冗余代码:

下面介绍一下模板方法模式:

定义

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

模板方法结构图

 

模板方法的特点:

把不变行为搬移到超类,去除子类中的代码来体现其优势。模板方法其实就是提供了一个很好的代码复用平台。

 

当不变和可变的行为在子类的实现中混合在一起的时候,不变的行为就会在子类中重复出现,我们通过模板方法模式将这些不变的行为搬移到一个单独的地方,这样就帮助子类摆脱了重复的不变行为的纠缠。

 

 

哎呀呀呀...终于完了,体力不支了,洗洗睡了。www.tianboo.net

原创粉丝点击