版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37415950/article/details/81043213
1 简介
定义一个模板结构,将具体内容延迟到子类去实现。它主要作用:在不改变模板结构的前提下在子类中重新定义模板中的内容。
主要两点
1 提高代码复用性
将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中
2 实现了反向控制
通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 & 符合“开闭原则”
实例:
我们试卷现在都是,试题和答卷是分开的,因为试题我们都是一样的,而我们的答案就各自有各自的答案
UML
对他非常简单,主要就是通过继承实现。
代码:
package com.sl.demo.templet;
/**
* 题目模型
* 现在有三道选择题
* @author pengkun
*
*/
public abstract class Questions {
//名字(不管试卷还是答题卡都会有名字)
private String name;
public void setName(String name) {
this.name = name;
}
//三道题目
private void createQuestions1() {
System.out.println("面向对象的特性不包括? A封装 B继承 C多态 D消息通信");
}
private void createQuestions2() {
System.out.println("<大话设计模式>这本书的作者是谁? A张三 B李四 C程杰 D都不是");
}
private void createQuestions3() {
System.out.println("<this girl>这首歌是被哪个人唱到收费的? A一个小学生 B一个初中生 C一个高中生 D一个大学生");
}
//开始出题了(final:防止被覆盖 模板方法 )
final public void run() {
System.out.println("姓名:"+this.name);
this.createQuestions1();
System.out.println(getAnswer1());
this.createQuestions2();
System.out.println(getAnswer2());
this.createQuestions3();
System.out.println(getAnswer3());
}
//1题答案(默认没填)
protected String getAnswer1() {
return "";
}
//2题答案(默认没填)
protected String getAnswer2() {
return "";
}
//3题答案(默认没填)
protected String getAnswer3() {
return "";
}
}
package com.sl.demo.templet;
/**
* 学生答题卡
* @author pengkun
*
*/
public class AnswerCard extends Questions {
//答题卡三道题答案
private String Answer1;
private String Answer2;
private String Answer3;
public void setAnswer1(String answer1) {
Answer1 = answer1;
}
public void setAnswer2(String answer2) {
Answer2 = answer2;
}
public void setAnswer3(String answer3) {
Answer3 = answer3;
}
//覆盖父类答案(其实这就是钩子方法,具体答案让子类来实现)
@Override
protected String getAnswer1() {
return Answer1;
}
@Override
protected String getAnswer2() {
return Answer2;
}
@Override
protected String getAnswer3() {
return Answer3;
}
}
测试:
@Test
public void test() {
//第一个同学
AnswerCard stu1=new AnswerCard();
stu1.setName("张三");
stu1.setAnswer1("D");
stu1.setAnswer2("C");
stu1.setAnswer3("B");
//第二个同学我就什么都不会,我全选B
AnswerCard stu2=new AnswerCard();
stu2.setName("李四");
stu2.setAnswer1("B");
stu2.setAnswer2("B");
stu2.setAnswer3("B");
//开始作答
stu1.run();
stu2.run();
}
结果:
姓名:张三
面向对象的特性不包括? A封装 B继承 C多态 D消息通信
D
<大话设计模式>这本书的作者是谁? A张三 B李四 C程杰 D都不是
C
<this girl>这首歌是被哪个人唱到收费的? A一个小学生 B一个初中生 C一个高中生 D一个大学生
B
姓名:李四
面向对象的特性不包括? A封装 B继承 C多态 D消息通信
B
<大话设计模式>这本书的作者是谁? A张三 B李四 C程杰 D都不是
B
<this girl>这首歌是被哪个人唱到收费的? A一个小学生 B一个初中生 C一个高中生 D一个大学生
B
模板方法模式的优缺点
优点:
1)封装不变部分,扩展可变部分:把认为不变部分的算法封装到父类实现,可变部分则可以通过继承来实现,很容易扩展。
2)提取公共部分代码,便于维护
3)行为由父类控制,由子类实现。
缺点:
模板方法模式颠倒了我们平常的设计习惯:抽象类负责声明最抽象、最一般的事物属性和方法,实现类实现具体的事物属性和方法。在复杂的项目中可能会带来代码阅读的难度。