在学习Spring的过程中经常看到一些大虾推荐阅读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的大作,强烈建议看原版!