onnection c) throws SQLException {
Statement stmt = c.createStatement();
return stmt.executeQuery(getSqlForEntity());
}
演化架构与紧急设计: 组合方法和 SLAP(3)
时间:2011-07-13 IBM Neal Ford
这很有意思。是否还能把更多的方法从子类提升到通用的父类中?如果看一下 清单 2 中的 populate() 方法本身,可以看出它与 PartDb 类的连接点是 getDatabaseConnection()、createResultSet() 和 addPartToListFromResultSet() 方法。前两个方法已经转移到父类中了。 如果对 addPartToListFromResultSet() 方法进行抽象(并使用适当的更通用的名称),就可以把整个 populate() 方法放到父类中,见清单 4:
清单 4. BoundaryBase 类
abstract public class BoundaryBase {
private static final String DRIVER_CLASS =
"com.mysql.jdbc.Driver";
private static final String DB_URL =
"jdbc:mysql://localhost/orderentry";
protected Connection getDatabaseConnection() throws ClassNotFoundException,
SQLException {
Connection c;
Class.forName(DRIVER_CLASS);
c = DriverManager.getConnection(DB_URL, "webuser", "webpass");
return c;
}
abstract protected String getSqlForEntity();
protected ResultSet createResultSet(Connection c) throws SQLException {
Statement stmt = c.createStatement();
return stmt.executeQuery(getSqlForEntity());
}
abstract protected void addEntityToListFromResultSet(ResultSet rs)
throws SQLException;
public void populate() throws Exception {
Connection c = null;
try {
c = getDatabaseConnection();
ResultSet rs = createResultSet(c);
while (rs.next())
addEntityToListFromResultSet(rs);
} finally {
c.close();
}
}
}
把这些方法提升到父类中之后,PartDb 类已经大大简化了,见清单 5:
清单 5. 简化和重构后的 PartDb 类
public class PartDb extends BoundaryBase {
private static final int DEFAULT_INITIAL_LIST_SIZE = 40;
private static final String SQL_SELECT_PARTS =
"select name, brand, retail_price from parts";
private static final Part[] TEMPLATE = new Part[0];
private ArrayList partList;
public PartDb() {
partList = new ArrayList(DEFAULT_INITIAL_LIST_SIZE);
}
public Part[] getParts() {
return (Part[]) partList.toArray(TEMPLATE);
}
protected String getSqlForEntity() {
return SQL_SELECT_PARTS;
}
protected void addEntityToListFromResultSet(ResultSet rs)
throws SQLException {
Part p = new Part();
p.setName(rs.getString("name"));
p.setBrand(rs.getString("brand"));
p.setRetailPrice(rs.getDouble("retail_price"));
partList.add(p);
}
}
我通过前面的重构得到了什么?首先, |