通過(guò)繼承構(gòu)造業(yè)務(wù)對(duì)象環(huán)境
Posted on 2005-12-06 22:33 canonical 閱讀(507) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 軟件開(kāi)發(fā) 現(xiàn)在很多設(shè)計(jì)中推崇接口和依賴注入(dependency
injection),而不傾向于采用繼承機(jī)制來(lái)構(gòu)造程序結(jié)構(gòu)。但很多時(shí)候作為一種簡(jiǎn)便而廉價(jià)的封裝方法,繼承仍然是不可或缺的.
例如與一些Engine打交道的時(shí)候,需要實(shí)現(xiàn)某些特定的接口. 在osworkflow中, 我們需要實(shí)現(xiàn)FunctionProvider接口,
interface FunctionProvider{
void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}
在Quartz中需要實(shí)現(xiàn)Job接口
interface Job{
public void execute(JobExecutionContext context) throws JobExecutionException;
}
這些接口是一種技術(shù)性的要求, 它們表示了代碼生存所依賴的技術(shù)環(huán)境. 為了屏蔽這種對(duì)于外部引擎的依賴, 我們可以簡(jiǎn)單的選擇實(shí)現(xiàn)一個(gè)基類(lèi),
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);
}
}
在派生類(lèi)中我們只要使用getPersistVar等函數(shù)就可以回避對(duì)于osworkflow特有的PropertySet類(lèi)的依賴,而只在概念上需要一 個(gè)對(duì)象的持久化機(jī)制.當(dāng)我們把業(yè)務(wù)代碼從osworkflow移植到其他工作流引擎的時(shí)候, 只需要改變一下基類(lèi)即可.我們可以在基類(lèi)中引入更加特殊的假 設(shè),
abstract AbstractBusinessFunction extends AbstractFunction{
public BusinessObject getBusinessObject(){
return transientVars.get("businessObject");
}
public void commonBusinessOp(){ ... }
}
AbstractBusinessFunction提供的可以是一個(gè)完整的業(yè)務(wù)對(duì)象環(huán)境, 我們?cè)谂缮?lèi)中的所有代碼都可以是與業(yè)務(wù)直接相關(guān)的,而與具體 的技術(shù)實(shí)現(xiàn)無(wú)關(guān)(例如業(yè)務(wù)變量是存放在transientVars中還是存放在args中)
class BusinessFunction extends AbstractBusinessFunction{
public void run(){
BusinessObject bo = getBusinessObject();
bo.methodA();
commonBusinessOp();
}
}
對(duì)于我們來(lái)說(shuō)實(shí)際有意義的是在派生類(lèi)中所書(shū)寫(xiě)的代碼,基類(lèi)僅僅提供一個(gè)環(huán)境而已.無(wú)論我們使用Ioc注入業(yè)務(wù)變量還是從transientVars中主動(dòng) 獲取業(yè)務(wù)變量,都是與我們的業(yè)務(wù)操作無(wú)關(guān)的. 實(shí)際上在理論上我們希望整個(gè)基類(lèi)都可以是注入的(包括業(yè)務(wù)變量和業(yè)務(wù)操作),在泛型編程中這對(duì)應(yīng)于所謂的 policy class.
interface FunctionProvider{
void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}
在Quartz中需要實(shí)現(xiàn)Job接口
interface Job{
public void execute(JobExecutionContext context) throws JobExecutionException;
}
這些接口是一種技術(shù)性的要求, 它們表示了代碼生存所依賴的技術(shù)環(huán)境. 為了屏蔽這種對(duì)于外部引擎的依賴, 我們可以簡(jiǎn)單的選擇實(shí)現(xiàn)一個(gè)基類(lèi),
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);
}
}
在派生類(lèi)中我們只要使用getPersistVar等函數(shù)就可以回避對(duì)于osworkflow特有的PropertySet類(lèi)的依賴,而只在概念上需要一 個(gè)對(duì)象的持久化機(jī)制.當(dāng)我們把業(yè)務(wù)代碼從osworkflow移植到其他工作流引擎的時(shí)候, 只需要改變一下基類(lèi)即可.我們可以在基類(lèi)中引入更加特殊的假 設(shè),
abstract AbstractBusinessFunction extends AbstractFunction{
public BusinessObject getBusinessObject(){
return transientVars.get("businessObject");
}
public void commonBusinessOp(){ ... }
}
AbstractBusinessFunction提供的可以是一個(gè)完整的業(yè)務(wù)對(duì)象環(huán)境, 我們?cè)谂缮?lèi)中的所有代碼都可以是與業(yè)務(wù)直接相關(guān)的,而與具體 的技術(shù)實(shí)現(xiàn)無(wú)關(guān)(例如業(yè)務(wù)變量是存放在transientVars中還是存放在args中)
class BusinessFunction extends AbstractBusinessFunction{
public void run(){
BusinessObject bo = getBusinessObject();
bo.methodA();
commonBusinessOp();
}
}
對(duì)于我們來(lái)說(shuō)實(shí)際有意義的是在派生類(lèi)中所書(shū)寫(xiě)的代碼,基類(lèi)僅僅提供一個(gè)環(huán)境而已.無(wú)論我們使用Ioc注入業(yè)務(wù)變量還是從transientVars中主動(dòng) 獲取業(yè)務(wù)變量,都是與我們的業(yè)務(wù)操作無(wú)關(guān)的. 實(shí)際上在理論上我們希望整個(gè)基類(lèi)都可以是注入的(包括業(yè)務(wù)變量和業(yè)務(wù)操作),在泛型編程中這對(duì)應(yīng)于所謂的 policy class.