Dorado用法与示例
Dorado用法與示例
dorado用后總結(jié)
一.dorado概念
dorado的產(chǎn)品全名是“dorado展現(xiàn)中間件”。從產(chǎn)品形態(tài)上dorado由兩部分組成,第一部分是一個(gè)具有AJAX特征的Web應(yīng)用表現(xiàn)層的快速開(kāi)發(fā)框架,第二部分配套的IDE開(kāi)發(fā)工具。開(kāi)發(fā)工具又可分為獨(dú)立的dorado studio與eclipse插件兩個(gè)選擇,eclipse插件將在以后發(fā)布,本文的開(kāi)發(fā)工具專指dorado studio。
Web表現(xiàn)層方面的產(chǎn)品主要技術(shù)流派有離散控件構(gòu)架、后臺(tái)衍伸構(gòu)架、展現(xiàn)中間件構(gòu)架等數(shù)種。離散控件構(gòu)架多是一套各個(gè)控件互不相關(guān)的JavaScript庫(kù),如bindows,后臺(tái)衍伸構(gòu)架多是為專有的后臺(tái)業(yè)務(wù)邏輯框架服務(wù),如工作流的表單設(shè)計(jì)器。展現(xiàn)中間件構(gòu)架提Wedget Lib(表現(xiàn)層控件庫(kù))并由展現(xiàn)層引擎統(tǒng)一驅(qū)動(dòng)與管理。控件使用的個(gè)數(shù)越多種類越多,越有效用。可對(duì)接的業(yè)務(wù)邏輯層也不限于某種框架,可以廣泛地通過(guò)整合 接口與各種第三方后臺(tái)邏輯框架相整合。還可以通過(guò)展現(xiàn)層引擎整合基于離散控件架構(gòu)的Web表現(xiàn)層產(chǎn)品,進(jìn)一步增強(qiáng)Web的展現(xiàn)力、操作性與承載量,同時(shí)提高開(kāi)發(fā)效率。
二.dorado主要包含5個(gè)組成部分
? 富瀏覽器客戶端:基于標(biāo)準(zhǔn)瀏覽器技術(shù),增強(qiáng)web界面的信息承載量、表現(xiàn)力與操作性。包含了應(yīng)用客戶端常用表格、樹(shù)、表單、多頁(yè)標(biāo)簽等一整套界面組件
? 展現(xiàn)引擎:支持AJAX特性,用于增強(qiáng)dorado客戶端的交互能力。
? MVC開(kāi)發(fā)框架:包括數(shù)據(jù)持久層的實(shí)現(xiàn)、頁(yè)面流控制、展現(xiàn)層角色機(jī)制、國(guó)際化資源管理、配置管理與監(jiān)控控制臺(tái)等。既可自成體系,又可與各種開(kāi)發(fā)模式與框架相結(jié)合。
? 集成開(kāi)發(fā)工具:dorado專用的IDE,可進(jìn)一步提升開(kāi)發(fā)速度。
? 應(yīng)用框架:又稱marmot,用于為基于Struts、WebWork、Spring、 Hibernate、iBatis等開(kāi)源框架的開(kāi)發(fā)模式提供與Dorado集成的范例性的實(shí)現(xiàn)代碼。其中包含了應(yīng)用主框架、完整權(quán)限的框架、用戶 Profile管理、即時(shí)消息等實(shí)用功能的實(shí)現(xiàn)代碼。
三.在項(xiàng)目里引入dorado
1. 在web.xml里面追加如下代碼:
Xml代碼
-
<!-- Dorado Serlvet --> -
<servlet> -
<servlet-name>dorado-servlet</servlet-name> -
<servlet-class>com.bstek.dorado.core.DoradoServlet</servlet-class> -
<load-on-startup>2</load-on-startup> -
</servlet> -
<servlet-mapping> -
<servlet-name>dorado-servlet</servlet-name> -
<url-pattern>*.d</url-pattern> -
</servlet-mapping> -
<filter-name>GZIPEncoder</filter-name> -
<filter-class>com.bstek.dorado.core.GZIPEncodeFilter</filter-class> -
<filter-name>dorado-filter</filter-name> -
<filter-class>com.bstek.dorado.core.DoradoFilter</filter-class> -
<filter-name>GZIPEncoder</filter-name> -
<url-pattern>*.jsp</url-pattern> -
<filter-name>dorado-filter</filter-name> -
<url-pattern>*.d</url-pattern> -
<filter-name>dorado-filter</filter-name> -
<url-pattern>*.do</url-pattern> -
<filter-name>dorado-filter</filter-name> -
<url-pattern>*.action</url-pattern> -
<taglib> -
<taglib-uri>http://www.bstek.com/dorado</taglib-uri> -
<taglib-location>/WEB-INF/dorado.tld</taglib-location> -
</taglib> -
在lib目錄里加入如下jar包
Html代碼 -
dorado5-action.jar
-
dorado5-admin.jar
-
dorado5-biz.jar
-
dorado5-common.jar
-
dorado5-core.jar
-
dorado5-data.jar
-
dorado5-designsrv.jar
-
dorado5-i18n.jar
-
dorado5-module.jar
-
dorado5-security.jar
-
dorado5-smartweb.jar
-
dorado5-utils.jar
-
dorado5-view.jar
-
在項(xiàng)目中加入home目錄,跟src目錄同級(jí)別,里面的內(nèi)容可以從doradosample里去拷貝過(guò)來(lái)。
四. 使用過(guò)程中遇到的問(wèn)題 -
如何使用項(xiàng)目中的自定義連接,不用dorado默認(rèn)的連接
在dorado的說(shuō)明文檔上有關(guān)于這個(gè)問(wèn)題的說(shuō)明,其中說(shuō)明里寫(xiě)道
Dorado重用最佳實(shí)踐
在實(shí)際開(kāi)發(fā)中,都會(huì)面臨組件重用的問(wèn)題, 面向?qū)ο蟮恼Z(yǔ)言,可以通過(guò)各種設(shè)計(jì)模式,實(shí)現(xiàn)重用.那么。在dorado框架中如何進(jìn)行重用呢? 對(duì)于dorado的重用問(wèn)題,下面從三個(gè)方面進(jìn)行說(shuō)明.
1.通過(guò)使用jsp:include指令進(jìn)行重用
將要重用的內(nèi)容寫(xiě)到一個(gè)jsp頁(yè)面中, 然后通過(guò)jsp:include標(biāo)記在需要使用的位置進(jìn)行重用, 該jsp中可再引用d:view標(biāo)簽,比如定義一個(gè)jsp頁(yè)面:
- <%@ page contentType=“text/html; charset=UTF-8”%>
- <%@ taglib uri=“http://www.bstek.com/dorado” prefix=“d”%>
- <d:View config=“com.baiyao.workflow.component.ChargeType”>
-
<d:SubWindow id="winChargeType" title="選擇類型" width="300" height="200" -
draggable="true" resizable="true" status="hidden" -
showMinimizeButton="false" showMaximizeButton="false" -
showCloseButton="true"> -
<d:Layout type="border" width="100%" height="100%"> -
<d:Pane position="center"> -
<d:DataTable id="tblType" /> -
</d:Pane> -
<d:Pane position="bottom" align="center"> -
<d:Button id="btnOK" /> -
</d:Pane> -
</d:Layout> -
</d:SubWindow> - </d:View>
在另外一個(gè)頁(yè)面中進(jìn)行引入: - <d:View config=“com.baiyao.workflow.charge.ChargeInput”>
-
<d:AutoForm id="frmForm"> -
<d:FormElementRenderer group="group1" element="render1"> -
<d:Layout type="border"> -
<d:Pane position="center"> -
<d:DataTable id="tblFormItem" /> -
</d:Pane> -
<d:Pane position="bottom" align="center"> -
<d:Button id="btnAdd" /> -
<d:Button id="btnDelete" /> -
</d:Pane> -
</d:Layout> -
</d:FormElementRenderer> -
</d:AutoForm> -
<jsp:include page="/workflow/component/win_charge_type.jsp" /> - </d:View>
該重用方式比較原始, 主要是利用了jsp:include指令, 會(huì)編寫(xiě)jsp的人都會(huì)用, 相對(duì)來(lái)說(shuō)還是非常簡(jiǎn)單的。比較適合組件在頁(yè)面中的布局中規(guī)中矩的情況, 比如實(shí)現(xiàn)某一類功能的組件都集中在頁(yè)面中的某一區(qū)域。如果某一類功能的組件在頁(yè)面中的分布跨度比較大的話, 則會(huì)因?yàn)闆](méi)法封裝在一個(gè)jsp中而無(wú)法實(shí)現(xiàn)重用。由于重用范圍僅限于jsp頁(yè)面中, 因此其維護(hù)性還是非常不錯(cuò)的。但是如果對(duì)單個(gè)簡(jiǎn)單組件專門(mén)寫(xiě)一個(gè)jsp從而在多個(gè)jsp頁(yè)面重用顯然有些得不償失。而且如果對(duì)于page1頁(yè)面中適用到了conrol1,conrol2,conrol3幾個(gè)組件, 同樣在page2頁(yè)面中也有這3個(gè)組件, 大部分屬性都差不多, 但是只有少數(shù)幾個(gè)屬性不同, 那么只能對(duì)jsp進(jìn)行重用, 而jsp對(duì)應(yīng)的view.xml文件則需要寫(xiě)兩個(gè)。因此重用性會(huì)大一定的折扣
易用程度:★★★★★
適用范圍:★★★☆☆
重用粒度:★★☆☆☆
可維護(hù)性:★★★★★
2. 對(duì)view組件定義進(jìn)行重用
view重用分為兩種, 一種是通過(guò)調(diào)用Server API來(lái)創(chuàng)建客戶端所需要的組件, 另外一種就是將多個(gè)view.xml中定義的組件進(jìn)行組合。
2.1.通過(guò)調(diào)用Server API來(lái)創(chuàng)建客戶端所需要的組件
通過(guò)調(diào)用Server API使用java代碼在后臺(tái)來(lái)來(lái)創(chuàng)建頁(yè)面所需要的各種Control和Dataset, 而不是在view.xml文件中定義需要的control和dataset, 因?yàn)椴捎眠@種方式就可以通過(guò)利用java的OO特性(封裝, 繼承和多態(tài)), 如一個(gè)保存按鈕, 可能在一個(gè)涉及到編輯操作的頁(yè)面中都會(huì)用到, 因此可以創(chuàng)建一個(gè)ViewModel基類,在基類的initControls()方法中通過(guò)new Button()的方式來(lái)創(chuàng)建該按鈕, 然后指定按鈕的屬性, 有時(shí)間的還要加上事件的javascript腳本, 這樣所有從該基類繼承的ViewModel所對(duì)應(yīng)的view所在的頁(yè)面都可以適用該按鈕了。
- @Override
- protected void initControls() throws Exception {
-
Button btnSave = (Button) createControl("Button", "btnSave"); -
btnSave.setCommand("cmdSave"); -
btnSave.setValue("保存"); -
btnSave.setWidth("70"); -
UpdateCommand cmdSave= (UpdateCommand) createControl( -
"UpdateCommand", "cmdSave"); -
cmdSave.setMethod("save"); -
DatasetInfo info = cmdSave.addDatasetInfo("dsEntity"); -
info.setSubmitScope(DatasetInfo.ALL_CHANGE); -
return btnSave; - }
該重用方式實(shí)際上就是將在view.xml配置文件中定義的control或者dataset通過(guò)java代碼來(lái)實(shí)現(xiàn), 實(shí)際上是換了一種寫(xiě)法而已, 但是相對(duì)于配置文件中的定義來(lái)說(shuō), 不夠直觀, 而且要寫(xiě)更多java的代碼, 如果該該組件比較復(fù)雜的話, 比如寫(xiě)有復(fù)雜的事件代碼, 需要去拼javascript字符串腳本, 這樣維護(hù)性將非常差。但是這種方式的重用粒度非常細(xì), 比如可以只對(duì)一個(gè)button中的某幾個(gè)屬性進(jìn)行重用。而且對(duì)于基類定義的組件可以根據(jù)需要進(jìn)行重載, 這樣靈活性將非常好。
易用程度:★★★☆☆
適用范圍:★★☆☆☆
重用粒度:★★★★★
可維護(hù)性:★☆☆☆☆
2.2.多個(gè)view.xml中定義的組件進(jìn)行組合重用
在前面介紹jsp重用方式的時(shí)候, 知道是將一個(gè)jsp頁(yè)面分解成多個(gè)頁(yè)面來(lái)進(jìn)行重用, 而這里換一個(gè)角度: 將一個(gè)view.xml根據(jù)重用的需要分解成多個(gè)view.xml文件, 其實(shí)在jsp重用中, 也使用了多個(gè)view.xml文件(進(jìn)行了view.xml的分解), 但是二者的合并時(shí)機(jī)是不同的, jsp重用是在jsp頁(yè)面的時(shí)候做的view.xml合并, 這里的合并是在ViewModel初始化中進(jìn)行的。
這里先來(lái)介紹一下JSP Dorado Taglib, ViewModel和view.xml之間的關(guān)系(僅限個(gè)人理解)
在dorado的view tag中, 根據(jù)給定的view文件所在的位置, 創(chuàng)建ViewModel對(duì)象, 該對(duì)象中會(huì)包含一個(gè)ViewModelConfig, 對(duì)應(yīng)的view.xml文件的一個(gè)解析, 接著進(jìn)行ViewModel的初始化工作, 初始化就是實(shí)際創(chuàng)建組件的過(guò)程, 這里面有一些細(xì)節(jié)這里不做研究(比如對(duì)于不同的control, 創(chuàng)建的時(shí)機(jī)是不同的)。最后得到的是一個(gè)個(gè)組件的Java對(duì)象, 可以將其看成一個(gè)個(gè)javabean, jsp頁(yè)面上的dorado taglib就會(huì)根據(jù)這些組件對(duì)象來(lái)生成html或者js腳本。
三者之間的關(guān)系大致是這樣, 接著開(kāi)始探討將多個(gè)view.xml合并的時(shí)機(jī), 最開(kāi)始采用在生成ViewModel的時(shí)候?qū)⒁M合的其他view.xml引入, 來(lái)生成最終需要的ViewModelConfig對(duì)象(在原有基礎(chǔ)上添加了其他view.xml中的組件), 后來(lái)這種做法失敗了(這個(gè)過(guò)程太多復(fù)雜, 比如還涉及到緩存問(wèn)題, 很容易出現(xiàn)在第一次展現(xiàn)沒(méi)有問(wèn)題, 但是在通過(guò)command發(fā)送ajax請(qǐng)求找不到對(duì)應(yīng)的對(duì)象而出錯(cuò)), 在ViewModel初始化(就是init方法)的時(shí)候?qū)⒁M合的view.xml引入進(jìn)去, 這時(shí)候成功了, 沒(méi)有出現(xiàn)問(wèn)題。可能dorado原來(lái)的設(shè)計(jì)沒(méi)有考慮到合并多個(gè)view.xml的做法, 因此ViewModel在這一方面還是很封閉的, 很多相關(guān)的方法都是private的, 因此需要copy出來(lái)。
- public class BaseViewModel extends DefaultViewModel {
-
protected static ControlFactory controlFactory; -
protected List<ViewModelConfig> compositedViewModelConfigs; -
protected List<String> compositedConfigNames; -
private int state; -
@Override -
public void init(int state) throws Exception { -
List<String> result = new ArrayList<String>(); -
addViewModelConfig(result); -
// 因?yàn)樵诔跏蓟渌鹶iewModelConfig的時(shí)候需要使用到狀態(tài), 而此時(shí)還沒(méi)有執(zhí)行super的init方法, -
// 因此sate還是最初的STATE_VIEW狀態(tài) -
setState(state); -
initCompositedViewModelConfigs(state, result); -
super.init(state); -
} -
protected void setState(int state) { -
this.state = state; -
} -
public int getState() { -
return state; -
} -
/** -
* 添加需要組合的view.xml文件路徑 -
* -
* @param result -
*/ -
protected void addViewModelConfig(List<String> result) { -
result.add(JbpmConstants.VIEW_TASK_INSTANCE); -
} -
/** -
* 根據(jù)ViewModelConfig初始化創(chuàng)建組件 -
* -
* @param state -
* @param configNames -
* @throws Exception -
*/ -
protected void initCompositedViewModelConfigs(int state, -
List<String> configNames) throws Exception { -
for (String configName : configNames) { -
ViewModelConfig config = getViewModelConfig(configName); -
loadDatasetConfigs(config); -
loadControlConfigs(config); -
if (state == STATE_VIEW) { -
loadEventConfig(DoradoContext.getContext(), config); -
} -
} -
} -
/** -
* 根據(jù)view.xml文件名得到ViewModelConfig對(duì)象 -
* -
* @param configName -
* @return -
* @throws Exception -
*/ -
protected ViewModelConfig getViewModelConfig(String configName) -
throws Exception { -
ViewModelConfig config = null; -
if (compositedViewModelConfigs == null) { -
compositedViewModelConfigs = new ArrayList<ViewModelConfig>(); -
compositedConfigNames = new ArrayList<String>(); -
} -
if (!compositedConfigNames.contains(configName)) { -
ViewModel viewModel = ViewModelManager.getViewModel(null, -
configName, getNamespace(), "request"); -
config = viewModel.getConfig(); -
compositedViewModelConfigs.add(config); -
compositedConfigNames.add(configName); -
} -
return config; -
} -
@SuppressWarnings("unchecked") -
protected static ControlFactory getControlFactory() { -
if (controlFactory == null) -
try { -
String clazz = Setting.getString("view.controlFactory"); -
Class cl = Class.forName(clazz); -
controlFactory = (ControlFactory) cl.newInstance(); -
} catch (IllegalAccessException ex) { -
Log.error(ex); -
} catch (InstantiationException ex) { -
if (System.getProperty("java.version").compareTo("1.4") >= 0) -
Log.error(ex.getCause()); -
else -
Log.error(ex); -
} catch (ClassNotFoundException ex) { -
Log.error(ex); -
} -
return controlFactory; -
} -
@SuppressWarnings("unchecked") -
protected void loadDatasetConfigs(ViewModelConfig viewModelConfig) -
throws Exception { -
if (viewModelConfig == null) -
return; -
List keys = viewModelConfig.datasetNodes(); -
int count = keys.size(); -
for (int i = 0; i < count; i++) { -
String id = (String) keys.get(i); -
XmlNode node = viewModelConfig.getDatasetNode(id); -
if (state != 2 && state != 3) -
createDataset(node); -
} -
} -
@SuppressWarnings("unchecked") -
protected void loadControlConfigs(ViewModelConfig config) throws Exception { -
if (config == null) -
return; -
List keys = config.controlNodes(); -
int count = keys.size(); -
for (int i = 0; i < count; i++) { -
String id = (String) keys.get(i); -
XmlNode node = config.getControlNode(id); -
String type = node.getAttribute("type"); -
Class typeClass = getControlFactory().getControlType(type); -
if (typeClass != null) { -
if ((com.bstek.dorado.view.control.Logical.class) -
.isAssignableFrom(typeClass)) { -
createControl(type, id); -
continue; -
} -
if (state == STATE_VIEW -
&& !(com.bstek.dorado.view.control.Placeable.class) -
.isAssignableFrom(typeClass)) -
createControl(type, id); -
} else { -
throw new IllegalArgumentException("Unknown control type '" -
+ type + "'!"); -
} -
} -
} -
protected void loadEventConfig(DoradoContext context, ViewModelConfig config) { -
if (config == null) -
return; -
XmlNode eventNodes[] = null; -
XmlNode eventsNode = config.getRoot().getChild("Events"); -
if (eventsNode != null) -
eventNodes = eventsNode.getChildren(); -
if (eventNodes != null) { -
for (int i = 0; i < eventNodes.length; i++) { -
XmlNode eventNode = eventNodes[i]; -
String script = XmlConfigUtils.getNodeContent(eventNode, -
context); -
EventHandler event = new EventHandler(eventNode -
.getAttribute("name"), script); -
addEventHandler(event); -
} -
} -
} -
public Control getControl(String id) throws Exception { -
ViewModelConfig config = getConfig(); -
Control control = getControl(config, id, true); -
return control; -
} -
/** -
* 在多個(gè)view.xml文件中遍歷直到找出要對(duì)應(yīng)的javabean模型數(shù)據(jù)來(lái)創(chuàng)建control -
* -
* @param config -
* @param id -
* @param loop -
* 是否循環(huán)查找, 如果是在compositeViewModelConfigs中查找的話應(yīng)該避免循環(huán)查找, 否則會(huì)死循環(huán) -
* @return -
* @throws Exception -
*/ -
private Control getControl(ViewModelConfig config, String id, boolean loop) -
throws Exception { -
Control control = (Control) controls.get(id); -
if (control == null && config != null) { -
XmlNode node = config.getControlNode(id); -
if (node != null) { -
String type = node.getAttribute("type"); -
control = createControl(type, id); -
} else if (loop) { -
// 注意順序, 添加組合的view.xml文件的原則是后添加的同id的control或dataset將覆蓋前面的 -
for (int i = compositedViewModelConfigs.size() - 1; i >= 0; i--) { -
compositedViewModelConfigs.get(i); -
control = getControl(compositedViewModelConfigs.get(i), id, -
false); -
if (control != null) { -
break; -
} -
} -
} -
} -
return control; -
} -
public Control createControl(String type, String id) throws Exception { -
Control control = (Control) controls.get(id); -
if (control == null) { -
control = constructControl(type, id); -
ViewModelConfig config = getConfig(); -
if (config != null) { -
initControl(control, config, id); -
} -
controls.forceAdd(id, control); -
initControl(control); -
} -
return control; -
} -
private void initControl(Control control, ViewModelConfig config, String id) -
throws Exception { -
XmlNode node = config.getControlNode(id); -
if (node == null) { -
for (int i = compositedViewModelConfigs.size() - 1; i >= 0; i--) { -
config = compositedViewModelConfigs.get(i); -
node = config.getControlNode(id); -
if (node != null) { -
break; -
} -
} -
} -
control.init(DoradoContext.getContext(), node); -
} -
protected ViewDataset createDataset(String type, String id, XmlNode node) -
throws Exception { -
ViewDataset dataset = constructDataset(type, id); -
DoradoContext context = DoradoContext.getContext(); -
if (node != null) { -
dataset.init(context, node); -
if (state == STATE_REPORT) -
dataset.setAutoLoadData(true); -
} -
datasets.forceAdd(id, dataset); -
initDataset(dataset); -
return dataset; -
} -
public ViewDataset createDataset(XmlNode node) throws Exception { -
String type = node.getAttribute("type"); -
String id = node.getAttribute("id"); -
return createDataset(type, id, node); -
} -
@Override -
public ViewDataset getDataset(String id) { -
// 在當(dāng)前config中找, 如果找不到, 將在組合config中去找 -
ViewDataset dataset = super.getDataset(id); -
if (dataset == null) { -
for (ViewModelConfig config : compositedViewModelConfigs) { -
if (dataset == null && config != null) { -
XmlNode node = config.getDatasetNode(id); -
if (node != null) -
try { -
String type = node.getAttribute("type"); -
dataset = createDataset(type, id); -
if (dataset != null) -
break; -
} catch (Exception ex) { -
Log.error(ex); -
} -
} -
} -
} -
return dataset; -
} -
@Override -
public ViewDataset createDataset(String type, String id) throws Exception { -
XmlNode node = null; -
ViewModelConfig config = getConfig(); -
if(config != null) { -
node = config.getDatasetNode(id); -
if (node == null) { -
for (ViewModelConfig vmc : compositedViewModelConfigs) { -
node = vmc.getDatasetNode(id); -
if (node != null) { -
break; -
} -
} -
} -
} -
return createDataset(type, id, node); -
} - }
該重用方式集成了jsp重用的優(yōu)點(diǎn), 在一定程度上消除了缺點(diǎn), 與jsp重用相比, 優(yōu)點(diǎn)在于,不會(huì)受到組件在頁(yè)面中的位置布局的影響。在重用粒度上能對(duì)單個(gè)的組件進(jìn)行重用, 相比jsp重用要細(xì), 但是比Server API的重用方式要粗一些。因?yàn)橹皇桥渲梦募系闹赜? 因此主要是對(duì)配置文件的維護(hù), 可維護(hù)性要比Server API方式要好, 該方式需要使用者對(duì)view.xml配置文件, jsp dorado taglib, ViewModel類三者之間的關(guān)系有非常好的認(rèn)識(shí)。
易用程度:★★☆☆☆
適用范圍:★★★★☆
重用粒度:★★★★☆
可維護(hù)性:★★★★★
其他重用技巧
如果view.xml文件都一樣(說(shuō)明界面一樣), 只是ViewModel不同(說(shuō)明后臺(tái)業(yè)務(wù)邏輯不同)的情況下, 可以讓其公用同一個(gè)view.xml, 只是在d:view的配置上加上clazz屬性指定二者不同的ViewModel即可。比如這樣的寫(xiě)法:
- <d:View config=“com.baiyao.workflow.settlement.SettlementInput”
-
clazz="com.baiyao.workflow.settlement.ExpenseSettlementInputViewModel"> -
<jsp:include page="/workflow/settlement/settlement_input.jsp" /> - </d:View>
如何選擇
其實(shí)這幾種重用方式互相之間并不矛盾, 可以在一個(gè)功能模塊中根據(jù)需要結(jié)合起來(lái)適用。但是如果使用太多的重用方式, 會(huì)提高項(xiàng)目的復(fù)雜程度, 這樣就會(huì)影響到可維護(hù)性, 因此重用也應(yīng)該適可而止, 否則就是過(guò)猶不及。
參考鏈接:
https://www.iteye.com/blog/xiangtui-675693
https://www.cnblogs.com/linsond/archive/2010/02/26/1674409.html
https://blog.csdn.net/weixin_30448603/article/details/98497684
總結(jié)
以上是生活随笔為你收集整理的Dorado用法与示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何在CPU上优化GEMM矩阵乘法
- 下一篇: 自研GPU之火(续)