Posted on 2005-12-06 22:33
canonical 閱讀(506)
評論(0) 編輯 收藏 所屬分類:
軟件開發
現在很多設計中推崇接口和依賴注入(dependency
injection),而不傾向于采用繼承機制來構造程序結構。但很多時候作為一種簡便而廉價的封裝方法,繼承仍然是不可或缺的.
例如與一些Engine打交道的時候,需要實現某些特定的接口. 在osworkflow中, 我們需要實現FunctionProvider接口,
interface FunctionProvider{
void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}
在Quartz中需要實現Job接口
interface Job{
public void
execute(JobExecutionContext context) throws JobExecutionException;
}
這些接口是一種技術性的要求, 它們表示了代碼生存所依賴的技術環境. 為了屏蔽這種對于外部引擎的依賴, 我們可以簡單的選擇實現一個基類,
abstract class AbstractFunction implements FunctionProvider,Runnable{
Map transientVars;
Map args;
PropertySet ps;
public final void execute(Map transientVars, Map args, PropertySet ps){
this.transientVars = transientVars;
this.args = args;
this.ps = ps;
run();
}
public Object getPersistVar(String name){
return ps.getAsActualType(name);
}
public void setPersistVar(String name, Object value){
ps.setAsActualType(name,value);
}
public void removePersistVar(String name){
ps.remove(name);
}
}
在派生類中我們只要使用getPersistVar等函數就可以回避對于osworkflow特有的PropertySet類的依賴,而只在概念上需要一
個對象的持久化機制.當我們把業務代碼從osworkflow移植到其他工作流引擎的時候, 只需要改變一下基類即可.我們可以在基類中引入更加特殊的假
設,
abstract AbstractBusinessFunction extends AbstractFunction{
public BusinessObject getBusinessObject(){
return transientVars.get("businessObject");
}
public void commonBusinessOp(){ ... }
}
AbstractBusinessFunction提供的可以是一個完整的業務對象環境, 我們在派生類中的所有代碼都可以是與業務直接相關的,而與具體
的技術實現無關(例如業務變量是存放在transientVars中還是存放在args中)
class BusinessFunction extends AbstractBusinessFunction{
public void run(){
BusinessObject bo = getBusinessObject();
bo.methodA();
commonBusinessOp();
}
}
對于我們來說實際有意義的是在派生類中所書寫的代碼,基類僅僅提供一個環境而已.無論我們使用Ioc注入業務變量還是從transientVars中主動
獲取業務變量,都是與我們的業務操作無關的. 實際上在理論上我們希望整個基類都可以是注入的(包括業務變量和業務操作),在泛型編程中這對應于所謂的
policy class.