策略模式(Strategy)簡介


一, 回顧簡單工廠模式(SimpleFactory)

上一篇博文: http://blog.csdn.net/nvd11/article/details/41855937

還是用回那個計算器作例子.



用簡單工廠模式實現的UML圖是這樣的:


客戶端關鍵代碼:

private void BtnClicked_btnDel(){
			int i = Integer.parseInt(tb_i.getText());
			int j = Integer.parseInt(tb_j.getText());
			
			Operation oper = OperationFactory.getOperationObj(i,j,"-");
			lblResult.setText("" + oper.getResult());
}


可見, 使用簡單工廠後,  在客戶端只知道算法是Operation的子類實現的,  但是不知道具體是哪個子類(OperationAdd 還是 OperationDel).


也就是將真正的業務子類對客戶端隱藏了.

正專業的講法就是把業務類封裝起來.


但是, 在上面的例子中, 即使使用了簡單工廠模式把業務類封裝起來, 但是還是暴露了真正的算法(方法)名字  GetResult().



二,策略模式(Strategy)定義

所謂策略模式其實跟簡單工廠模式在定義上有點類似, 只不過簡單工廠封裝的是業務類, 而策略模式封裝了方法(算法),

也就講令客戶端無法知道真正的業務方法名字.


再簡單點講,

就是利用面向對象多態, 根據子類的不同而調用不同的重寫方法.


對於上面計算器的例子.


我們移除OperationFactory類,   類似地, 添加1個叫做OperationContext的類, 它的作用有點類似與工廠類OperationFactory


Factory類:  工廠, 具有1個靜態方法. 根據參數的不同返回不同的類的對象. 通常不實例化工廠類, 只調用其靜態方法生成對象.

Context類:    具有非靜態1個方法,  根據參數對象的不同調用相同(重寫自同一超類)的方法. 客戶端通常會實例化這個類.


上所提到的對象所屬的類都是繼承(或間接繼承)自同1個超類.



三,具體代碼

3.1 Operation 類

跟上次的例子變化不大, 加上了Set方法.

public abstract class Operation {
	private int i;
	private int j;
	
	public int getI(){
		return i;
	}
	
	public void setI(int i){
		this.i = i;
	}
	
	public void setJ(int j){
		this.j = j;
	}
	
	public int getJ(){
		return j;
	}
	
	public abstract int getResult();
}

3.2 OperationAdd 類

public class OperationAdd extends Operation{
	
	@Override
	public int getResult(){
		return this.getI() + this.getJ();
	}
}

3.3 OperationDel 類

public class OperationDel extends Operation{
	
	@Override
	public int getResult(){
		return this.getI() - this.getJ();
	}
}


3.3 OperationContext 類

public class OperationContext {
	private Operation oper;
	
	public OperationContext(Operation oper){
		this.oper = oper;
	}
	
	public int compute(int i, int j){
		oper.setI(i);
		oper.setJ(j); 
		return oper.getResult();
	}
}

可見它可以根據oper對象的不同, 而調用不同的同名方法,  這就是多態的基本特性!

3.5 客戶端代碼

	private void BtnClicked_btnDel(){
			int i = Integer.parseInt(tb_i.getText());
			int j = Integer.parseInt(tb_j.getText());
			
			Operation oper = new OperationDel();
			OperationContext context = new OperationContext(oper);
			
			
			lblResult.setText("" + context.compute(i,j));
	}

3.6 UML







四, 策略模式和簡單工廠模式相結合


策略模式對客戶端封裝(隱藏)了 業務的具體方法,   也就是說上面例子中的客戶端調用OperationContext類的compute方法來計算, 而不知道真正的方法是getResutl().

但是上面的客戶端暴露了OperationDel類...


而簡單工廠模式的好處就是可以封裝具體業務類.

所以將兩個模式結合就可以同時封裝業務類和業務方法(算法).


簡單修改下OperationContext:

package strategy.bizobj;

public class OperationContext {
	private Operation oper;
	
	public OperationContext(Operation oper){
		this.oper = oper;
	}
	
	//Simple Factory 
	public OperationContext(String symbol){
		switch(symbol){
		case "+": this.oper = new OperationAdd();
		case "-": this.oper = new OperationDel();
		}
	}
	
	public int compute(int i, int j){
		oper.setI(i);
		oper.setJ(j); 
		return oper.getResult();
	}
}

上面的Context類就是簡單工廠模式和策略模式的集合了.


此時的客戶端代碼:

private void BtnClicked_btnDel(){
			int i = Integer.parseInt(tb_i.getText());
			int j = Integer.parseInt(tb_j.getText());
			
			OperationContext context = new OperationContext("-");
			lblResult.setText("" + context.compute(i,j));
}

相當簡潔, 同時隱藏(封裝)了業務類和業務方法.


擴展性同樣很強大, 如果需要增加乘法button, 只需要增加1個乘法類, 以及修改簡單工廠內的switch 代碼.















































                









發佈了288 篇原創文章 · 獲贊 300 · 訪問量 63萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章