引言
有3家企业依次找到你,让你帮他们设计一个网站,分别用oracle,sql server,mysql作为数据库,这3家企业要求设计网站内容大差不差,如果是你?在刚开始设计网站的时候你会怎么做?
用hibernate,更换数据库只需要在配置的时候更换方言就好了,如果没有hibernate呢?那就用jdbc,但是如何设计才能保证工作量小一点呢?
工厂方法
public interface IFactory {
UserDao CreateUser();
}
public class SqlServerFactory implements IFactory {
public UserDao CreateUser() {
return new SqlServerUser();
}
}
public class MysqlFactory implements IFactory {
public UserDao CreateUser() {
return new MysqlUser();
}
}
public interface UserDao {
void insert(User user);
User getUser(int id);
}
public class SqlServerUser implements UserDao {
public void insert(User user) {
System.out.println("在SqlServer中插入一条记录");
}
public User getUser(int id) {
System.out.println("在SqlServer中得到一条记录");
return null;
}
}
public class MysqlUser implements UserDao {
public void insert(User user) {
System.out.println("在Mysql中插入一条记录");
}
public User getUser(int id) {
System.out.println("在Mysql中得到一条记录");
return null;
}
}
但是数据库里面怎么可能只有一张用户User表呢?可能还有department部门表等其他表,那该如何办呢?
抽象工厂
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
优点:客户端只需要改变具体工厂就可以使用不同的产品配置;创建实例的过程与客户端分离,客户端通过它们的抽象接口来操纵实例。
缺点:我们现在增添role角色表,那么就需要添加RoleDao,SqlServerRole,MysqlRole,OracleRole,除此之外,还需要修改SqlServerFactory,MySqlFactory,OracleFactory,需要改动的地方太多了。
用简单工厂改进抽象工厂
public class DataAccess {
private static final String DATASOURCE = "SqlServer";
public static UserDao createUser() {
UserDao dao = null;
switch (DATASOURCE) {
case "SqlServer":
dao = new SqlServerUser();
break;
case "Mysql":
dao = new MysqlUser();
break;
default:
break;
}
return dao;
}
public static DepartmentDao createDepart() {
DepartmentDao dao = null;
switch (DATASOURCE) {
case "SqlServer":
dao = new SqlServerDepart();
break;
case "Mysql":
dao = new MysqlDepart();
break;
default:
break;
}
return dao;
}
public static void main(String[] args) {
User user = new User();
Department department = new Department();
//插入用户数据
UserDao userDao = DataAccess.createUser();
userDao.insert(user);
//插入部门数据
DepartmentDao departmentDao = DataAccess.createDepart();
departmentDao.insert(department);
}
}
用DataAccess取代了上面的SqlServerFactory,MysqlFactory,OracleFactory这三个工厂类,当添加Role角色表时,只要需进行添加动作而不需要修改,但是仍然存在问题,当需要添加新的数据库访问时,就必须修改case条件语句,这就违背了开放封闭原则,那应该怎么做呢?
反射 + 配置文件
public class DataAccess2 {
private static String dataSource = null;
static {
Properties prop = new Properties();
try {
prop.load(DataAccess2.class.getClassLoader().getResourceAsStream("dataSource.properties"));
dataSource = prop.getProperty("dataSource");
} catch (IOException e) {
e.printStackTrace();
}
}
public static UserDao createUser() {
String className = dataSource + "User";
UserDao dao = null;
try {
dao = (UserDao) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return dao;
}
public static DepartmentDao createDepart() {
String className = dataSource + "Depart";
DepartmentDao dao = null;
try {
dao = (DepartmentDao) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return dao;
}
public static void main(String[] args) {
User user = new User();
Department department = new Department();
//插入用户数据
UserDao userDao = DataAccess2.createUser();
userDao.insert(user);
//插入部门数据
DepartmentDao departmentDao = DataAccess2.createDepart();
departmentDao.insert(department);
}
}
暂时就写到这,以后有补充再加