?????????在學習Spring的過程中經??吹揭恍┐笪r推薦閱讀Rod_Johnson的<Expert_One-on-One_J2EE_Design_and_Development>書,據說此書的第四章每個學java人都要看看.好不容易搞到pdf版,可惜是E文的,中文的搞不到,沒辦法只好硬著頭皮看下去。
???第四章主要講的是面向對象的設計模式,怎么采用一致的編碼公約,怎么利用也有的系統.這對于理解Spring框架有很大的幫助!因為這是Spring之父的編程思想。):
???關于接口的好處及組合模式的有點,我這里就不說了。
???Template模式:適用范圍,我們知道某個業務或算法的步驟,但是不知道怎么把每步的順序。Template模式采用在abstract類中有個Public and final的方法封裝了調用每步的順序,也就是說控制了工作流程。所有的繼承類也就只要實現每步的具體方法。這是控制反轉的一種表現,以前都是我們在程序中去調用API中的方法,現在是我們實現API某個類中的抽象方法給該類調用!這種控制反轉的機制,是框架的代碼基礎.比如,EJB中的Init()和destory()方法等等.Spring框架中的對數據持久層的實現就是很好的例子!
下面把書中的例子COPY下:
? AbstractOrderEJB父類實現了商業邏輯,包括用戶是否金額超現和對大的訂單進行打折,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的,由子類來實現。
?? Strategey模式和Template模式比較相似.用Strategey模式對上個例子進行改造:把三個單獨的方法放入一個接口中,工作流方法進行如下修改:
?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模式復雜點,但是它具有更高的靈活性,對于實際項目一些流程的控制有很好的作用!這是本人的觀點,不一定正確,僅供參考。
???
在下面的情況下,用Stratery模式比Temlater模式更好:
1,每步都是可變的
2,實現每步的類需要一個獨立的繼承體系
3,實現每步的類要和其他的類打交道
4,實現每步的類要實現多態性
備注:本文主要內容來源于Rod_Johnson的大作,強烈建議看原版!