美文网首页
第15章 就不能不换DB吗?--抽象工厂模式

第15章 就不能不换DB吗?--抽象工厂模式

作者: 落墨Zero | 来源:发表于2018-07-11 14:51 被阅读0次

情境:在需要更改项目数据库时,代码尽量少的更改。

为了可以切换数据库,首先可以想到使用工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。

代码如下

IUser接口,用于客户端访问,解除与具体数据库访问的耦合。

public interface IUser {

    void insert(User user);

}

SqlServerUser类,用于访问SqlServer的User

public class SqlServerUser implements IUser{

    @Override
    public void insert(User user){
        print("在SQL Server中给User表增加一条记录");
    }

}

AccessUser类,用于访问Access的User

public class AccessUser implements IUser{

    @Override
    public void insert(User user){
        print("在Access中给User表增加一条记录");
    }

}

IFactory接口,定义一个创建访问User表对象的工厂接口

public interface IFactory {

    IUser getUserFactory();

}

SqlServerFactory类,实现IFactory接口,实例化SqlServerUser

public class SqlServerFactory implements IFactory {
    @Override
    public IUser createUserFactory() {
        return new SqlServerUser();
    }
}

AccessFactory类,实现IFactory接口,实例化AccessUser

public class AccessFactory implements IFactory {
    @Override
    public IUser createUserFactory() {
        return new AccessUser();
    }
}

测试代码

public class Test {

    public static void main(String[] args) {
        User user = new User();
        //若要改成Access数据库,只需要将本句改成IFactory factory = new AccessFactory();
        IFactory factory = new SqlServerFactory();
        IUser userFactory = factory.createUserFactory();
        userFactory.insert(user);
    }

}

此时,由于多态的关系,使得声明IUser接口的对象userFactory事先根本不知道是在访问哪个数据库,却可以在运行时很好地完成工作,这就是所谓的业务逻辑与数据访问的解耦。
但是如果增加一个部门表(Department表),需要做下面的改动。

新增IDepartment接口,用于客户端访问,解除与具体数据库访问的耦合

public interface IDepartment {

    void insert(Department department);

}

新增SqlServerDepartment类,用于访问SqlServer的Department

public class SqlServerDepartment implements IDepartment{

    @Override
    public void insert(Department department){
        print("在SQL Server中给Department表增加一条记录");
    }

}

新增AccessDepartment类,用于访问Access的Department

public class AccessDepartment implements IDepartment{

    @Override
    public void insert(Department department){
        print("在Access中给Department表增加一条记录");
    }

}

修改IFactory接口

public interface IFactory {

    IUser createUserFactory();

    IDepartment createDepartmentFactory();
}

修改SqlServerFactory

public class SqlServerFactory implements IFactory {
    @Override
    public IUser createUserFactory() {
        return new SqlServerUser();
    }

    @Override
    public IDepartment createDepartmentFactory() {
        return new SqlServerDepartment();
    }
}

修改AccessFactory

public class AccessFactory implements IFactory {
    @Override
    public IUser createUserFactory() {
        return new AccessUser();
    }

    @Override
    public IDepartment createDepartmentFactory() {
        return new AccessDepartment();
    }
}

抽象工厂模式

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。[DP]

抽象工厂模式(Abstract Factory)结构图

抽象工厂模式结构图.png

AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同的实现,就刚才的例子来说就是User和Department,而ProductA1、ProductA2和ProductB1、ProductB2就是对两个抽象产品的具体分类的实现,比如ProductA1可以理解为是SqlServerUser,而ProductB1是AccessUser。
IFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂。就像SqlServerFactory和AccessFactory一样。
通常是在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。

抽象工厂模式的优点与缺点

优点

1、易于交换产品系列,由于具体工厂类,在一个应用中只需要再初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2、它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

缺点

每一个类的开始都要声明IFactory factory = new SqlServerFactory()新增功能,需要修改Factory相关类。

用简单工厂来改进抽象工厂

新增DataAccess类

public class DataAccess {

    private static final String db = "SqlServer";

    public static IUser createUser() {
        IUser result = null;
        switch (db) {
            case "SqlServer":
                result = new SqlServerUser();
                break;
            case "Access":
                result = new AccessUser();
                break;
        }
        return result;
    }

    public static IDepartment createDepartment() {
        IDepartment result = null;
        switch (db) {
            case "SqlServer":
                result = new SqlServerDepartment();
                break;
            case "Access":
                result = new AccessDepartment();
                break;
        }
        return result;
    }
}

测试代码

public class Test {

    public static void main(String[] args) {
        User user = new User();
        IUser userFactory = DataAccess.createUser();
        userFactory.insert(user);
    }

}

抛弃IFactory、SqlServerFactory、AccessFactory三个工厂类,取而代之的是DataAccess类,客户端没有出现任何一个SqlServer或Access的字样,达到解耦的目的。

用反射解决switch case

修改DataAccess类

public class DataAccess {

    private static final String fullName = "com.luomo.study.design.patten.absfactory.";

    private static final String db = "Access";

    public static IUser createUser() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> cls = Class.forName(fullName+db+"User");
        return (IUser) cls.newInstance();
    }

    public static IDepartment createDepartment() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        Class<?> cls = Class.forName(fullName+db+"Department");
        return (IDepartment) cls.newInstance();
    }
}

所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合。

相关文章

  • 大话设计模式读书笔记-15抽象工厂模式

    第15章 就不能不换DB吗?——抽象工厂模式 概念 定义多个创建接口可以创建多套产品,每套产品有不同的实现方案(子...

  • 第15章 就不能不换DB吗?--抽象工厂模式

    情境:在需要更改项目数据库时,代码尽量少的更改。 为了可以切换数据库,首先可以想到使用工厂方法模式,定义一个用于创...

  • (5)JavaScript抽象工厂模式

    前边介绍了简单工厂模式和组合工厂模式,其实都换汤不换药,这里再介绍一种抽象工厂模式。抽象工厂模式常出现在后端开发中...

  • 抽象工厂模式(选择产品簇)

    目录 回顾众多工厂模式 抽象工厂模式的理念 抽象工厂模式与工厂方法模式的差异 怎么来实现抽象工厂模式 抽象工厂模式...

  • 全面了解工厂模式

    工厂模式是啥? 简单工厂是工厂模式吗? 工厂模式的哼哈二将(工厂方法、抽象工厂) 一、工厂模式是啥? ​ 我们...

  • 工厂模式

    工厂模式细分三种:简单工厂模式、工厂模式、抽象工厂模式。 工厂模式相当于抽象了简单工厂模式的工厂类,而抽象工厂模式...

  • 【抽象工厂模式】Abstract Factory Design

    抽象工厂模式 抽象工厂模式是**Creational **模式之一 抽象工厂模式和工厂模式很相似,甚至可以说抽象工...

  • 第3章 创建型模式-抽象工厂模式

    ■ 抽象工厂模式的优点 ■ 抽象工厂模式的缺点 ■ 抽象工厂模式的使用场景 ■ 抽象工厂 AbstractFact...

  • 常用设计模式

    设计模式 工厂模式 工厂模式思路上分:简单工厂模式,工厂模式, 抽象工厂模式// 抽象工厂模式可以代替工厂模式,做...

  • 找女朋友之简单工厂模式,工厂模式,抽象工厂模式

    找女朋友之简单工厂模式,工厂模式,抽象工厂模式 找女朋友之简单工厂模式,工厂模式,抽象工厂模式

网友评论

      本文标题:第15章 就不能不换DB吗?--抽象工厂模式

      本文链接:https://www.haomeiwen.com/subject/mmthpftx.html