`

大话设计模式十五:抽象工厂模式(就不能不换DB吗?)

 
阅读更多

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

//Department类
public class Department
{
	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;
	}
}
//IDepartment接口,用于客户端访问,解除与具体数据库访问的耦合
public interface IDepartment
{
	void insert(Department department);

	Department getDepartment(int id);
}
//SqlServerDepartment类,用于访问SQL Server的Department
public class SqlServerDepartment implements IDepartment
{
	public void insert(Department department)
	{
		System.out.println("在SQL Server中给Deaprtment表增加一条记录");
	}

	public Department getDepartment(int id)
	{
		System.out.println("在SQL Server中根据ID得到Deaprtment表一条记录");
		return null;
	}
}
//AccessDepartment类,用于访问Access的Department
public class AccessDepartment implements IDepartment
{
	public void insert(Department department)
	{
		System.out.println("在Access中给Deaprtment表增加一条记录");
	}

	public Department getDepartment(int id)
	{
		System.out.println("在Access中根据ID得到Deaprtment表一条记录");
		return null;
	}
}
//IFactory接口,定义一个创建访问User表对象的抽象工厂接口
public interface IFactory
{
	IUser createUser();

	IDepartment createDepartment();
}
//SqlServerFactory类,实现IFactory接口,实例化SqlServerUser和SqlServerDepartment
public class SqlServerFactory implements IFactory
{
	public IUser createUser()
	{
		return new SqlServerUser();
	}

	public IDepartment createDepartment()
	{
		return new SqlServerDepartment();
	}
}
//AccessFactory类,实现IFactory接口,实例化AccessUser和AccessDepartment
public class AccessFactory implements IFactory
{
	public IUser createUser()
	{
		return new AccessUser();
	}

	public IDepartment createDepartment()
	{
		return new AccessDepartment();
	}
}
//客户端代码
public class Main
{
	public static void main(String[] args)
	{
		User user = new User();
		Department department = new Department();

		// IFactory factory = new SqlServerFactory();
		
		IFactory factory = new AccessFactory();

		IUser iu = factory.createUser();

		iu.insert(user);
		iu.getUser(1);

		IDepartment id = factory.createDepartment();

		id.insert(department);
		id.getDepartment(1);
	}
}
结果显示:
在Access中给User表增加一条记录
在Access中根据ID得到User表一条记录
在Access中给Deaprtment表增加一条记录
在Access中根据ID得到Deaprtment表一条记录


抽象工厂模式的优缺点:

优点:易于交换产品系列,由于具体工厂类,例如IFactory factory = new AccessFactory(),在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置,现在如果你要更改数据库访问,我们只需要更改具体的工厂就可以做到了。第二大好处在于,它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。

缺点:抽象工厂模式可以很方便地切换两个数据库访问的代码,但是如果你的需求来自增加功能,比如我们现在要增加项目表Project,那就要至少增加三个类,Iproject、SqlServerProject、AccessProject,还需要更改IFactory、SqlServerFactory和AccessFactory才可以完全实现。


配置文件配置db,根据db加载类,动态加载生成User和Department接口实例

package AbstractFactory;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

/**
 * dbPriority.priority文件中包含db的配置
 * db=Oracle
 */
public class MainClass {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		User user = DataAccess.createUser();
		user.insert("user");
		user.getUser();
		
		Department department = DataAccess.createDepartment();
		department.insert("department");
		department.getDepartment();
	}
}

interface User {
	public void insert(String user);
	public void getUser();
}

class AccessUser implements User {

	@Override
	public void insert(String user) {
		// TODO Auto-generated method stub
		System.out.println("Access insert User");
	}

	@Override
	public void getUser() {
		// TODO Auto-generated method stub
		System.out.println("Access get User");
	}
}

class OracleUser implements User {

	@Override
	public void insert(String user) {
		// TODO Auto-generated method stub
		System.out.println("Oracle insert User");
	}

	@Override
	public void getUser() {
		// TODO Auto-generated method stub
		System.out.println("Oracle get User");
	}
}

interface Department {
	public void insert(String department);
	public void getDepartment();
}

class AccessDepartment implements Department {

	@Override
	public void insert(String department) {
		// TODO Auto-generated method stub
		System.out.println("Access insert department");
	}

	@Override
	public void getDepartment() {
		// TODO Auto-generated method stub
		System.out.println("Access get Department");
	}
	
}

class OracleDepartment implements Department {

	@Override
	public void insert(String department) {
		// TODO Auto-generated method stub
		System.out.println("Oracle insert department");
	}

	@Override
	public void getDepartment() {
		// TODO Auto-generated method stub
		System.out.println("Oracle get Department");
	}
}

class DataAccess {
	static {
		Properties properties = new Properties();
		try (FileReader freader = new FileReader("src\\AbstractFactory\\dbProperty.property")) {
			properties.load(freader);
			db = properties.getProperty("db");
			System.out.println(DataAccess.db);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private static String db;
	
	public static User createUser() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		return (User) Class.forName("AbstractFactory."+db+"User").newInstance();
	}
	
	public static Department createDepartment() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		return (Department) Class.forName("AbstractFactory."+db+"Department").newInstance();
	}
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics