首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

基于view实业的设计

2012-07-28 
基于view实体的设计view对象1.何为view对象首先,view对象不是view层。关于这个问题,先来看一个常用的模式se

基于view实体的设计

view对象

1.何为view对象

首先,view对象不是view层。

关于这个问题,先来看一个常用的模式

service 层

dao 层

view 层

entity 实体

?

也许在基于领域模型的设计中,还会有一个专门的model实体,领域实体,来对领域对象进行抽离。

?

该结构忽略了一个细节,也就是,view层,视图层,它的规则,不受领域,更不受数据实体的关注。以java语言为例,一般情况下,model对象或者entity对象时可以直接被视图模板直接使用并输出的。但视图层有个特点就是随时变化的,或者视图层的展示,极其复杂的,entity和model的数据本身就无法在未进过一些处理直接使用。这个特殊处理在哪里进行?entity或者领域内部?这不可能,这根本就不是他们的职责,view层或者service,dao层就更别说了。到了模板引擎来处理?是的,经常这么做。

?

那么来看一个例子

?


基于view实业的设计


基于view实业的设计

这是两种收费凭证,第一种是普通的,第二种是课外活动的(实际上有很多种凭证,这里只截取了系统的两种)。

?

?

对于打印界面

?

都类似,于是采用同一张freemarker模板文件,printInvoice.html。


基于view实业的设计

?

随后,有个要求,对于课外活动的凭证打印的时候,要求按照时间,也就是周一到周日,顺序显示。并且取出来的时候是没有按照这个顺序排列好的,也许有人说,order by一下不行吗?行,但是我变一下,我要求周三显示到第一列,周五显示到第二列,其他按照顺序显示呢?你还想告诉我order by一下嘛?视图层变化随时可能发生的。它的变化度要远远高于业务变化吧。

?

?

为了满足这个要求,根据上面说的,在freemarker中完成吧?但模板这东西,它如果加上复杂的逻辑,这模板的可读性,不言而喻。

上代码

?

?

<td valign="top" align="left" style="padding-left:0px">

? ? ? ? ? ? ? ?<table border="0" cellspacing="0" cellpadding="0" style="border-collapse: collapse">

? ? ? ? ? ? ? ?<#--课外活动-->

? ? ? ? ? ? ? ?<#if periodNoAttr?exists && periodNoAttr.attrValue?exists>

<#list 0..6 as i>

<#assign w = daysPerWeekE[i] + "."/>

<#--查找星期信息-->

<#list invoiceItems as it>

<#if it.description?? && it.description ==w>

<#assign curInvoiceItemTypeId=it.getRelatedOne("InvoiceItemType")>

<#assign itW = it>

<#break />

</#if>

</#list>

<#if itW?? && itW != "">

<tr>

<td>

${(itW.description)?if_exists}

</td>

<td>${(curInvoiceItemTypeId.description)?if_exists}</td>

</tr>

</#if>

<#assign itW = "" />

<#assign curInvoiceItemTypeId = "" />

</#list>

<#--非课外活动-->

<#else>

? ? ? ? ? ? ? ?<#list 0..6 as i>

? ? ? ? ? ? ? ?<#if invoiceItems?has_content>

<#if (invoiceItems[i])?has_content>

<#assign curInvoiceItemTypeId=invoiceItems[i].getRelatedOne("InvoiceItemType")>

<tr>

<td>${(invoiceItems[i].description)?if_exists}</td>

? ? ? ? ? ? ? ?<td>${(curInvoiceItemTypeId.description)?if_exists}</td>

? ? ? ? ? ? ?</tr>

</#if>

<#else>

<#assign curInvoiceItemTypeId="">

</#if>

? ? ? ? ? ? ? ?</#list>

</#if>

? ? ? ? ? ? ? ?</table>

</td>

? ? ? ? ? ? ? ?<td valign="top" align="right" style="width: 200px;">

? ? ? ? ? ? ? ?<table border="0" cellspacing="0" cellpadding="0" style="border-collapse: collapse">

? ? ? ? ? ? ? ?<#--课外活动-->

? ? ? ? ? ? ? ?<#if periodNoAttr?exists && periodNoAttr.attrValue?exists>

? ? ? ? ? ? ? ? <#list 0..6 as i>

? ? ? ? ? ? ? ? <#assign w = daysPerWeekE[i] + "."/>

? ? ? ? ? ? <#list invoiceItems as it>

? ? ? ? ? ? <#if it.description?? && it.description ==w>

<#assign itW = it>

</#if>

</#list>

<#if itW?? && itW != "">

<#assign curInvoiceAmount=itW.amount>

<tr>

? ? ? ? ? ? ? ?<td style="padding-right:25px">&nbsp;<#if curInvoiceAmount?? && curInvoiceAmount?string != '0'>${(curInvoiceAmount?if_exists)?string("currency")}</#if></td>

? ? ? ? ? ? ?</tr>

</#if>

<#assign itW= ""/>

</#list>

<#else>

<#--非课外活动-->

? ? ? ? ? ? ? ?<#list 0..6 as i> ?

? ? ? ? ? ? ? ?<#if invoiceItems?has_content>

<#if (invoiceItems[i])?has_content>

<#assign curInvoiceAmount=invoiceItems[i].amount>

<tr>

? ? ? ? ? ? ? ?<td style="padding-right:25px">&nbsp;<#if curInvoiceAmount?? && curInvoiceAmount?string != '0'>${(curInvoiceAmount?if_exists)?string("currency")}</#if></td>

? ? ? ? ? ? ?</tr>

<#else>

<#assign curInvoiceAmount="">

</#if>

</#if>

? ? ? ? ? ? ? ?</#list>

</#if>

? ? ? ? ? ? ? ?</table>

</td>

?

?

这代码似乎不难,但别忘了我这里的例子也不复杂。

?

通过view实体来完成这些也许会越来越复杂的东西,

?

public class InvoiceView {

///其他代码省略

?

/** *  * 描述:按照星期排序收费子项 *  * @return * @author liyixing 2012-4-1 下午10:36:13 */public List<GenericValue> getInvoiceItemsOrderByWeek() {List<GenericValue> invoiceItemsOrderByWeek = FastList.newInstance();for (int start = 1; start <= 7; start++) {String currentInvoiceItemSeqId = "0000" + start;for (GenericValue invoiceItem : invoiceItems) {// 找到当前星期if (currentInvoiceItemSeqId.equals(invoiceItem.getString("invoiceItemSeqId"))) {invoiceItemsOrderByWeek.add(invoiceItem);break;}}}return invoiceItemsOrderByWeek;}
//正常部分
public List<GenericValue> getInvoiceItems() {return invoiceItems;}
?

}

?

?

这个时候再模板中,要做的事情就清晰的多了

?

<#--项目-->

<div style="position: absolute; left:105px; top: 150px; width: 590px;">

<#if invoiceView.invoice.invoiceTypeId == "AFTSCH_ACT_INV">

<#--课外活动,按照收费时间,周一到周日排序-->

<#list invoiceView.invoiceItemsOrderByWeek as invoiceItem>

${invoiceView.daysEnPerWeek.get(invoiceItem.invoiceItemSeqId)}

${invoiceView.getInvoiceItemType(invoiceItem).description}:?

${invoiceItem.amount}?

</#list>

<#else>

<#--其他凭证,按照正常逻辑-->

<#list invoiceView.invoiceItems as invoiceItem>

${invoiceView.getInvoiceItemType(invoiceItem).description}:?

${invoiceItem.amount}

</#list>

</#if>

<#--校车,校车和参加周在view对象中的代码我省略掉了-->

<#list invoiceView.schoolBusTerms as invoiceTerm>

schoolbus: ${invoiceView.daysEnPerWeekBySchoolBus.get(invoiceTerm.textValue)}

</#list>

<#list invoiceView.weekTerms as invoiceTerm>

Week: ${invoiceTerm.textValue}.

</#list>

</div>

?

?

这就是对比了。

?

?

2.好处

好处,很简单,java代码的可读性本身就比嵌套了其他诸如html,xml之类的模板要清晰的多的多,这个每个人都明白的吧。

?

?

view能适应各种变化,只是加一个get或者其他方法而已,或者更改原有的方法的值。

?

?

3.注意项

view对象应该经过抽离,一般情况下和领域对象直接对应即可。

如Invoice凭证领域对象

和InvoiceView。

?

?

view无需考虑它所处的位置,如对于admin平台有对student的展示有特殊要求,bbs部分对student也有要求,那么只需要一个view,而不要分离出两个。从我想到view实体对象,到用到现在,发现view的方法会逐步增加,而且这些方法很少有能重用的,但没关系view是一个很简单,也很没有必要过分抽象的对象,甚至你的view里面的一个方法只会被一个模板页面用到,那也没关系。

?

?

view会引用model或者entity对象。建议引用model。实际上继承是更好的方式。然后再利用BeanUtils直接拷贝两个对象值。


基于view实业的设计


基于view实业的设计

?

?

2 楼 wangyi878750 2012-04-06   OH 原来这个项目还有人维护啊 3 楼 liyixing1 2012-04-07   wangyi878750 写道OH 原来这个项目还有人维护啊
嗯,准备和另外一个项目整合到一起呢。

本来我是在另外一个项目想到的view对象,然后这个项目的展示方式又太复杂了,就把view加到这个项目了。

正好想把这个view对象的设计整理下,就用这个项目做了例子,因为这个项目做例子比较好。

热点排行