轉(zhuǎn)自: CCIENET
自從J2EE出現(xiàn)以來(lái),就大大簡(jiǎn)化了在Java下的企業(yè)級(jí)開(kāi)發(fā)。但是隨著J2EE越來(lái)越普遍
地被應(yīng)用到各個(gè)領(lǐng)域中,開(kāi)發(fā)者們漸漸意識(shí)到需要一種方法來(lái)標(biāo)準(zhǔn)化應(yīng)用程序的開(kāi)發(fā)過(guò)程,他們采用的方法是標(biāo)準(zhǔn)化應(yīng)用程序的結(jié)構(gòu)層。在結(jié)構(gòu)層通常封裝了一些獨(dú)
立于業(yè)務(wù)邏輯的復(fù)雜技術(shù),以便在業(yè)務(wù)邏輯和底層的架構(gòu)之間建立起弱連接。無(wú)可否認(rèn),J2EE是一個(gè)很成功的技術(shù),它為一些基本的任務(wù)提供了一致的標(biāo)準(zhǔn),例
如數(shù)據(jù)庫(kù)連接、分布式應(yīng)用程序等。但是使用J2EE并不能保證開(kāi)發(fā)人員開(kāi)發(fā)出成功的應(yīng)用程序。有些人認(rèn)為J2EE本身就是一種框架技術(shù),但是這種認(rèn)識(shí)是不
正確的,我們應(yīng)該意識(shí)到J2EE并沒(méi)有提供一個(gè)能夠幫助開(kāi)發(fā)人員開(kāi)發(fā)出高質(zhì)量應(yīng)用程序的框架,因此很多有經(jīng)驗(yàn)的開(kāi)發(fā)人員通過(guò)利用設(shè)計(jì)模式來(lái)彌補(bǔ)這一缺陷。
在開(kāi)發(fā)人員的圈子中,大家通過(guò)相互交流在開(kāi)發(fā)過(guò)程中所遇到的問(wèn)題以及解決方法來(lái)豐
富整個(gè)圈子的經(jīng)驗(yàn)。而設(shè)計(jì)模式就是在這樣的情況下產(chǎn)生的。一個(gè)設(shè)計(jì)模式必然是針對(duì)某個(gè)特定的問(wèn)題的,這個(gè)問(wèn)題的解決方案以及這樣解決問(wèn)題產(chǎn)生的后果。在本
文中我將討論復(fù)合模式的特點(diǎn)和它的應(yīng)用。
復(fù)合模式(Composite Patten)介紹
在介紹復(fù)合模式前,我們需要定義一下什么是復(fù)合對(duì)象(Composite
Object)。復(fù)合對(duì)象是包含了其它對(duì)象的對(duì)象。例如,一幅圖由一些基本的對(duì)象組成,例如線(xiàn)、圓、矩形和文本等,因此圖就是復(fù)合對(duì)象。因?yàn)樵贘ava
中,開(kāi)發(fā)人員操作基本對(duì)象的方式和操作復(fù)合對(duì)象的方式常常相同,因此需要利用到復(fù)合模式。例如,線(xiàn)或文本等基本圖形對(duì)象都需要支持繪制、移動(dòng)或縮放等功
能;而圖這種復(fù)合對(duì)象也需要支持相同的功能。在理想的情況下,我們希望對(duì)復(fù)合對(duì)象和基本對(duì)象以完全相同的方式完成這些操作,否則實(shí)現(xiàn)的代碼將會(huì)產(chǎn)生不必要
的復(fù)雜性,并且不易于維護(hù)和擴(kuò)展。
那么什么是復(fù)合模式呢?將對(duì)象組織到樹(shù)結(jié)構(gòu)中以表達(dá)部分整體的層次關(guān)系就實(shí)現(xiàn)了復(fù)合模式,它使程序能夠以相同的方式對(duì)待基本對(duì)象和復(fù)合對(duì)象。
在程序中實(shí)現(xiàn)復(fù)合模式并不難。復(fù)合類(lèi)繼承一個(gè)代表基本類(lèi)型的基類(lèi)就可以了
。圖1顯示了一個(gè)表現(xiàn)復(fù)合模式思想的類(lèi)圖。
圖1 復(fù)合模式的實(shí)現(xiàn)
在圖1中,Component是代表基本類(lèi)型的基類(lèi)(也可以是一個(gè)接口);
Composite是復(fù)合類(lèi)。例如Component代表的是基本圖形元素的基類(lèi),而Composite代表的是圖;Operation1()和
Operation2()方法分別是移動(dòng)和縮放操作。圖1中的Leaf類(lèi)代表的是點(diǎn)、線(xiàn)或者圓等基本圖形元素。
針對(duì)Component類(lèi)中的每個(gè)方法,Composite類(lèi)都有相同名稱(chēng)的方法
與之對(duì)應(yīng)。Composite類(lèi)保存了一個(gè)基本對(duì)象的集合。通常Composite類(lèi)中的方法在實(shí)現(xiàn)時(shí)都會(huì)將集合中的對(duì)象遍歷一次,然后調(diào)用每個(gè)對(duì)象中相
應(yīng)的方法。例如圖對(duì)象Drawing的draw()方法可能是這樣實(shí)現(xiàn)的:
//
?代碼1一個(gè)復(fù)合方法
public
?
void
?draw()?{
???
//
?I遍歷所有的對(duì)象
???
for
(
int
?i
=
0
;?i?
<
?getComponentCount();?
++
i)?{
??????
//
?獲得對(duì)對(duì)象的應(yīng)用,調(diào)用它的draw方法
??????Component?component?
=
?getComponent(i);
??????component.draw();???
???}
由于Composite類(lèi)繼承了Component類(lèi),因此你可以將一個(gè)Composite對(duì)象傳遞給需要Component對(duì)象作為參數(shù)的方法。例如:
//
?代碼2??repaint方法
public
?
void
?repaint(Component?component)?{
???
//
?事實(shí)上component可能是一個(gè)復(fù)合對(duì)象,因此該方法沒(méi)有區(qū)分基本對(duì)象和復(fù)合對(duì)象
???component.draw();
}
????????????????????????????????????????
上面的repaint()方法中,Component對(duì)象被作為參數(shù)傳遞到了函數(shù)
體,這個(gè)對(duì)象可以是Component,也可以是Composite。然后函數(shù)體中調(diào)用draw()方法。由于Composte類(lèi)繼承了
Component,程序就不用區(qū)分傳入的參數(shù)到底是哪種類(lèi)的實(shí)例,只需要調(diào)用該對(duì)象的draw()方法就可以了。
圖1中的類(lèi)圖展示了復(fù)合模式的一個(gè)方面:開(kāi)發(fā)人員必須在引用一個(gè)
Component對(duì)象時(shí)必須區(qū)分它到底了一個(gè)Component對(duì)象還是一個(gè)Composite對(duì)象。通常開(kāi)發(fā)人員可以在Component類(lèi)中加入一
個(gè)方法,例如isComposite(),來(lái)辨別Composite類(lèi)。如果該方法返回的是True,開(kāi)發(fā)人員就需要將Component對(duì)象強(qiáng)制轉(zhuǎn)換為
Compoiste對(duì)象。
????????????????????????????
//
?代碼3,區(qū)分Component和Composite
if
(component.isComposite())?{
???Composite?composite?
=
?(Composite)component;
???composite.addComponent(AComponent);
}
圖2顯示了另一種實(shí)現(xiàn)復(fù)合模式的方法:
圖2 另一種復(fù)合模式的實(shí)現(xiàn)方法
在圖2所示的復(fù)合模型中,開(kāi)發(fā)人員不必區(qū)分Component對(duì)象和Composite對(duì)象,也不需要將Component對(duì)象強(qiáng)制轉(zhuǎn)換Composited對(duì)象。這樣代碼3中的代碼就變成了一行:
//
?代碼4,不區(qū)分Component和Composite
component.addComponent(AComponent);
但是如果代碼4中的component不是Composite的實(shí)例,
addComponent()方法會(huì)做些什么呢?這是圖2中的復(fù)合模式中最重要的一部分。顯然一個(gè)基本類(lèi)型不可能包含其他基本類(lèi)型或復(fù)合類(lèi)型,
Component.addComponent()可能什么也不干,或者拋出一個(gè)異常。通常我們認(rèn)為將基本類(lèi)型加入其他基本類(lèi)型的操作是一個(gè)錯(cuò)誤,因此拋
出異常是開(kāi)發(fā)人員最好的選擇。
那么這兩種復(fù)合模式的實(shí)現(xiàn)方法哪一個(gè)更好呢?這是一個(gè)常常引起爭(zhēng)論的問(wèn)題。我個(gè)人覺(jué)得第二種方法更好一些,因?yàn)殚_(kāi)發(fā)人員不必區(qū)分Component對(duì)象和Composite對(duì)象,也不用強(qiáng)制轉(zhuǎn)換對(duì)象。
使用復(fù)合模式的實(shí)際例子:Struct Tiles
下面讓我們來(lái)看一個(gè)復(fù)合模式應(yīng)用用到Apache Struts
JSP框架中的例子。在Apache
Struts的框架中包含了一個(gè)被稱(chēng)為T(mén)iles的JSP標(biāo)簽庫(kù),它是你能夠?qū)⒍鄠€(gè)JSP組合成一個(gè)Web頁(yè)面。事實(shí)上,它實(shí)現(xiàn)J2EE復(fù)合視圖模式。在
我們討論復(fù)合模式和Tiles標(biāo)簽庫(kù)的聯(lián)系前,讓我們先來(lái)看一個(gè)Tiles的例子。如果你對(duì)Struts已經(jīng)非常熟悉了,你可以跳到"在Struts
Tiles中使用復(fù)合模式"一節(jié)。
通常一張網(wǎng)頁(yè)是有幾個(gè)區(qū)域構(gòu)成的。例如圖3中的網(wǎng)頁(yè)包含了邊欄、頭、內(nèi)容和角注四個(gè)部分。這四個(gè)部分在網(wǎng)頁(yè)上的分布構(gòu)成了布局。Struts Tiles使你能夠重用單獨(dú)的每個(gè)區(qū)域和布局。在我們討論重用的問(wèn)題之前,讓我們來(lái)看看怎樣用不同的方法實(shí)現(xiàn)圖3中的網(wǎng)頁(yè)。
圖3 例子網(wǎng)頁(yè)
1.手工實(shí)現(xiàn)布局
下面是相應(yīng)的HTML代碼:
????????????????????代碼5?手工實(shí)現(xiàn)布局的HTML代碼
<!
DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN"
>
<%
@?page?contentType
=
'
text/html;?charset=UTF-8'?%>
<
html
>
???
<
head
>
??????
<
title
>
Implementing?Complex?Layouts?by?Hand
</
title
>
???
</
head
>
???
<
body?background
=
'
graphics/blueAndWhiteBackground.gif'>
??????
<
%
--
?One?table?lays?out?all?of?the?content?
for
?this?page?
--
%>
??????
<
table?
width
='100%'?
height
='100%'
>
?????????
<
tr
>
????????????
<%
--
?Sidebar
--
%>
????????????
<
td?
width
='150'?
valign
='top'?
align
='left'
>
???????????????
<
table
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Sidebar?top?
--
%>
?????????????????????
<
td?
width
='150'?
height
='65'?
valign
='top'?
align
='left'
>
????????????????????????
<
a?
href
=''
>
???????????????????????????
<
img?
src
='graphics/flags/britain_flag.gif'
/></
a
>
????????????????????????
<
a?
href
=''
>
???????????????????????????
<
img?
src
='graphics/flags/german_flag.gif'
/></
a
>
????????????????????????
<
a?
href
=''
>
???????????????????????????
<
img?
src
='graphics/flags/chinese_flag.gif'
/></
a
>
?????????????????????
</
td
>
??????????????????
</
tr
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Sidebar?bottom?
--
%>
?????????????????????
<
td
>
????????????????????????
<
font?
size
='5'
>
Links
</
font
><
p
>
????????????????????????
<
a?
href
=''
>
Home
</
a
><
br
>
????????????????????????
<
a?
href
=''
>
Products
</
a
><
br
>
????????????????????????
<
a?
href
=''
>
Downloads
</
a
><
br
>
????????????????????????
<
a?
href
=''
>
White?papers
</
a
><
br
>
????????????????????????
<
a?
href
=''
>
Contact?us
</
a
><
br
>
?????????????????????
</
td
>
??????????????????
</
tr
>
???????????????
</
table
>
????????????
</
td
>
????????????
<%
--
?Main?content
--
%>
????????????
<
td?
valign
='top'?
height
='100%'?
width
='*'
>
???????????????
<
table?
width
='100%'?
height
='100%'
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Header
--
%>
?????????????????????
<
td?
valign
='top'?
height
='15%'
>
????????????????????????
<
font?
size
='6'
>
Welcome?to?Sabreware,?Inc.
</
font
>
????????????????????????
<
hr
>
?????????????????????
</
td
>
??????????????????
<
tr
>
?????????????????
<
tr
>
?????????????????????
<%
--
?Content
--
%>
?????????????????????
<
td?
valign
='top'?
height
='*'
>
????????????????????????
<
font?
size
='4'
>
Page-specific?content?goes?here
</
font
>
?????????????????????
</
td
>
??????????????????
</
tr
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Footer
--
%>
?????????????????????
<
td?
valign
='bottom'?
height
='15%'
>
????????????????????????
<
hr
>
????????????????????????Thanks?for?stopping?by!
?????????????????????
</
td
>
??????????????????
</
tr
>
???????????????
</
table
>
????????????
</
td
>
?????????
</
tr
>
??????
</
table
>
???
</
body
>
</
html
>
然后你需要實(shí)現(xiàn)JSP。根據(jù)代碼5編寫(xiě)出的JSP代碼有兩個(gè)缺點(diǎn)。第一,頁(yè)面的內(nèi)容
被嵌入了JSP代碼中,因此開(kāi)發(fā)人員無(wú)法重用它。而事實(shí)上,邊欄、頭和角注在一個(gè)網(wǎng)站的網(wǎng)頁(yè)中可能會(huì)被多次重用。第二,頁(yè)面的布局也被嵌入到JSP代碼
中,因此即使有很多網(wǎng)也采用同樣的布局,開(kāi)發(fā)人員也無(wú)法重用它。通過(guò)使用可以避免第一個(gè)問(wèn)題。
2.使用<jsp:include>實(shí)現(xiàn)布局
在下面的例子中,我們使用<jsp:include>來(lái)實(shí)現(xiàn)圖3中的網(wǎng)頁(yè)。
????????????????????????????????????????????代碼6?用jsp:include實(shí)現(xiàn)布局
<%
@?page?contentType
=
'
text/html;?charset=UTF-8'?%>
<
html
>
???
<
head
>
??????
<
title
>
Implementing?Complex?Layouts?by?Hand
</
title
>
???
</
head
>
???
<
body?background
=
'
graphics/blueAndWhiteBackground.gif'>
??????
<
%
--
?One?table?lays?out?all?of?the?content?
for
?this?page?
--
%>
??????
<
table?
width
='100%'?
height
='100%'
>
?????????
<
tr
>
????????????
<%
--
?Sidebar?section?
--
%>
????????????
<
td?
width
='150'?
valign
='top'?
align
='left'
>
???????????????
<
jsp:include?
page
='sidebar.jsp'
/>
????????????
</
td
>
????????????
<%
--
?Main?content?section?
--
%>
????????????
<
td?
height
='100%'?
width
='*'
>
???????????????
<
table?
width
='100%'?
height
='100%'
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Header?section?
--
%>
?????????????????????
<
td?
valign
='top'?
height
='15%'
>
????????????????????????
<
jsp:include?
page
='header.jsp'
/>
?????????????????????
</
td
>
??????????????????
<
tr
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Content?section?
--
%>
?????????????????????
<
td?
valign
='top'?
height
='*'
>
????????????????????????
<
jsp:include?
page
='content.jsp'
/>
?????????????????????
</
td
>
??????????????????
</
tr
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Footer?section?
--
%>
?????????????????????
<
td?
valign
='bottom'?
height
='15%'
>
????????????????????????
<
jsp:include?
page
='footer.jsp'
/>
?????????????????????
</
td
>
??????????????????
</
tr
>
???????????????
</
table
>
????????????
</
td
>
?????????
</
tr
>
??????
</
table
>
???
</
body
>
</
html
>
在上面的代碼中,通過(guò)使用<jsp:include>來(lái)
調(diào)用其它JSP。由于在sidebar.jsp、header.jsp、content.jsp、和footer.jsp中封裝了邊欄、頭、內(nèi)容和角注,
因此開(kāi)發(fā)人員可以重用這些元素。但是這種解決方案仍然無(wú)法重用網(wǎng)頁(yè)的布局。下面是sidebar.jsp、header.jsp、
content.jsp、和footer.jsp的代碼:
????????????????????????????????????????代碼7?sidebar.jsp
<%
@?page?contentType
=
'
text/html;?charset=UTF-8'?%>
<
table?width
=
'
100%'>
???
<
tr
>
??????
<
%
--
?Sidebar?top?component?
--
%>
??????
<
td?
width
='150'?
height
='65'?
valign
='top'?
align
='left'
>
????????
<
a?
href
=''
><
img?
src
='graphics/flags/britain_flag.gif'
/></
a
>
????????
<
a?
href
=''
><
img?
src
='graphics/flags/german_flag.gif'
/></
a
>
????????
<
a?
href
=''
><
img?
src
='graphics/flags/chinese_flag.gif'
/></
a
>
??????
</
td
>
???
</
tr
>
???
<
tr
>
??????
<%
--
?Sidebar?bottom?component?
--
%>
??????
<
td
>
?????????
<
table
>
????????????
<
tr
>
???????????????
<
td
>
??????????????????
<
font?
size
='5'
>
Links
</
font
><
p
>
??????????????????
<
a?
href
=''
>
Home
</
a
><
br
>
??????????????????
<
a?
href
=''
>
Products
</
a
><
br
>
??????????????????
<
a?
href
=''
>
Downloads
</
a
><
br
>
??????????????????
<
a?
href
=''
>
White?papers
</
a
><
br
>
??????????????????
<
a?
href
=''
>
Contact?us
</
a
><
br
>
???????????????
</
td
>
????????????
</
tr
>
?????????
</
table
>
??????
</
td
>
???
</
tr
>
</
table
>
????????
????????????????????????????代碼8?header.jsp
<
font?
size
='6'
>
Welcome?to?Sabreware,?Inc.
</
font
>
<
hr
>
代碼9?content.jsp
<
font?
size
='4'
>
Page-specific?content?goes?here
</
font
>
代碼10?footer.jsp
<
hr
>
Thanks?for?stopping?by!
3.利用Structs Tiles來(lái)實(shí)現(xiàn)布局
代碼10中展示了如何用Struts Tiles來(lái)實(shí)現(xiàn)前面提到的網(wǎng)頁(yè)。這段代碼利用了<titles:insert>標(biāo)
簽來(lái)創(chuàng)建圖3中對(duì)應(yīng)的JSP網(wǎng)頁(yè)。該JSP文件被定義在名稱(chēng)為sidebar-header-footer-definition的Tiles定義中,定
義信息保存在Tiles的配置文件中,在這個(gè)例子中,配置文件是WEB-INF/tlds/struts-tiles.tld。代碼11列出了該文件。
????????????????????????代碼10?使用Struts?Tiles來(lái)封裝布局信息
<%
@?page?contentType
=
'
text/html;?charset=UTF-8'?%>
<
%@?taglib?uri
=
'
WEB-INF/tlds/struts-tiles.tld'?prefix='tiles'?%>
<
tiles:insert?definition
=
'
sidebar-header-footer-definition'/>
代碼11?struts
-
tiles.tld
<
!DOCTYPE?tiles
-
definitions?
PUBLIC
??
"
-//Apache?Software?Foundation//DTD?Tiles?Configuration//EN
"
??
"
http://jakarta.apache.org/struts/dtds/tiles-config.dtd
"
>
<
tiles
-
definitions
>
???
<
definition??name
=
'
sidebar-header-footer-definition'?
????????????????path
=
'
header-footer-sidebar-layout.jsp'>
??????
<
put?name
=
'
sidebar'?value='sidebar.jsp'/>
??????
<
put?name
=
'
header'??value='header.jsp'/>???
??????
<
put?name
=
'
content'?value='content.jsp'/>???
??????
<
put?name
=
'
footer'??value='footer.jsp'/>???
???
</
definition
>
</
tiles
-
definitions
>
在struts-tiles.tld中可以看到,網(wǎng)頁(yè)的布局被封裝在header-
footer-sidebar-layout.jsp中,而網(wǎng)頁(yè)的內(nèi)容被封裝在sidebar.jsp, header.jsp,
content.jsp和footer.jsp中(參見(jiàn)代碼7到代碼10)。代碼12列出了封裝了網(wǎng)頁(yè)布局的JSP。
????????????????????????????????????????代碼12?header-footer-sidebar-layout.jsp
<!
DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN"
>
<%
@?page?contentType
=
'
text/html;?charset=UTF-8'?%>
<
html
>
???
<
head
>
??????
<
title
>
Struts?Tiles?implements?the?Composite?pattern
</
title
>
???
</
head
>
???
<
body?background
=
'
graphics/blueAndWhiteBackground.gif'>
??????
<
%@?taglib?uri
=
'
/WEB-INF/tlds/struts-tiles.tld'?
??????????????prefix
=
'
tiles'%>
??????
<
%
--
?One?table?lays?out?all?of?the?content?
--
%>
??????
<
table?
width
='100%'?
height
='100%'
>
?????????
<%
--
?Sidebar?section?
--
%>
?????????
<
tr
>
????????????
<
td?
width
='150'?
valign
='top'?
align
='left'
>
???????????????
<
tiles:insert?
attribute
='sidebar'
/>
????????????
</
td
>
????????????
<%
--
?Main?content?section?
--
%>
????????????
<
td?
valign
='top'?
height
='100%'?
width
='*'
>
???????????????
<
table?
width
='100%'?
height
='100%'
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Header?section?
--
%>
?????????????????????
<
td?
height
='15%'
>
????????????????????????
<
tiles:insert?
attribute
='header'
/>
?????????????????????
</
td
>
??????????????????
<
tr
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Content?section?
--
%>
?????????????????????
<
td?
valign
='top'?
height
='*'
>
????????????????????????
<
tiles:insert?
attribute
='content'
/>
?????????????????????
</
td
>
??????????????????
</
tr
>
??????????????????
<
tr
>
?????????????????????
<%
--
?Footer?section?
--
%>
?????????????????????
<
td?
valign
='bottom'?
height
='15%'
>
????????????????????????
<
tiles:insert?
attribute
='footer'
/>
?????????????????????
</
td
>
??????????????????
</
tr
>
???????????????
</
table
>
????????????
</
td
>
?????????
</
tr
>
??????
</
table
>
???
</
body
>
</
html
>
如果你希望改變網(wǎng)頁(yè)的內(nèi)容,你可以定義另外一個(gè)Tile(如代碼13、14),更改其中與內(nèi)容相關(guān)的部分,但是保留網(wǎng)頁(yè)原有的布局,這樣重用布局和重用內(nèi)容的問(wèn)題都解決了。
????????????????????????????????????????????代碼13?另一個(gè)Tile的定義
<
tiles-definitions
>
???
<
definition??
name
='a-different-sidebar-header-footer-definition'?
????????????????
path
='header-footer-sidebar-layout.jsp'
>
??????
<
put?
name
='sidebar'?
value
='sidebar.jsp'
/>
??????
<
put?
name
='header'??
value
='header.jsp'
/>
???
??????
<
put?
name
='content'?
value
='someOtherContent.jsp'
/>
???
??????
<
put?
name
='footer'??
value
='footer.jsp'
/>
???
???
</
definition
>
</
tiles-definitions
>
????????????????
然后在<tiles:insert>標(biāo)簽中使用新定義的Tile,如代碼14所示
代碼14 使用新定義的Tiles <%@ page contentType='text/html; charset=UTF-8' %> <%@ taglib uri='WEB-INF/tlds/struts-tiles.tld' prefix='tiles' %> <tiles:insert definition='a-different-sidebar-header-footer-definition'/>
|
在Struts Tiles中使用復(fù)合模式
Struct Tiles實(shí)現(xiàn)了復(fù)合模式,在Struct
Tiles中,JSP就是圖1和圖2中提到的Component類(lèi),而Tiles的定義代表了Composite類(lèi)。這使開(kāi)發(fā)人員能夠指定一個(gè)JSP文件
或一個(gè)Tiles定義作為JSP頁(yè)面上某個(gè)區(qū)域中的內(nèi)容。代碼15展示了這個(gè)功能:
????????????????????????????????????????????代碼15在Struts?Tiles中使用復(fù)合模式
<!
DOCTYPE?tiles-definitions?PUBLIC
??"-//Apache?Software?Foundation//DTD?Tiles?Configuration//EN"
??"http://jakarta.apache.org/struts/dtds/tiles-config.dtd"
>
<
tiles-definitions
>
???
<
definition??
name
='sidebar-definition'?
????????????????
path
='sidebar-layout.jsp'
>
??????
<
put?
name
='top'????
value
='flags.jsp'
/>
??????
<
put?
name
='bottom'?
value
='sidebar-links.jsp'
/>
???
</
definition
>
???
<
definition??
name
='sidebar-header-footer-definition'?
????????????????
path
='header-footer-sidebar-layout.jsp'
>
??????
<
put?
name
='sidebar'?
value
='sidebar-definition'
???????????
type
='definition'
/>
??????
<
put?
name
='header'??
value
='header.jsp'
/>
??????
<
put?
name
='content'?
value
='content.jsp'
/>
??????
<
put?
name
='footer'??
value
='footer.jsp'
/>
???
</
definition
>
</
tiles-definitions
>
在上面的代碼中定義了兩個(gè)Tile:sidebar-definition和
sidebar-header-footer-definition。sidebar-definition被指定為sidebar-header-
footer-definition中Value屬性的值。這是一個(gè)很典型的復(fù)合模式的應(yīng)用。在前面的一些例子中,Value屬性的值通常是一個(gè)JSP文
件,而在這里,Value屬性的值是另一個(gè)Tile的定義。
小結(jié)
復(fù)合模式在與界面相關(guān)的設(shè)計(jì)中被經(jīng)常使用到,最明顯的例子就是Swing和Struts。由于它能夠使你以同樣的方式對(duì)待部件和包含部件的容器,因此在某些情況下可以大大提高代碼的可重用度,提高開(kāi)發(fā)的效率