Spring中使用到的设计模式(五)----抽象工厂模式

时间:2024-03-29 07:55:09

1. 抽象工厂模式

1.1 什么是抽象工厂模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。

1.2 意图

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

1.3 UML图

Spring中使用到的设计模式(五)----抽象工厂模式

UML图详细说明

Spring中使用到的设计模式(五)----抽象工厂模式

1.3 优缺点

优点:

1. 抽象工厂模式最大的好处是易于交换产品系列,由于具体工厂类,例如 IFactory factory=new OracleFactory(); 在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。

2. 另一个好处就是它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品实现类的具体类名也被具体的工厂实现类分离,不会出现在客户端代码中。

缺点:

抽象工厂模式虽然可以很方便的帮我们切换两个不同的数据库访问的代码。但是如果我们的需求来自于增加功能,例如我们还需要加多一个会员数据表 MemberData,那么我们就得先在以上代码的基础上,增加三个类:IMemberData,MysqlMemberData,OracleMemberData,还需要修改IFactory、MysqlFactory以及OracleFactory才可以完全实现。增加类还好说,毕竟我们是对扩展开放的,但是却要修改三个类,就有点糟糕了。

1.4 抽象工厂与工厂方法的区别

区别:抽象工厂是可以生产多个产品的,例如 MysqlFactory 里可以生产 MysqlUser 以及 MysqlLogin 两个产品,而这两个产品又是属于一个系列的,因为它们都是属于MySQL数据库的表。而工厂方法模式则只能生产一个产品,例如之前的 MysqlFactory 里就只可以生产一个 MysqlUser 产品。

Spring中使用到的设计模式(五)----抽象工厂模式

1.5 改进方法

  • +简单工厂模式继续改进代码;
  • +配置文件+简单工厂模式继续改进代码;

1.6 使用场景

1、QQ 换皮肤,一整套一起换;

2、生成不同操作系统的程序。

1.7 注意事项

产品族难扩展,产品等级易扩展。

2. 抽象工厂模式的代码实现

IFactory:

public interface IFactory {

    public IUser createUser();

    public ILogin createLogin();

}

MysqlFactory:

public class MysqlFactory implements IFactory{

public IUser createUser() {

        return new MysqlUser();

    }

    public ILogin createLogin() {

        return new MysqlLogin();

    }

}

OracleFactory

public class OracleFactory implements IFactory{

public IUser createUser() {

        return new OracleUser();

    }

    public ILogin createLogin() {

        return new OracleLogin();

    }

}

User:

public class User {

    public int getUid() {

        return uid;

    }

    public void setUid(int uid) {

        this.uid = uid;

    }

    public String getUname() {

        return uname;

    }

    public void setUname(String uname) {

        this.uname = uname;

    }

    private int uid;

    private String uname;

}

IUser:

public interface IUser {

    public void insert(User user);

    public IUser getUser(int uid);

}

MysqlUser:

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 表得到了一条数据");

return null;

}

}

OracleUser

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 表得到了一条数据");

        return null;

    }

}

Login:

public class Login {

    private int id;

    private Date date;

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public Date getDate() {

        return date;

    }

    public void setDate(Date date) {

        this.date = date;

    }

}

ILogin:

public interface ILogin {

    public void insert(Login login);

    public Login getLogin(int id);

}

MysqlLogin:

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 表得到了一条数据");

        return null;

    }

}

OracleLogin:

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 表得到了一条数据");

        return null;

    }

}

MainTest:

public class MainTest {

public static void main(String[] args){

        User user=new User();

        Login login = new Login();

        // 只需要确定实例化哪一个数据库访问对象给factory

        // IFactory factory=new MysqlFactory();

        IFactory factory=new OracleFactory();

        // 已与具体的数据库访问解除了耦合

        IUser userOperation=factory.createUser();

        userOperation.getUser(1);

        userOperation.insert(user);

        // 已与具体的数据库访问解除了耦合

        ILogin loginOperation=factory.createLogin();

        loginOperation.insert(login);

        loginOperation.getLogin(1);

    }

}