抽象工厂模式(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();
}
}