演化架构与紧急设计: 组合方法和 SLAP
2009-11-05 00:00:00 来源:WEB开发网addOrder() 方法中有许多杂乱的东西。但是,我感兴趣的是接近 try 块开头的工作流。请注意下面这两行:
c.setAutoCommit(false);
addSingleOrder(order, c, ps, userKey);
这两行代码违反了 SLAP 原则。第一行(和它上面的方法)处理设置数据库基础结构的低层细节。第二行是高层的订单方法,业务分析师会理解它。这两行属于两个不同的领域。如果必须在抽象层之间转移,阅读代码会很困难,这正是 SLAP 原则试图避免的情况。可读性问题导致难以理解代码的底层设计,因此难以分离这个应用程序中的惯用模式。
为了改进 清单 6 中的代码,我要根据 SLAP 原则重构它。在经过两轮提取方法 重构之后,得到了清单 7 中的代码:
清单 7. 改进抽象后的 addOrder() 方法public void addOrderFrom(ShoppingCart cart, String userName,
Order order) throws SQLException {
setupDataInfrastructure();
try {
add(order, userKeyBasedOn(userName));
addLineItemsFrom(cart, order.getOrderKey());
completeTransaction();
} catch (SQLException sqlx) {
rollbackTransaction();
throw sqlx;
} finally {
cleanUp();
}
}
private void setupDataInfrastructure() throws SQLException {
_db = new HashMap();
Connection c = dbPool.getConnection();
_db.put("connection", c);
_db.put("transaction state",
Boolean.valueOf(setupTransactionStateFor(c)));
}
private void cleanUp() throws SQLException {
Connection connection = (Connection) _db.get("connection");
boolean transactionState = ((Boolean)
_db.get("transation state")).booleanValue();
Statement s = (Statement) _db.get("statement");
PreparedStatement ps = (PreparedStatement)
_db.get("prepared statement");
ResultSet rs = (ResultSet) _db.get("result set");
connection.setAutoCommit(transactionState);
dbPool.release(connection);
if (s != null)
s.close();
if (ps != null)
ps.close();
if (rs != null)
rs.close();
}
private void rollbackTransaction()
throws SQLException {
((Connection) _db.get("connection")).rollback();
}
private void completeTransaction()
throws SQLException {
((Connection) _db.get("connection")).commit();
}
private boolean setupTransactionStateFor(Connection c)
throws SQLException {
boolean transactionState = c.getAutoCommit();
c.setAutoCommit(false);
return transactionState;
}
更多精彩
赞助商链接