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