逝去的青春

勇往直前

Template模式和Strategey模式

         在学习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的大作,强烈建议看原版!

posted on 2006-03-29 20:49 逝去的年华 阅读(1475) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航: