标签:
由于抽象工厂在我们编程当中经常使用和常见,所有本篇文章对《大话设计模式》中的15章做了很详细的比较。通过一个Dao层可以更换访问任意数据库的例子来学习抽象工厂模式。例如:Dao层可以访问Sqlserver数据库,也可以访问Access数据库,当程序新增访问Oracle数据库时,无需修改现有代码,只需要添加访问Oracle相关的类就可以,实现了开闭原则。本篇文章的例子中每种数据库上都有User和Department表,我们Dao层对这两个表进行查询和插入操作。
一下是访问Sqlserver数据库的代码。
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}public class SqlserverUser{
public void insert(User user) {
System.out.println("SqlserverUser insert user");
}
public void getUser(int id) {
System.out.println("SqlserverUser get user");
}
}public class ClientTest {
public static void main(String [] args){
SqlserverUser su = new SqlserverUser();
su.getUser(1);
su.insert(new User());
}
}public interface IUser {
void insert(User user);
void getUser(int id);
}
public class SqlserverUser implements IUser {
@Override
public void insert(User user) {
System.out.println("SqlserverUser insert user");
}
@Override
public void getUser(int id) {
System.out.println("SqlserverUser get user");
}
}public class AccessUser implements IUser {
@Override
public void insert(User user) {
System.out.println("AccessUser insert user");
}
@Override
public void getUser(int id) {
System.out.println("AccessUser get user");
}
}
public interface IFactory {
IUser createUser();
}
public class SqlserverFacotry implements IFactory {
@Override
public IUser createUser() {
// TODO Auto-generated method stub
return new SqlserverUser();
}
}public class AccessFactory implements IFactory {
@Override
public IUser createUser() {
// TODO Auto-generated method stub
return new AccessUser();
}
}
public class ClientTest {
public static void main(String [] args){
IFactory factory = new SqlserverFacotry();
//IFactory factory = new AccessFactory();
IUser iu = factory.createUser();
iu.insert(new User());
iu.getUser(1);
}
}public class DataAccess {
private static String DB = "sqlserver";
public static IUser createUser(){
IUser user = null;
switch (DB) {
case "sqlserver":
user = new SqlserverUser();
break;
case "access":
user = new AccessUser();
break;
}
return user;
}
public static IDepartment createDepartment(){
IDepartment dep = null;
switch (DB) {
case "sqlserver":
dep = new SqlserverDepartment();
break;
case "access":
dep = new AccessDepartment();
break;
}
return dep;
}
}
public class DataAccess {
private static String DB = "sqlserver";
public static IUser createUser(){
IUser user = null;
switch (DB) {
case "sqlserver":
user = new SqlserverUser();
break;
case "access":
user = new AccessUser();
break;
}
return user;
}
public static IDepartment createDepartment(){
IDepartment dep = null;
switch (DB) {
case "sqlserver":
dep = new SqlserverDepartment();
break;
case "access":
dep = new AccessDepartment();
break;
}
return dep;
}
}
package fly.zxy.dhms.chapter15_8.factory;
import fly.zxy.dhms.chapter15_8.IDB.IDepartment;
import fly.zxy.dhms.chapter15_8.IDB.IUser;
public class DataAccess {
private static String DB = "sqlserver";
private static String packageBasePath = "fly.zxy.dhms.chapter15_8";
public static IUser createUser(){
String name = "User";
IUser iu =null;
iu = (IUser) ref( getPackagePath(name) );
return iu;
}
public static IDepartment createDepartment(){
String name = "Department";
IDepartment dep = null;
dep = (IDepartment) ref( getPackagePath(name) );
return dep;
}
private static String getPackagePath(String className){
//fly.zxy.dhms.chapter15_8.sqlserverDB
//fly.zxy.dhms.chapter15_8.accessDB
className = DB.substring(0,1).toUpperCase() + DB.substring(1, DB.length()) + className;
String path = packageBasePath+"."+DB+"DB"+"."+className;
return path;
}
private static Object ref(String className){
Object obj = null;
try {
Class<? extends Object> cls = Class.forName(className);
obj = cls.newInstance();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
}
由于使用了反射技术,我们在增加表的时候只需要在AccessData类中增加对应的方法,而方法中没有了一堆的switch case分支判断。新增对一种数据库的访问,无需再更改每个方法增加case语句了。解决了抽象工厂模式的缺点二。其实从某种角度来说,所有在使用简单工厂的地方,都可以考虑用反射来去除switch或if。
标签:
原文地址:http://blog.csdn.net/fly_zxy/article/details/51344663