抽象工厂

简单工厂以及工厂方法在上篇博客中有提到

引言

有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);
	}
}

暂时就写到这,以后有补充再加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值