c++設計模式(一)模板方法

設計模式的學習方法:

知道在什麼時候,什麼地方使用設計模式,比理解設計模式結構本身更加重要。

設計模式的三階段:

不會設計模式 ---->濫用設計模式---->會用設計模式

重構的關鍵技法:

  1. 靜態--->動態

  2. 早綁定--->晚綁定

  3. 繼承--->組合

  4. 編譯時依賴--->運行時依賴

  5. 緊耦合--->松耦合

組件協作模式:

組件協作模式通過晚期綁定,來實現框架與應用程序之間的松耦合,是二者之間協作常用的模式。

典型的有:

  • Template Method(模板方法)
  • Strategy(策略模式)
  • Observer/Event(事件模式) 

Template Method

動機

  • 在軟件構建的過程中,對某一項任務,它常常有穩定的整體操作結構,但各個子步驟卻有很多改變的需求,或者由於固有的原因(比如框架與應用之間的關係)而無法和任務的整體結構同時實現。
  • 如何在確定穩定操作結構的前提下,來靈活應對各個子步驟的變化或者晚期實現需求。

例如有一個程序庫開發人員設計了一個Library類,它實現了三種方法,代碼如下:

#ifndef LIBRARY_H
#define LIBRARY_H
class Library{
public:
	void Step1(){
		//...
	}
	
	void Step3(){
		//...
	}
	
	void Step5(){
		//...
	}
		
}; 
#endif

而應用程序開發人員要實現這個任務的話,他可能會編寫以下代碼

#ifndef APPLICATION_H
#define APPLICATION_H
class Application{
public:
	void Step2(){
		//...
	}
	
	void Step4(){
		//...
	}
};
#endlif

進行以下調用(這個調用類似於一些框架的生命週期,必須得如此調用)

#include <iostream>
#include "Application.h"
#include "Library.h"
int main(int argc, char** argv) {
	Library lib();
	Application app();
	
	lib.Step1();
	
	if(app.Step2()){
		lib.Step3();
	}
	
	for(int i = 0; i < 4; i++){
		app.Step4();
	}
	
	lib.Step5();
}

我們發現這個設計的糟糕之處就是,無論是誰來使用Library類都必須重複實現main函數裏面的步驟。

我們可以做出如下改進:

#ifndef LIBRARY_H
#define LIBRARY_H
class Library{
public:
	//穩定的template Method
	void Run(){
		Step1();
		
		if(Step2()){//支持變化===>虛函數的多態調用 
			Step3();
		}
		
		for(int i = 0; i < 4; i++){
			Step4();//支持變化===>虛函數的多態調用 
		}
		
		Step5();
	}
	
	virtual ~Library(){ };
	
protected:
 
	void Step1(){//穩定 
		//...
	}
	
	void Step3(){//穩定 
		//...
	}
	
	void Step5(){//穩定 
		//...
	}
	
	virtual bool Step2() = 0;//變化 
	virtual void Step4() = 0;//變化 		
}; 

#endif

然後讓Application繼承Library,並實現虛函數

#ifndef APPLICATION_H
#define APPLICATION_H
#include"Library.h"
class Application : public Library{
public:
	bool Step2(){
		//...
	}
	
	void Step4(){
		//...
	}
};

#endif

這個時候應用程序開發人員無需知道整個代碼書寫流程,只要實現相關虛函數並調用run方法就可以使用,main函數如下:

#include <iostream>
#include "Application.h"
int main(int argc, char** argv) {
	Library *pLib = new Application();
	pLib->Run();
	return 0;
}

流程如下

分析兩種寫法

  • 第一種寫法就是典型的早綁定當程序庫開發人員提前寫好Library庫時,應用程序開發人員再在此基礎上經行編寫代碼。Library是早出現的,Application是晚出現的,由晚出現調用早出現的就叫早綁定;
  • 第二種寫法是典型的晚綁定,Library是早出現的,Application是晚出現的,由早出現調用晚出現的就叫晚綁定;

模式的定義

定義一個操作中的算法骨架(穩定),而將一些步驟延遲(變化)到子類中。Template Method使得子類可以不改變(複用)一個算法的結構即可重定義(override重寫)該算法的某些特定步驟。 

缺點

必須有一個穩定的算法骨架,如代碼中的Run()方法。這也就是設計模式在穩定中平衡變化的特點。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章