?????????在學(xué)習(xí)Spring的過程中經(jīng)常看到一些大蝦推薦閱讀Rod_Johnson的<Expert_One-on-One_J2EE_Design_and_Development>書,據(jù)說此書的第四章每個學(xué)java人都要看看.好不容易搞到pdf版,可惜是E文的,中文的搞不到,沒辦法只好硬著頭皮看下去。
???第四章主要講的是面向?qū)ο蟮脑O(shè)計(jì)模式,怎么采用一致的編碼公約,怎么利用也有的系統(tǒng).這對于理解Spring框架有很大的幫助!因?yàn)檫@是Spring之父的編程思想。):
???關(guān)于接口的好處及組合模式的有點(diǎn),我這里就不說了。
???Template模式:適用范圍,我們知道某個業(yè)務(wù)或算法的步驟,但是不知道怎么把每步的順序。Template模式采用在abstract類中有個Public and final的方法封裝了調(diào)用每步的順序,也就是說控制了工作流程。所有的繼承類也就只要實(shí)現(xiàn)每步的具體方法。這是控制反轉(zhuǎn)的一種表現(xiàn),以前都是我們在程序中去調(diào)用API中的方法,現(xiàn)在是我們實(shí)現(xiàn)API某個類中的抽象方法給該類調(diào)用!這種控制反轉(zhuǎn)的機(jī)制,是框架的代碼基礎(chǔ).比如,EJB中的Init()和destory()方法等等.Spring框架中的對數(shù)據(jù)持久層的實(shí)現(xiàn)就是很好的例子!
下面把書中的例子COPY下:
? AbstractOrderEJB父類實(shí)現(xiàn)了商業(yè)邏輯,包括用戶是否金額超現(xiàn)和對大的訂單進(jìn)行打折,palceOrder()方法就是那個工作流方法。
abstract
?
class
?AbstractOrderEJB

{
????
public
?
final
?Invoice?placeOrder?(
int
?customerId,?InvoiceItem[]?items)
????????
throws
?NoSuchCustomerException,?SpendingLimitViolation?

????
{
????????
int
?total?
=
?
0
;
????????
for
?(
int
?i?
=
?
0
;?i?
<
?items.?length;?i
++
)?

????????
{
????????????total?
+=
?getItemPrice?(items?[i])?
*
?items?[i]?.getQuantity();
????????}
????????
if
?(total?
>
?getSpendingLimit?(customerId)?)

????????
{
????????????getSessionContext()?.setRollbackOnly();
????????????
throw
?
new
?SpendingLimitViolation?(total,?limit);
????????}
????????
else
?
if
?(total?
>
?DISCOUNT_THRESHOLD)?

????????
{
????????????
//
?Apply?discount?to?total
????????}
????????
int
?invoiceId?
=
?placeOrder?(customerId,?total,?items);
????????
return
?
new
?InvoiceImpl?(iid,?total);
????}
????
protected
?
abstract
?
int
?getItemPrice(InvoiceItem?item);

????
protected
?
abstract
?
int
?getSpendingLimit(customerId)
throws
?NoSuchCustomerException;

????
protected
?
abstract
?
int
?placeOrder(
int
?customerId,?
int
?total,InvoiceItem[]?items);
??}
???getItemPrice,getSpendingLimit,placeOrder這三個方法,是protected and abstract的,由子類來實(shí)現(xiàn)。
?? Strategey模式和Template模式比較相似.用Strategey模式對上個例子進(jìn)行改造:把三個單獨(dú)的方法放入一個接口中,工作流方法進(jìn)行如下修改:
?1
public
?
class
?OrderEJB
?2
{
?3
????
private
?DataHelper?dataHelper;
?4
????
public
?
void
?setDataHelper?(DataHelper?newDataHelper)?
?5
????
{
?6
????????
this
.dataHelper?
=
?newDataHelper;
?7
????}
?8
????
public
?
final
?Invoice?placeOrder?(
int
?customerId,?InvoiceItem[]?items)
?9
????????
throws
?NoSuchCustomerException,?SpendingLimitViolation?
10
????
{
11
????????
int
?total?
=
?
0
;
12
????????
for
?(
int
?i?
=
?
0
;?i?
<
?items.length;?i
++
)?
13
????????
{
14
????????????total?
+=
?
this
.dataHelper.getItemPrice(items[i])?
*
15
????????????items[i].getQuantity();
16
????????}
17
????????
if
?(total?
>
?
this
.dataHelper.getSpendingLimit(customerId))?
18
????????
{
19
????????????getSessionContext()?.setRollbackOnly();
20
????????????
throw
?
new
?SpendingLimitViolation(total,?limit);
21
????????}
?
22
????????
else
?
if
?(total?
>
?DISCOUNT_THRESHOLD)?
23
????????
{
24
????????????
//
?Apply?discount?to?total
25
????????}
26
????????
int
?invoiceId?
=
?
this
.dataHelper.placeOrder?(customerId,?total,?items);
27
????????
return
?
new
?InvoiceImpl?(iid,?total);
28
????}
29
}
???Stratery模式比Temlater模式復(fù)雜點(diǎn),但是它具有更高的靈活性,對于實(shí)際項(xiàng)目一些流程的控制有很好的作用!這是本人的觀點(diǎn),不一定正確,僅供參考。
???
在下面的情況下,用Stratery模式比Temlater模式更好:
1,每步都是可變的
2,實(shí)現(xiàn)每步的類需要一個獨(dú)立的繼承體系
3,實(shí)現(xiàn)每步的類要和其他的類打交道
4,實(shí)現(xiàn)每步的類要實(shí)現(xiàn)多態(tài)性
備注:本文主要內(nèi)容來源于Rod_Johnson的大作,強(qiáng)烈建議看原版!