使用抽象工厂模式在客户端切换不同数据库

1、抽象工厂模式:提供一个创建对象的接口IFactory ,该接口中定义了一个的创建对象的方法createUser(),这个方法的返回值是接口类型,当在客户端创建了IFactory接口的某个实现类的实例instance之后,就可以调用IFactory 接口中的创建对象的方法,返回对象实例user
比如:
IFactory instance= new MySqlFactory();

IFactory instance= new OracleFactory();
IUser user = instance.createUser();
由于我们在IFactory 中声明方法时用的返回值类型是一个接口类型,所以就可以用接口类型IUser接收对象实例user,这时我们可以发现:IFactory的实例instance可以是MySQL类型的也可以是Oracle类型的,所以调用创建对象的方法instance.createUser()时就可以创建出MySQL类型的实例或者是Oracle类型的实例,然后可以继续调用MySQL类型对象的各种方法或Oracle类型对象的各种方法。这样就是实现了数据库的切换,值得注意的是:在整个切换过程中,我们只需更改一行代码
2、优点:对于多个系列的产品,可以在客户端通过抽象接口去创建不同系列的实例,而每种实例底层的逻辑全部被封装在服务端,这样客户端看上去只改了一行代码而已。
3、缺点
(1) 在每一个类中都需要一句: IFactory instance= new MySqlFactory();,如果我们有1000个这样的类那是不是要new上1000次呢?
(2) 尽管如此我们还是要在客户端改一行代码,那可不可以实现不改代码就切换数据库呢?(tips:可以通过反射+简单工厂模式实现在配置文件中切换数据库,将编译期创建对象转化为运行时期创建对象,这样就可以避免更改代码了,请看文末。。。)

package 创建型模式.工厂模式.抽象工厂模式.AbstractFactory;
import 创建型模式.工厂模式.抽象工厂模式.department.IDepartment;
import 创建型模式.工厂模式.抽象工厂模式.user.IUser;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/21:55
 * @Description: 创建不同对象的抽象工厂接口
 */
public interface IFactory {
    /**
     * 创建用户表
     * @return 接口类型IUser
     */
    IUser createUser();

    /**
     * 创建部门表
     * @return 接口类型IDepartment
     */
    IDepartment createDepartment();
}

package 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.impl;
import 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.IFactory;
import 创建型模式.工厂模式.抽象工厂模式.department.IDepartment;
import 创建型模式.工厂模式.抽象工厂模式.department.impl.MySqlDepartment;
import 创建型模式.工厂模式.抽象工厂模式.user.IUser;
import 创建型模式.工厂模式.抽象工厂模式.user.impl.MySqlUser;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:10
 * @Description: MySQL数据库的对象工厂
 */
public class MySqlFactory implements IFactory {

    @Override
    public IUser createUser() {
        return new MySqlUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new MySqlDepartment();
    }
}

package 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.impl;

import 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.IFactory;
import 创建型模式.工厂模式.抽象工厂模式.department.IDepartment;
import 创建型模式.工厂模式.抽象工厂模式.department.impl.OracleDepartment;
import 创建型模式.工厂模式.抽象工厂模式.user.IUser;
import 创建型模式.工厂模式.抽象工厂模式.user.impl.OracleUser;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:12
 * @Description: Oracle数据库的对象工厂
 */
public class OracleFactory implements IFactory {
    @Override
    public IUser createUser() {
        return new OracleUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new OracleDepartment();
    }
}

package 创建型模式.工厂模式.抽象工厂模式.department;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:00
 * @Description: 部门表接口
 */
public interface IDepartment {

    /**
     * 部门表的插入方法
     */
    void insert();
}

package 创建型模式.工厂模式.抽象工厂模式.department.impl;
import 创建型模式.工厂模式.抽象工厂模式.department.IDepartment;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:08
 * @Description: MySQL数据库的部门表
 */
public class MySqlDepartment implements IDepartment {
    @Override
    public void insert() {
        System.out.println("向MySQL数据库中的部门表中插入一条数据");
    }
}

package 创建型模式.工厂模式.抽象工厂模式.department.impl;
import 创建型模式.工厂模式.抽象工厂模式.department.IDepartment;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:08
 * @Description: MySQL数据库的部门表
 */
public class OracleDepartment implements IDepartment {
    @Override
    public void insert() {
        System.out.println("向Oracle数据库中的部门表中插入一条数据");
    }
}

package 创建型模式.工厂模式.抽象工厂模式.user;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/21:57
 * @Description: 用户表接口
 */
public interface IUser {

    /**
     * 用户表的插入数据方法
     */
    void insert();
}

package 创建型模式.工厂模式.抽象工厂模式.user.impl;
import 创建型模式.工厂模式.抽象工厂模式.user.IUser;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:04
 * @Description: MySQL 数据库下的User表
 */
public class MySqlUser implements IUser {

    @Override
    public void insert() {
        System.out.println("向MySQL数据库的User表中插入一条数据");
    }
}

package 创建型模式.工厂模式.抽象工厂模式.user.impl;
import 创建型模式.工厂模式.抽象工厂模式.user.IUser;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:06
 * @Description: Oracle数据库下的User表
 */
public class OracleUser implements IUser {
    @Override
    public void insert() {
        System.out.println("向Oracle数据库的User表中插入一条数据");
    }
}

package 创建型模式.工厂模式.抽象工厂模式;
import 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.IFactory;
import 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.impl.MySqlFactory;
import 创建型模式.工厂模式.抽象工厂模式.AbstractFactory.impl.OracleFactory;
import 创建型模式.工厂模式.抽象工厂模式.department.IDepartment;
import 创建型模式.工厂模式.抽象工厂模式.user.IUser;

/**
 * @Author: lxpStu
 * @Date: 2021/10/28/22:14
 * @Description: 模拟客户端测试类
 *
 * 可以发现测试代码中只有第23行和第30行代码不同,其余地方全部相同
 */
public class Main {
    public static void main(String[] args) {

        IFactory factory = null;
        IUser user = null;
        IDepartment dept = null;

        factory = new MySqlFactory();
        user = factory.createUser();
        user.insert();
        dept = factory.createDepartment();
        dept.insert();

        factory = new OracleFactory();
        user = factory.createUser();
        user.insert();
        dept = factory.createDepartment();
        dept.insert();
    }
}

改为反射+配置文件实现修改配置文件切换数据库

//配置文件:db.properties
className=DB.changeDB.user.impl.MySqlUser
methodName=insert
//测试代码
  public static void main(String[] args) throws Exception {

        Properties pro = new Properties();
        InputStream in = Main.class.getClassLoader().getResourceAsStream("db.properties");
        pro.load(in);
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");

        Class clz = Class.forName(className);
        Object o = clz.newInstance();
        Method method = clz.getMethod(methodName);
        method.invoke(o);
    }
 // 输出
C:\java\java8\jdk\bin\java.exe...MySQL数据库的User表中插入一条数据

Process finished with exit code 0
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抽象工厂模式是一种创建型设计模式,它提供了一种将客户端代码与具体工厂分离的方法。在这种模式中,客户端不需要知道它所使用的对象的具体类型,只需要知道它们的抽象类型即可。 在实现不同数据库的连接时,可以使用抽象工厂模式来实现。假设我们需要连接 MySQL 和 Oracle 数据库,可以定义一个抽象工厂类 `DatabaseFactory`,它定义了两个抽象方法 `createConnection()` 和 `createStatement()`。 ```java public abstract class DatabaseFactory { public abstract Connection createConnection(); public abstract Statement createStatement(); } ``` 然后,定义两个具体工厂类 `MySQLDatabaseFactory` 和 `OracleDatabaseFactory`,它们分别实现了 `createConnection()` 和 `createStatement()` 方法,返回 MySQL 和 Oracle 数据库的连接和语句对象。 ```java public class MySQLDatabaseFactory extends DatabaseFactory { @Override public Connection createConnection() { // 连接 MySQL 数据库 return null; } @Override public Statement createStatement() { // 创建 MySQL 数据库语句对象 return null; } } public class OracleDatabaseFactory extends DatabaseFactory { @Override public Connection createConnection() { // 连接 Oracle 数据库 return null; } @Override public Statement createStatement() { // 创建 Oracle 数据库语句对象 return null; } } ``` 最后,客户端代码只需要使用抽象工厂类 `DatabaseFactory`,而不需要知道具体的数据库连接和语句对象是什么。客户端可以通过传入不同的具体工厂类来创建不同类型的数据库连接和语句对象。 ```java public class Client { public static void main(String[] args) { DatabaseFactory factory = new MySQLDatabaseFactory(); Connection connection = factory.createConnection(); Statement statement = factory.createStatement(); // 使用连接和语句对象进行数据库操作 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值