抽象工厂模式深度理解,以及举例说明
一、抽象工厂模式举例
1、工厂模式类
package factory; public class FactoryPattern { public static void main(String[] args) { //工厂A只能生产产品A Factory factory = (Factory) new FactoryA(); Product product = factory.createProduct(); product.use(); } }
2、抽象工厂类
package factory; public interface Factory { public Product createProduct(); }
3、具体工厂A
package factory; public class FactoryA implements Factory{ @Override public Product createProduct() { System.out.println("具体工厂A"); return new ProductA(); } }
4、具体工厂B
package factory; public class FactoryB implements Factory{ @Override public Product createProduct() { System.out.println("具体工厂B"); return new ProductB(); } }
5、抽象产品
package factory; public interface Product { public void use(); }
6、具体产品A
package factory; public class ProductA implements Product{ @Override public void use() { System.out.println("具体产品A"); } }
7、具体产品B
package factory; public class ProductB implements Product{ @Override public void use() { System.out.println("具体产品B"); } }
二、哪里用到了抽象工厂模式
mybatis中的sqlSessionFactory使用了抽象工厂模式,
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
通过读取配置文件,来决定创建mysql连接,还是oracle连接
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 加载类路径下的属性文件 --> <properties resource="db.properties"/> <!-- 设置类型别名 --> <typeAliases> <typeAlias type="cn.itcast.javaee.mybatis.app04.Student" alias="student"/> </typeAliases> <!-- 设置一个默认的连接环境信息 --> <environments default="mysql_developer"> <!-- 连接环境信息,取一个任意唯一的名字 --> <environment id="mysql_developer"> <!-- mybatis使用jdbc事务管理方式 --> <transactionManager type="jdbc"/> <!-- mybatis使用连接池方式来获取连接 --> <dataSource type="pooled"> <!-- 配置与数据库交互的4个必要属性 --> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </dataSource> </environment> <!-- 连接环境信息,取一个任意唯一的名字 --> <environment id="oracle_developer"> <!-- mybatis使用jdbc事务管理方式 --> <transactionManager type="jdbc"/> <!-- mybatis使用连接池方式来获取连接 --> <dataSource type="pooled"> <!-- 配置与数据库交互的4个必要属性 --> <property name="driver" value="${oracle.driver}"/> <property name="url" value="${oracle.url}"/> <property name="username" value="${oracle.username}"/> <property name="password" value="${oracle.password}"/> </dataSource> </environment> </environments> <!-- 加载映射文件--> <mappers> <mapper resource="cn/itcast/javaee/mybatis/app14/StudentMapper.xml"/> </mappers> </configuration>
三、实际的项目中遇到的使用场景
项目背景:
项目中某个接口是一个异步流程,合作方调用该接口,处理完任务之后,再将结果返回至合作方(回调时请求的地址不一样),当只有一家合作方时,不需要考虑任何问题,响应结果直接发送该合作方即可,但是当合作方数量逐渐增加到2、3、4等更多时,每次都使用if-else进行处理,就要修改代码,然后全部回归测试,增加工作量不说,还会引入bug。为了减少这样的情况,就需要引入工厂模式进行改造。
改造方案:
将回调的方法,改造成具体工厂,每次新增合作方,都是新增一个具体的工厂类,来处理个性化的操作
遇到的问题:
合作方A,如果与工厂A联系起来?
可以通过配置文件,或者通过数据库来配置,总之目的就是,每次新增合作方,都是修改配置,或者数据库,而不是修改代码