抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1. 抽象工厂模式最大的好处是易于交换产品系列,由于具体工厂类,例如 IFactory factory=new OracleFactory(); 在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2. 另一个好处就是它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品实现类的具体类名也被具体的工厂实现类分离,不会出现在客户端代码中。
抽象工厂模式虽然可以很方便的帮我们切换两个不同的数据库访问的代码。但是如果我们的需求来自于增加功能,例如我们还需要加多一个会员数据表 MemberData,那么我们就得先在以上代码的基础上,增加三个类:IMemberData,MysqlMemberData,OracleMemberData,还需要修改IFactory、MysqlFactory以及OracleFactory才可以完全实现。增加类还好说,毕竟我们是对扩展开放的,但是却要修改三个类,就有点糟糕了。
区别:抽象工厂是可以生产多个产品的,例如 MysqlFactory 里可以生产 MysqlUser 以及 MysqlLogin 两个产品,而这两个产品又是属于一个系列的,因为它们都是属于MySQL数据库的表。而工厂方法模式则只能生产一个产品,例如之前的 MysqlFactory 里就只可以生产一个 MysqlUser 产品。
public class MysqlFactory implements IFactory{
public class OracleFactory implements IFactory{
public void setUname(String uname) {
public void insert(User user);
public IUser getUser(int uid);
public class MysqlUser implements IUser{
public void insert(User user) {
System.out.println("对 MySQL 里的 User 表插入了一条数据");
public IUser getUser(int uid) {
System.out.println("通过 uid 在 MySQL 里的 User 表得到了一条数据");
public class OracleUser implements IUser{
public void insert(User user) {
System.out.println("对 Oracle 里的 User 表插入了一条数据");
public IUser getUser(int uid) {
System.out.println("通过 uid 在 Oracle 里的 User 表得到了一条数据");
public void setDate(Date date) {
public void insert(Login login);
public Login getLogin(int id);
public class MysqlLogin implements ILogin{
public void insert(Login login) {
System.out.println("对 MySQL 里的 Login 表插入了一条数据");
public Login getLogin(int id) {
System.out.println("通过 uid 在 MySQL 里的 Login 表得到了一条数据");
public class OracleLogin implements ILogin{
public void insert(Login login) {
System.out.println("对 Oracle 里的 Login 表插入了一条数据");
public Login getLogin(int id) {
System.out.println("通过 uid 在 Oracle 里的 Login 表得到了一条数据");
public static void main(String[] args){
// IFactory factory=new MysqlFactory();
IFactory factory=new OracleFactory();
IUser userOperation=factory.createUser();