比如我们要新加个模块功能,首先会新建一个action类,让它继承某个抽象类A,A就是这个模板,里面包含了抽象方法B和非抽象方法C,B就是一类比如增删改查的方法,C就是一类比较复杂业务的方法,因为C方法可能要调用B类的方法。子类将这些B方法实现并完成各自的逻辑,在最终实现复杂功能时,只需运用多态的方式创建子类对象,调用父类的C方法即可。
例如想实现一个附件校验的功能,那就需要先上传附件,同时对附件中的信息进行查询并校验,此时这个附件校验的功能就是C方法,上传附件功能和校验查询就是这类抽象方法B,不同的模块都需要上传附件校验,但附件内容和校验形式不一样,通过模板方法,只需将不同模块类实现这个模板,然后实现各自的上传附件以及校验查询的抽象方法,最终只需调用这个C方法即可。
推荐一个微信公众账号一起学习:快乐编程
10.1选择题不会做,蒙呗!
“小菜,今天面试的情况如何?”大鸟刚下班,回来就敲开了小菜的房门。
“唉!”小菜叹了口气,“书到用时方恨少呀,英语太烂,没办法。”
“是和你用英语对话还是让你做英语题目了?”
“要是英语对话.我可能马上就跟他们说拜拜了。是做编程的英语题,因为平时英语文章看得少。所以好多单词都是似曾相识,总之猜不出意思,造成我不得不瞎蒙。还好都是选择题,一百道题蒙起来也不算太困难。”
“小菜又在指望运气了。做完后他们怎么说?”
“还不是一样,说有意向会很快与我联系。所有的公司都这样,其实一百道选择题,马上就可以算出结果来的,又何必要我多跑一趟呢。”
“题目难不难?”
“其实题目还好,如果看得懂的话,应该大多是知道的,都是些编程的基础。主要是单词记不住,所以就没把握。”
“我记得六七年前,那时候很流行微软的MCSE和MCSD的认证考试。于是国内就出现了许多的培训机构,他们弄到了微软的考试题库,给出保证通过,不通过不收费的承诺。大学生们为了能找到好工作,都去参加这个培训。我听说有个哥们,不是计算机专业的,对软件开发也算基本不懂吧,但他英文特好,于是他参加了这个培训后,短短一个多月,靠着背答案,他竟然把MCSD的证书考出来了。一个几乎不会开发的人却考出了世界最大软件公司的开发技术认证,你感觉如何?”
“说明中国学生很聪明。”小菜笑道,“其实在美国,这个认证是很有权威性的,只是中国的学生太会考试了。这带来的后果就是毁了这个证书,不管哪家公司招到这个不会开发的人都会有上当的感觉,于是对微软证书彻底失望。”
“是呀,这其实就是标准化考试的弊端。不过标准化考试好处也不少,那就是比较客观,不管世界的哪个地方,大家做同类型的题目,得分超过一定数,就判定达到一定的能力,不会因为评卷人的主观判断而影响结果。像高考的作文,由于是主观题,其实就很难说得清是好还是不好。或许不同的人给分差距是会非常大的。”
“是的,我相信鲁迅参加高考,作文一定不会得高分的。明明要是纪念,却偏要说忘却。我要是写类似的语句,一定是完了。”
“哈,大师的作品当然不能在高考这个场合去评判,高考当中写另类作文等于找死。”大鸟感慨地说,“我回想我小时候,数学老师的随堂测验,都是在黑板上抄题目,要我们先抄题目,然后再做答案,我那时候眼睛己经开始不好了,所以有时没看清楚就会把题目抄错,比如数字3我看成了8, 7看成了1,那就意味着我做得再好,也不会正确了。惨呀,没考好,回家父母还说我考试成绩差是不认真学习,还专门找借口。”
“看来大鸟的往事不堪回首呀。”
“往事不要再提—你分析一下原因在哪里?”
“题目抄错了,那就不是考试题目了,而考试试卷最大的好处就是,大家都是一样的题目,特别是标准化的考试,比如全是选择或判断的题目,那就最大化地限制了答题者的发挥,大家都是ABCD或打勾打叉,非对即错的结果。”
“说得好,这其实就是一个典型的设计模式。不过为了讲解这个模式,你先把抄题目的程序写给我看看。”
“好的。”
10.2重复=易错+难改
二十分钟后,小菜上交了第一份作业。
代码结构图
//学生甲抄的试卷类 public class TestPaperA { public void testQuestion1() { System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] " + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维"); System.out.println("答案:b"); } public void testQuestion2() { System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 " + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化"); System.out.println("答案:a"); } public void testQuestion3() { System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] " + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对"); System.out.println("答案:c"); } } //学生乙抄的试卷类 public class TestPaperB { public void testQuestion1() { System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] " + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维"); System.out.println("答案:d"); } public void testQuestion2() { System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 " + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化"); System.out.println("答案:b"); } public void testQuestion3() { System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] " + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对"); System.out.println("答案:a"); } } //客户端代码 public class Main { public static void main(String[] args) { System.out.println("学生甲抄的试卷:"); TestPaperA studentA = new TestPaperA(); studentA.testQuestion1(); studentA.testQuestion2(); studentA.testQuestion3(); System.out.println("学生乙抄的试卷:"); TestPaperA studentB = new TestPaperA(); studentB.testQuestion1(); studentB.testQuestion2(); studentB.testQuestion3(); } }
10.3提炼代码
“大鸟,我自己都感觉到了,学生甲和学生乙两个抄试卷类非常类似,除了答案不同之外,没有什么不一样的,这样写又容易错,又难以维护。”
“说的对,如果老师突然要改题目呢,那两个人就都需要改代码了,如果某人抄错了,真是糟糕之极。那你说怎么办?”
“老师出一份试卷,打印多份,让学生填答案即可。在这里应该把试题和答案分离,抽象一个父类,让两个子类去继承它,公共的试题代码写到父类中,就可以了吧。”
“好的,写写看。”
十分钟后,小菜的第二份作业。
//试卷父类 public class TestPaper { public void testQuestion1() { System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] " + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维"); } public void testQuestion2() { System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 " + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化"); } public void testQuestion3() { System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] " + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对"); } } //学生甲抄的试卷 public class TestPaperA extends TestPaper { public void testQuestion1() { super.testQuestion1(); System.out.println("答案:b"); } public void testQuestion2() { super.testQuestion2(); System.out.println("答案:b"); } public void testQuestion3() { super.testQuestion3(); System.out.println("答案:b"); } } //学生乙抄的试卷 public class TestPaperB extends TestPaper { public void testQuestion1() { super.testQuestion1(); System.out.println("答案:b"); } public void testQuestion2() { super.testQuestion2(); System.out.println("答案:b"); } public void testQuestion3() { super.testQuestion3(); System.out.println("答案:b"); } } //客户端代码 public class Main { public static void main(String[] args) { System.out.println("学生甲抄的试卷:"); TestPaperA studentA = new TestPaperA(); studentA.testQuestion1(); studentA.testQuestion2(); studentA.testQuestion3(); System.out.println("学生乙抄的试卷:"); TestPaperA studentB = new TestPaperA(); studentB.testQuestion1(); studentB.testQuestion2(); studentB.testQuestion3(); } }
“大鸟,这下子类就简单了,只需要填写答案就可。”
“这还只是初步的泛化,你仔细看看,两个学生的类里面,还有没有类似的代码。”
“啊,感觉相同的东西还是有啊,比如都有super.testQuestion1()和System.out.println("答案:b"),我感觉除了选项的abcd,其他都是重复的。”
“说的好啊,我们既然用了继承,并且肯定这个继承是有意义的,就应该要成为子类的模板,所有重复的代码都怡颜悦色上升到父类去,而不是让每个子类都去重复。”
“那该如何做?我不知道了。”
“哈,模板方法登场了,当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。现在来研究研究我们最初的试题方法。”
public void testQuestion1() { System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] "+ "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维"); System.out.println("答案:b"); }
于是我们就改动这里,增加一个虚方法。
//试题父类 public class TestPaper { public void testQuestion1() { System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] " + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维"); System.out.println("答案:" + answer1()); } public void testQuestion2() { System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 " + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化"); System.out.println("答案:" + answer2()); } public void testQuestion3() { System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] " + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对"); System.out.println("答案:" + answer3()); } protected String answer1() { return ""; } protected String answer2() { return ""; } protected String answer3() { return ""; } } //学生甲抄试卷类 public class TestPaperA extends TestPaper { protected String answer1() { return "b"; } protected String answer2() { return "c"; } protected String answer3() { return "a"; } } //学生乙抄试卷类 public class TestPaperB extends TestPaper { protected String answer1() { return "c"; } protected String answer2() { return "a"; } protected String answer3() { return "a"; } } //客户端代码 public class Main { public static void main(String[] args) { System.out.println("学生甲抄的试卷:"); TestPaper studentA = new TestPaperA(); studentA.testQuestion1(); studentA.testQuestion2(); studentA.testQuestion3(); System.out.println("学生乙抄的试卷:"); TestPaper studentB = new TestPaperB(); studentB.testQuestion1(); studentB.testQuestion2(); studentB.testQuestion3(); } }
代码结构图
“子类就非常的简单了,重写虚方法后,把答案填上,其他什么都不用管。因为父类建立了所有重复的模板。客户端改动了一个小地方,即本来是子类变量的声明,改成了父类,这样就可以利用多态性实现代码的利用了。此时要有更多的学生来答试卷,只不过是在试卷的撒手人寰填写选择题的选项答案,这是每个人试卷唯一的不同。”
“大鸟太绝对了吧,还有姓名是不相同的。”
“哈,小菜说的对,除了题目答案外,每个人的姓名也是不相同的。但这样的做法的确是对试卷的最大复用。”
10.4模板方法模式
“而这其实就是典型的模板方法模式。”
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式(TemplateMethod)结构图
//AbstractClass是抽象类,其实也就是一抽象模板,定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。 public abstract class AbstractClass { public abstract void primitiveOperation1(); public abstract void primitiveOperation2(); public void templateMethod() { primitiveOperation1(); primitiveOperation2(); } } //ConcreteClass,实现父灰所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass与之相对应,而每一个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同,从而使得顶级逻辑的实现各不相同。 public class ConcreteClassA extends AbstractClass { @Override public void primitiveOperation1() { System.out.println("具体类A方法1实现"); } @Override public void primitiveOperation2() { System.out.println("具体类A方法2实现"); } } public class ConcreteClassB extends AbstractClass { @Override public void primitiveOperation1() { System.out.println("具体类B方法1实现"); } @Override public void primitiveOperation2() { System.out.println("具体类B方法2实现"); } } //客户端代码 public class Main { public static void main(String[] args) { AbstractClass c; c = new ConcreteClassA(); c.templateMethod(); c = new ConcreteClassB(); c.templateMethod(); } }
10.5模板方法模式特点
“大鸟,是不是可以这么说,模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。”
“对的,模板方法模式就是提供了一个很好的代码复用平台。因为有蚨,我们会遇到由一系列步骤构成的过程需要执行。这个过程从高层次上看是完全相同的,但有些步骤的实现可能会有不同。这个时候,我们通常就应该要考虑用模板方法模式了。”
“你的意思也就是说,碰到这个情况,当不变的和可变的行为在方法的子类实现中混合在一起时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。”
“总结的非常好,看来这省心的事你总是学得最快。”
“哪里哪里,这还不是大鸟教得好呀。”小菜也不忘谦虚两句,“不过老实讲,这模板方法实在不算难,我早就用过了,只不过以前不知道这也算是一个设计模式。”
“是呀,模板方法模式是很常用的模式,对继承和多态玩得好的人几乎都会在继承体系中多多少少用到它。比如在.NET或Java类库的设计中,通常都会利用模板方法模式提取类库中的公共行为到抽象类中。”
10.6主观题,看你怎么蒙
此时,小菜手机响了。
“请问是蔡遥先生吗?”手机那边一女士的声音。
“我是,请问您是?”小菜不认识这手机号。
“我是您今天面试的XX公司的人事经理。您今天在我们公司做的面试题,我们公司开发部非常满意,希望您能明天再到我们公司复试。”
“复试?还做选择题?”小菜有点心虚。
“哦,不是的,复试会是一些主观编程的题目,应该不是大问题的。地址您也知道,明天上午10点到吧,明天见。拜拜……嘟……嘟……”
“喂!喂!喂!”小菜喂了几声,知道对方己挂了电话,不得不放下手机,对大鸟说道,“大鸟,刚才还说选择题好,容易蒙,这下不好使了,人家要复试,还是做题,而且是主观编程题,要实实在在写代码了,不能靠猜选择题蒙了。”
“哈,看来模板方法玩不起来了。你就见招拆招吧,不就是做题吗,拿山我教你的‘伎俩’,好好表现。”
“嗯,主观题,难道我就不能蒙了?等我的好消息吧。”
转载于:http://damonshell.sinaapp.com/?p=147
相关推荐
JAVA-设计模式-行为型模式-模板方法模式
根据给定文件内容,以下是关于Java设计模式的知识点说明: 1. 策略模式(Strategy Pattern)是一种行为设计模式,允许在运行时选择算法的行为。策略模式的意图是定义一系列算法,将每个算法封装起来,并使它们可以...
模板方法模式是设计模式中行为型模式的一种,它在软件工程中扮演着非常重要的角色,尤其是在Java编程中。模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。它允许子类不改变一个算法的结构即可重...
模板模式是一种行为设计模式,它在面向对象编程中扮演着重要的角色。此模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。这样,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤...
Java设计模式是软件开发中的一种最佳实践,它总结了在解决特定问题时程序员们经常采用的有效方法。这个“JAVA设计模式-chm版”资源显然包含了关于Java设计模式的详细信息,便于理解和应用。设计模式是对常见问题的...
Java设计模式是软件工程中的一种重要思想,它总结了在解决特定问题时,程序员们反复使用的一些最佳实践和解决方案。这个资源"Java设计模式----通俗易懂版"显然是一个专门针对初学者或需要深入理解设计模式的开发者...
今天,我们将讨论两种常用的Java设计模式:状态模式和模板模式。 状态模式(State Pattern) --------------------- 状态模式是一种行为型设计模式,它允许对象在内部状态改变时改变它的行为。状态模式将状态封装...
### Java设计模式详解 #### 创建型模式 **1.1 工厂方法(Factory Method)** 工厂方法模式定义了一个创建对象的接口,但允许子类决定实例化哪一个类。这使得一个类的实例化可以被推迟到其子类。这种模式在以下...
### Java设计模式的应用 #### 一、引言 在当今快速发展的软件开发领域,Java作为一门功能强大且灵活的语言,不仅拥有丰富的API资源,还能与强大的数据库系统无缝对接。这使得许多开发人员能够以模块化的形式构建...
JAVA设计模式是编程领域中非常重要的概念,它为软件开发人员提供了在特定情境下解决常见问题的模板。设计模式公司出品的《JAVA设计模式》书籍,详细介绍了多种设计模式,适合不同水平的程序员学习和使用。 首先,...
设计模式通常分为三类:创建型模式(如工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式),结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式、享元模式)以及行为型模式(如...
这篇名为"JAVA设计模式---100%推荐"的资源,可能是对Java设计模式的深入解析,旨在帮助开发者更好地理解和应用这些模式。 设计模式通常分为三类:创建型、结构型和行为型。创建型模式涉及对象的实例化过程,如单例...
本资源主要介绍了JAVA设计模式的原则和23种设计模式的总结。设计模式是软件设计中的一种解决方案,能够使软件系统更加灵活、可维护和可扩展。本资源首先介绍了设计模式的六大原则,包括单一责任原则、开闭原则、里氏...
《Java与模式》是阎宏博士的一本经典著作,它深入浅出地介绍了如何在Java编程中应用设计模式。这本书不仅讲解了设计模式的基本概念,还涵盖了23种经典的GOF设计模式,并结合Java语言特性进行了详细的解释和实例演示...
在Java中,模板模式通常使用抽象类来定义模板方法,这个方法由一系列基本操作组成,这些操作在模板类中可能是抽象的或已经实现了的。子类通过重写这些抽象方法,为算法的具体步骤提供实现。这种设计模式遵循“开闭...
Java设计模式是软件工程中的一种重要思想,它代表了在解决特定问题时的最佳实践。这些模式都是经过时间和经验验证的设计解决方案,可以提高代码的可读性、可维护性和复用性。Java设计模式主要分为三类:创建型模式、...
在软件工程中,设计模式是一种被广泛接受的解决特定设计问题的...因此,深入学习和理解Java设计模式对于任何Java开发者来说都是至关重要的。通过文档中的图解和代码示例,读者可以更好地理解和掌握这些模式的实际应用。
在Java中,好奇递归模板模式(CRTP)是一种强大的设计模式,用于实现静态多态性。通过让一个类模板从其自身类的模板实例化中派生,CRTP能够实现方法重写和编译时的多态行为,提高Java应用程序的效率和性能。 ## 二...
### 设计模式之模板方法模式解析 #### 一、引言 在软件开发过程中,我们经常面临这样的场景:有一些步骤是固定的,而某些步骤则可能因具体实现而异。为了解决这类问题,设计模式中引入了一种叫做“模板方法模式”的...
**Java设计模式——入门** 设计模式是软件开发中的一种最佳实践,它是在特定上下文中解决常见问题的经验总结。Java设计模式是面向对象编程中的一个重要概念,可以帮助开发者编写可复用、可维护、易于理解的代码。这...