1. 程式人生 > >設計模式13:模板方法模式

設計模式13:模板方法模式

模板方法

概念:定義一個操作中演算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變演算法的結構即可重定義該演算法的某些特定步驟

本質:分離演算法,選擇實現。即處理步驟父類中定義好,具體實現延遲到子類中定義

其實這個蠻好懂啦,設想一下,當你和某個老哥一起去銀行辦理業務,你辦理貸款,他辦理存款業務,一般來說,你們去了的第一件事情都是排隊,輪到你們了你們再去辦理各自要辦理的業務,辦理好後就離開。

如果用程式語言描述的話,應該是這樣的 

//辦理貸款的你
public class You {
	
	public void loan(){
		//排隊
		queue();
		//辦理貸款業務中
		loaning();
		//走啦
		leave();
		
	}
	
	public void queue(){
		System.out.println("老子在排隊,累死了");
	}
	
	public void loaning(){
		System.out.println("窮成狗,想貸款..");
	}
	
	public void leave(){
		System.out.println("溜了溜了");
	}

}
//辦理存款的老哥
class Laoge{
	
	public void deposit(){
		//排隊
		queue();
		//辦理貸款業務中
		depositing();
		//走啦
		leave();
		
	}
	
	public void queue(){
		System.out.println("老子在排隊,累死了");
	}
	
	public void depositing(){
		System.out.println("富得一批,趕緊存起來.");
	}
	
	public void leave(){
		System.out.println("溜了溜了");
	}

}

我們會發現,在這個過程中,你和這位老哥有一些一樣的行為(排隊和離開),也就是說You和Laoge中有兩個共同的queue和leave方法。我們也已經學了這麼久的設計模式了,相信現在多少有些感覺了,碰到這種有重複程式碼的,我們的第一感覺是有沒有辦法把這些相同的程式碼抽出來呢。哈哈,我們要介紹的模板方法模式,就可以比較優雅地實現我們的需求。

先大致講一下思路吧,我們可以先定義一個抽象類,在該類中定義公有的行為(排隊,離開),然後把辦理的具體業務(貸款、存款)封裝為一個抽象方法,由子類實現並定義具體的行為。在這個過程中,由於我們在抽象類中已經實現了公有的方法,所以You和Laoge(繼承自抽象類)就只需要實現我們封裝的那個方法就行啦!

例項

我們先定義個抽象類,

public abstract class Bank {
	
	public void queue(){
		System.out.println("老子在排隊,累死了");
	}
	
	public abstract void transact();
	
	public void leave(){
		System.out.println("溜了溜了");
	}

	public final void process(){	//模板方法!!!
		this.queue();

		this.transact();

		this.leave();
	}
}

分類定義具體的子類,實現抽象方法

You

public class You extends Bank{

	@Override
	public void transact() {
		System.out.println("窮成狗..要貸款哦");	
	}
	
}

Laoge

class Laoge extends Bank{
	
	@Override
	public void transact() {
		System.out.println("富得一批,趕緊存起來.");
	}
}

客戶端測試

	public static void main(String[] args) {
		Bank you = new You();
		you.process();
		
		System.out.println(".....");
		
		Bank laoge = new Laoge();
		laoge.process();
	}

優點

  • 程式碼複用
  • 開閉原則

缺點

  • 每一個不同的實現都需要一個子類來實現,導致類的個數增加,使得系統更加龐大。

應用場景

實現一個演算法時,整體步驟很固定。但是,某些部分易變。易變部分可以抽象成出來,供子類實現。

實際應用

非常頻繁。各個框架、類庫中都有他的影子。比如常見的有:
資料庫訪問的封裝

srpingJDBC
Junit單元測試
servlet中關於doGet/doPost方法呼叫
Hibernate中模板程式
spring中JDBCTemplate、HibernateTemplate等。