码迷,mamicode.com
首页 > 其他好文 > 详细

企业应用架构模式-事物脚本

时间:2015-06-12 14:40:16      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:

 概述: 使用过程来组织业务逻辑,每个过程处理来自表现层的单个请求

特点
(1) 以数据为中心(输入->查询->处理->输出),典型的面向过程思想)
(2) 代码简单,易懂
(3) 适合项目不大的开发
(4) 业务逻辑和领域逻辑夹杂在事物脚本中,容易产生冗余数据

组织方式
(1) 一个类处理一类事物脚本,我们非常熟悉的编程方式

 1 public class Gateway{
 2     private  static final String findRecognitionsStatement = "select amount from revenueRecognitions where contract = ? and recognizedOn <= ?"
 3     private  static final String findContractStatement = "select * from contracts c,product p where id = ? and c.product = p.id"; 
 4     private  static final String insertRecognitionStatement = "insert into revenueRecognitions values(?,?,?)";
 5     private Connection _db;
 6     public ResultSet findRecognitionsFor(long contractId,Date asof) throws SQLException{
 7             PreparedStatement stmt = db.preparedStatement(findRecognitionsStatement);
 8             stmt.setLong(1,contractId);
 9             stmt.setDate(2,asof);
10             return stmt.executeQuery();
11     }
12     public ResultSet findContract(long contractId)throws SQLException{
13             PreparedStatement stmt = db.preparedStatement(findContractStatement);
14             stmt.setLong(1,contractId);
15             return stmt.executeQuery();
16     }
17     public void insertRecognition(long contractId,Money amount,Date asof) throws SQLException{
18         PreparedStatement stmt = _db.preparedStatement(insertRecognitionStatement);
19         stmt.setLong(1,contractId);
20         stmt.setBigDecimal(2,amount.amount());
21         stmt.setDate(3,asof);
22         stmt.executeUpdate();
23     }
24 }

 

class RecognitionService{
	private Gateway _db;
	public Money recognizedRevenue(long contractNumber,Date asof){
			Money result = Money.dollar(0);
			try{
				ResultSet rs = _db.findRecognitionsFor(contractNumber,asof);
				while(rs.next()){
					 result = result.add(Money.dollars(rs.getBigDecimal("amount")));
				}
				return result;
			}catch(Exception ex){
				throw new RuntimeException(ex);
			}
	 }
	 public void calculateRevenueRecognitions(long contractNumber){
			try{
				ResultSet contracts = _db.findContract(contractNumber);
				contracts.next();
				Money totalRevenue = Money.dollars(contracts.getBigDecimal("revenue"));
				Date recognitionDate = new Date(contracts.getDate("dataSigned"));
				String type = contracts.getString("type");
				if(type.equals("S")){
						Money[] allocation = totalRevenue.allocate(3);
						_db.insertRecognition(contractNumber,allocation[0],recognitionDate);
						_db.insertRecognition(contractNumber,allocation[1],recognitionDate.addDays(60));
						_db.insertRecognition(contract,allocation[2],recognitionDate.addDays(90));
				}else if(type.equals("W")){
						_db.insertRecognition(contractNumber,totalRevenue,recognitionDate);
				}else if(type.equals("D")){
						Money[] allocation = totalRevenue.allocate(3);
						_db.insertRecognition(contractNumber,allocation[0],recognitionDate);
						_db.insertRecognition(contractNumber,allocation[1],recognitionDate.addDays(30));
						_db.insertRecognition(contract,allocation[2],recognitionDate.addDays(60));
				}
			}catch(Exception ex){
				throw new RuntimeException(ex);
			}
	  }
}

 


(2) 一个类处理一个事物脚本,这种方式可以以命令模式方式组织. Command pattern

 

1     interface transactionScript{ Object run() }

 


  

 1 class recognizedRevenueTransationScript implements TransationScript{
 2         private long _contractNumber;
 3         private Date _asof;
 4         public recognizedRevenueTransationScript(long contractNumber,Date asof){
 5                 _contractNumber = contractNumber;
 6                 _asof = asof;
 7         }
 8         public Object run(){
 9             Money result = Money.dollar(0);
10             try{
11                 ResultSet rs = _db.findRecognitionsFor(_contractNumber,_asof);
12                 while(rs.next()){
13                      result = result.add(Money.dollars(rs.getBigDecimal("amount")));
14                 }
15                 return result;
16             }catch(Exception ex){
17                 throw new RuntimeException(ex);
18             }
19         }
20     
21 }
 1 class calculateRevenueRecognitionsTransationScript implements TransationScript{
 2         private long _contractNumber;
 3         
 4         public calculateRevenueRecognitionsTransationScript(long contractNumber){
 5                 _contractNumber = contractNumber;
 6                 _asof = asof;
 7         }
 8         public Object run(){
 9             try{
10                 ResultSet contracts = _db.findContract(contractNumber);
11                 contracts.next();
12                 Money totalRevenue = Money.dollars(contracts.getBigDecimal("revenue"));
13                 Date recognitionDate = new Date(contracts.getDate("dataSigned"));
14                 String type = contracts.getString("type");
15                 if(type.equals("S")){
16                         Money[] allocation = totalRevenue.allocate(3);
17                         _db.insertRecognition(contractNumber,allocation[0],recognitionDate);
18                         _db.insertRecognition(contractNumber,allocation[1],recognitionDate.addDays(60));
19                         _db.insertRecognition(contract,allocation[2],recognitionDate.addDays(90));
20                 }else if(type.equals("W")){
21                         _db.insertRecognition(contractNumber,totalRevenue,recognitionDate);
22                 }else if(type.equals("D")){
23                         Money[] allocation = totalRevenue.allocate(3);
24                         _db.insertRecognition(contractNumber,allocation[0],recognitionDate);
25                         _db.insertRecognition(contractNumber,allocation[1],recognitionDate.addDays(30));
26                         _db.insertRecognition(contract,allocation[2],recognitionDate.addDays(60));
27                 }
28             }catch(Exception ex){
29                 throw new RuntimeException(ex);
30             }
31             return null;
32         }
33     
34 }

 
    
现在大多数公司都是用这种方式开发软件,原因有以下几点

(1) 本质业务并不复杂
(2) 学习成本低(以数据为中心的编程方式不用考虑抽象,多态等一些问题)
(3) 这种开发方式已经被大多数公司认定为开发标准
(4) 公司不看重开发过程,只看最终结果

总结 :
    这种开发方式是典型的经典的面向过程开发方式,在业务不复杂的时候可以非常好的解决
 业务问题。
 由于一个功能执行一个脚本,随着业务不断复杂,必定会出现冗余代码. 
 比如转账业务和取钱业务,都会出现相同的查询账户和验证。
 可以通过抽取方法,或提取公共类解决相应的问题,
 可是增加了复杂度,违背了事物脚本简单的初衷。

企业应用架构模式-事物脚本

标签:

原文地址:http://www.cnblogs.com/freebird2014/p/4571041.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!