源碼git地址 https://github.com/dlovetco/designMode
問題提出
老師在黑板上寫了一套試卷,需要小明和小剛兩個人做試卷。請用儘可能簡潔的代碼模擬出這個場景。
最簡單無腦的做法
public class TemplateMode {
public static void main(String[] args) {
Ming ming = new Ming();
ming.answerQuestion1();
ming.answerQuestion2();
Gang gang = new Gang();
gang.answerQuestion1();
gang.answerQuestion2();
}
}
class Ming {
void answerQuestion1() {
System.out.println("問題一。。。。。。。。。。");
System.out.println("小明回答xxxx");
}
void answerQuestion2() {
System.out.println("問題二、、、、、、、、、、");
System.out.println("小明回答yyyy");
}
}
class Gang {
void answerQuestion1() {
System.out.println("問題一。。。。。。。。。。");
System.out.println("小剛回答aaaa");
}
void answerQuestion2() {
System.out.println("問題二、、、、、、、、、、");
System.out.println("小剛回答bbbb");
}
}
大家一看應該就能看出來,這代碼絲毫沒有結構,重複率高。那麼我們改怎麼修改這個代碼呢?我們先分析一下這個問題就可以發現 問題的特點是問題都是一樣的,不同的只是每個同學的回答。所以我們可以把題目抽象成父類,然後因爲每個同學都要回答。把回答這個動作也抽象到父類中。
模板方法模式
package templateMode;
public class TemplateMode {
public static void main(String[] args) {
Ming ming = new Ming();
ming.question1();
ming.question2();
Gang gang = new Gang();
gang.question1();
gang.question2();
}
}
abstract class Exam{
void question1() {
System.out.println("問題一。。。。。。。。。。");
answerQuestion1();
}
abstract void answerQuestion1();
void question2() {
System.out.println("問題二。。。。。。。。。。");
answerQuestion2();
}
abstract void answerQuestion2();
}
class Ming extends Exam {
@Override
void answerQuestion1() {
System.out.println("小明回答xxxx");
}
@Override
void answerQuestion2() {
System.out.println("小明回答yyyy");
}
}
class Gang extends Exam {
@Override
void answerQuestion1() {
System.out.println("小剛回答aaaa");
}
@Override
void answerQuestion2() {
System.out.println("小剛回答bbbb");
}
}
這個模式比較特別一點的是抽象類和抽象方法的使用。因爲對於每個學生來說都是看到題目,回答問題兩個步驟。而且每個學生不一樣的只有各自的回答,所以我們不光把試卷內容抽象出來,還把回答的流程也抽象出來。由於 回答 是交給學生做的,所以在父類中可以使用抽象方法來表明 回答 這一個動作。
模板方法模式所做的事情就是:把不變的事情移到父類,去除子類中的重複代碼。
對了下面照例再貼一張plantuml
@startuml
abstract class Exam{
question1()
{abstract} answerQuestion1()
question2()
{abstract} answerQuestion2()
}
Exam <|--Ming
class Ming{
answerQuestion1()
}
Exam <|--Gang
class Gang{
answerQuestion2()
}
@enduml