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
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐