使用抽象工厂模式在客户端切换不同数据库
1、抽象工厂模式:提供一个创建对象的接口IFactory ,该接口中定义了一个的创建对象的方法createUser(),这个方法的返回值是接口类型,当在客户端创建了IFactory接口的某个实现类的实例instance之后,就可以调用IFactory 接口中的创建对象的方法,返回对象实例user,比如:IFactory instance= new MySqlFactory();或IFactory
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)