抽象工厂模式(Abstract Factory)
定义
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
UML
各部分介绍
AbstractProductA
、AbstractProductB
:两个抽象的产品,之所以抽象,是因为这两个产品可能具有不同的实现 ProductA1
、ProductA2
、ProductB1
、ProductB2
:对两个抽象产品的具体分类的实现。 AbstractFactory
:抽象工厂类,它里面应该包含所有的产品创建的抽象方法。 ConcreteFactory1
、ConcreteFactory1
:具体的工厂
一般的使用特点,通常是在运行的时刻再创建一个ConcreteFactory
类的实例,这个具体的工厂再创建具有特定实现的产品对象。也就是说,为创建不同的产品对象,客户端应该使用不同的具体工厂。
具体实例代码
interface IFactory { /** * 创建使用者的抽象方法 * @return :返回使用者 * */ IUser createUser(); /** * 创建部门的抽象方法 * @return :返回创建部门 * */ IDepartment createDepartment(); }
public class AccessFactory implements IFactory { @Override public IUser createUser() { return new AccessUser(); } @Override public IDepartment createDepartment() { return new AccessServerDepartment(); } }
public class SqlServerFactory implements IFactory{ @Override public IUser createUser() { return new SqlServerUser(); } @Override public IDepartment createDepartment() { return new SqlServerDepartment(); } }
public interface IUser { /** * 用户表中增加内容 * @param user :增加使用者 * */ void insert(User user); /** * 获取用户 * @param id :通过id获取用户 * */ User getUser(int id); }
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中从User表得到一条记录"); 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中从User表得到一条记录"); return null; } }
public interface IDepartment { /** * @param department :增加部门 * * */ void insert(Department department); /** * @param id :通过id获取部门 * */ Department getDepartment(int id); }
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中从Department 表得到一条记录"); return null; } }
public class AccessDepartment implements IDepartment { @Override public void insert(Department department) { System.out.println("在Access中给Department 表增加一条记录"); } @Override public Department getDepartment(int id) { System.out.println("在Access中从Department 表得到一条记录"); return null; } }
public class User { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } }
public class Department { private int id; private String deptName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
public class Client { public static void main(String[] args) { User user=new User(); Department department=new Department(); IFactory factory=new AccessFactory(); IUser iUser=factory.createUser(); iUser.insert(user); iUser.getUser(1); IDepartment iDepartment=factory.createDepartment(); iDepartment.insert(department); iDepartment.getDepartment(1); } }
抽象工厂模式优缺点
好处:
-
便于交换产品系列,由具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,因为只是需要改变具体工厂即可使用不同的产品配置;
-
具体的创建实例与客户端分离,客户端是通过他们的抽象接口创建实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端的代码中。
缺点:
假设我们需要在抽象工厂模式(上面的示例)中再增加一个一个项目表Project
,那么至少是需要增加IProject
、SqlServerProject
、AccessProject
,这三个类,同时还是需要修改IFactory
、SqlServer
、AccessFactory
这三个类(创建Project).这样会导致大量的改动,这是非常麻烦的事情。
使用简单工厂模式去改进抽象工厂模式
UML
代码
public class DataAccess { private static String db="SqlServer"; // private String db="Access" public static IUser createUser(){ IUser result=null; switch (db){ case "SqlServer": result=new SqlServerUser(); break; case "Access": result=new AccessUser(); break; default:break; } return result; } public static IDepartment createDepartment(){ IDepartment result=null; switch (db){ case "SqlServer": result=new SqlServerDepartment(); break; case "Access": result=new AccessDepartment(); break; default:break; } return result; } }
/** * @className:Client2 * @Description: 这种情况就是依赖注入 */ public class Client2 { public static void main(String[] args) { User user=new User(); Department department=new Department(); IUser iUser=DataAccess.createUser(); iUser.insert(user); iUser.getUser(1); IDepartment iDepartment=DataAccess.createDepartment(); iDepartment.insert(department); iDepartment.getDepartment(1); } }
小结
这样即完成了改造,由抽象工厂模式变成了简单工厂模式,但是这样就是依赖注入,还需要加入反射机制,这样才能完美的解决我们的程序问题。