研磨设计模式 之 代理模式(Proxy)1――跟着cc学设计系列(一)

2014-11-24 03:17:02 · 作者: · 浏览: 0

11.1 场景问题

11.1.1 访问多条数据

考虑这样一个实际应用:要一次性访问多条数据。

这个功能的背景是这样的;在一个HR(人力资源)应用项目中客户提出,当选择一个部门或是分公司的时候,要把这个部门或者分公司下的所有员工都显示出来,而且不要翻页,好方便他们进行业务处理。在显示全部员工的时候,只需要显示名称即可,但是也需要提供如下的功能:在必要的时候可以选择并查看某位员工的详细信息。

客户方是一个集团公司,有些部门或者分公司可能有好几百人,不让翻页,也就是要求一次性的获取这多条数据并展示出来。

该怎么样实现呢?

11.1.2 不用模式的解决方案

不就是要获取某个部门或者某个分公司下的所有员工的信息吗?直接使用sql语句从数据库中查询就可以得到,示意性的SQL大致如下:

String sql = "select * from 用户表,部门表 "

+"where 用户表.depId=部门表.depId "

+"and 部门表.depId like '"+用户选择查看的depId+"%'";

为了方便获取某个部门或者某个分公司下的所有员工的信息,设计部门编号的时候,是按照层级来进行编码的,比如:上一级部门的编码为“01”,那么本级的编码就是“0101”、“0102”……以此类推,下一级的编码就是“010101”、“010102”……。

这种设计方式,从设计上看虽然不够优雅,但是实用,像这种获取某个部门或者某个分公司下的所有员工的信息的功能,就不用递归去查找了,直接使用like,只要找到以该编号开头的所有部门就可以了。

示例涉及到的表有两个,一个是用户表,一个是部门表。两个表需要描述的字段都较多,尤其是用户表,多达好几十个,为了示例简洁,简化后简单的定义如下:

DROP TABLE TBL_USER CASCADE CONSTRAINTS ;

DROP TABLE TBL_DEP CASCADE CONSTRAINTS ;

CREATE TABLE TBL_DEP (

DEPID VARCHAR2(20) PRIMARY KEY,

NAME VARCHAR2(20)

);

CREATE TABLE TBL_USER (

USERID VARCHAR2(20) PRIMARY KEY,

NAME VARCHAR2(20) ,

DEPID VARCHAR2(20) ,

SEX VARCHAR2(10) ,

CONSTRAINT TBL_USER_FK FOREIGN KEY(DEPID)

REFERENCES TBL_DEP(DEPID)

);

全部采用大写,是基于Oracle开发的习惯。再来增加点测试数据,SQL如下:

INSERT INTO TBL_DEP VALUES('01','总公司');

INSERT INTO TBL_DEP VALUES('0101','一分公司');

INSERT INTO TBL_DEP VALUES('0102','二分公司');

INSERT INTO TBL_DEP VALUES('010101','开发部');

INSERT INTO TBL_DEP VALUES('010102','测试部');

INSERT INTO TBL_DEP VALUES('010201','开发部');

INSERT INTO TBL_DEP VALUES('010202','客服部');

INSERT INTO TBL_USER VALUES('user0001','张三1','010101','男');

INSERT INTO TBL_USER VALUES('user0002','张三2','010101','男');

INSERT INTO TBL_USER VALUES('user0003','张三3','010102','男');

INSERT INTO TBL_USER VALUES('user0004','张三4','010201','男');

INSERT INTO TBL_USER VALUES('user0005','张三5','010201','男');

INSERT INTO TBL_USER VALUES('user0006','张三6','010202','男');

COMMIT;

准备好了表结构和测试数据,下面来看看具体的实现示例,为了示例的简洁,直接使用JDBC来完成。

(1)先来定义描述用户数据的对象,示例代码如下:

/**

* 描述用户数据的对象

*/

public class UserModel {

/**

* 用户编号

*/

private String userId;

/**

* 用户姓名

*/

private String name;

/**

* 部门编号

*/

private String depId;

/**

* 性别

*/

private String sex;

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getDepId() {

return depId;

}

public void setDepId(String depId) {

this.depId = depId;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public String toString(){

return "userId="+userId+",name="+name+",depId="

+depId+",sex="+sex+"\n";

}

}

(2)接下来使用JDBC来实现要求的功能,示例代码如下:

/**

* 实现示例要求的功能

*/

public class UserManager {

/**

* 根据部门编号来获取该部门下的所有人员

* @param depId 部门编号

* @return 该部门下的所有人员

*/

public Collection getUserByDepId(

String depId)throws Exception{

Collection col = new ArrayList ();

Connection conn = null;

try{

conn = this.getConnection();

String sql = "select * from tbl_user u,tbl_dep d "

+"where u.depId=d.depId and d.depId like ";

PreparedStatement pstmt = conn.prepareStatement(sql);

pstmt.setString(1, depId+"%");

ResultSet rs = pstmt.executeQuery();

while(rs.next()){

UserModel um = new UserModel();

um.setUserId(rs.getString("userId"));

um.setName(rs.getString("name"));

um.setDepId(rs.getString("depId"));

um.setSex(rs.getString("sex"))