一、介绍
抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同的实现;
IFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。
通常是在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。
二、代码实现
需求:有两种数据库(mysql、access)需要插入数据和查询数据,SQL有区别。
基础类
public class User { private int _id; private String _name; public int get_id() { return _id; } public void set_id(int _id) { this._id = _id; } public String get_name() { return _name; } public void set_name(String _name) { this._name = _name; } } public class Department { private int _id; private String _name; public int get_id() { return _id; } public void set_id(int _id) { this._id = _id; } public String get_name() { return _name; } public void set_name(String _name) { this._name = _name; } }
产品类
//抽象产品 public interface IUser { public void insert(User user); public User getUser(int id); } //抽象产品 public interface IDepartment { public void insert(Department department); public Department getDepartment(int id); } public class AccessDepartment implements IDepartment { //新增用户 @Override public void insert(Department user){ System.out.println("在Access中给Department表增加一条记录"); } @Override public Department getDepartment(int id) { System.out.println("在Access中根据用户ID得到一条记录"); return null; } } public class AccessUser implements IUser { //新增用户 @Override public void insert(User user){ System.out.println("在Access中给User表增加一条记录"); } //查询用户 @Override public User getUser(int id){ System.out.println("在Access中根据用户ID得到一条记录"); return null; } } public class SqlserverDepartment implements IDepartment { //新增用户 @Override public void insert(Department department){ System.out.println("在SQL Server中给Department表增加一条记录"); } //查询用户 @Override public Department getDepartment(int id){ System.out.println("在SQL Server中根据用户ID得到一条记录"); return null; } } public class SqlserverUser implements IUser { //新增用户 @Override public void insert(User user){ System.out.println("在SQL Server中给User表增加一条记录"); } //查询用户 @Override public User getUser(int id){ System.out.println("在SQL Server中根据用户ID得到一条记录"); return null; } }
厂类
//抽象工厂 public interface IFactory { public IUser createUser(); public IDepartment createDepartment(); } //具体工厂 public class AccessFactory implements IFactory{ @Override public IUser createUser() { return new AccessUser(); } @Override public IDepartment createDepartment() { return new AccessDepartment(); } } //具体工厂 public class SqlserverFactory implements IFactory{ @Override public IUser createUser() { return new SqlserverUser(); } @Override public IDepartment createDepartment() { return new SqlserverDepartment(); } }
测试代码
两种数据切换只需切换具体工厂类
//客户端 public class Client { public static void main(String[] args) { //数据 User user = new User(); Department department = new Department(); //IFactory sqlserverFactory = new AccessFactory(); IFactory sqlserverFactory = new SqlserverFactory(); IUser sqlUser = sqlserverFactory.createUser(); sqlUser.insert(user); sqlUser.getUser(1); IDepartment sqlDepartment = sqlserverFactory.createDepartment(); sqlDepartment.insert(department); sqlDepartment.getDepartment(1); } }
在Access中给User表增加一条记录 在Access中根据用户ID得到一条记录 在Access中给Department表增加一条记录 在Access中根据用户ID得到一条记录 在SQL Server中给User表增加一条记录 在SQL Server中根据用户ID得到一条记录 在SQL Server中给Department表增加一条记录 在SQL Server中根据用户ID得到一条记录
调试小技巧:使用Ctrl+Alt点击进入实现类的方法。
随着产品越来越多,可以使用反射,取消工厂类的维护:
import java.lang.reflect.InvocationTargetException; public class FactoryAll { private String db; public FactoryAll(String db) { this.db = db; } public IUser createUser(){ IUser result=null; try { result=(IUser)Class.forName("org.minos.chapter15.inter.impl"+"."+db+"User").getDeclaredConstructor().newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (SecurityException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } return result; } public IDepartment createDepartment() { IDepartment result=null; try { result=(IDepartment)Class.forName("org.minos.chapter15.inter.impl"+"."+db+"Department").getDeclaredConstructor().newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (SecurityException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } return result; } }
public static void main(String[] args) { //数据 User user = new User(); Department department = new Department(); //IFactory sqlserverFactory = new AccessFactory(); FactoryAll sqlserverFactory = new FactoryAll("Sqlserver"); //IFactory sqlserverFactory = new SqlserverFactory(); IUser sqlUser = sqlserverFactory.createUser(); sqlUser.insert(user); sqlUser.getUser(1); IDepartment sqlDepartment = sqlserverFactory.createDepartment(); sqlDepartment.insert(department); sqlDepartment.getDepartment(1); }
在SQL Server中给User表增加一条记录 在SQL Server中根据用户ID得到一条记录 在SQL Server中给Department表增加一条记录 在SQL Server中根据用户ID得到一条记录