03. 23种经典设计模式-13-工厂方法模式

1. 工厂方法模式(Factory Method Pattern)

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口, 让子类决定实例化哪个类. 工厂方法模式使一个类的实例化延迟到子类)

1.1 工厂方法模式核心思想

工厂模式是一个典型的解耦框架, 用于解耦产品的创建。高层模块儿只需要与产品的抽象类打交道即可, 无须知道产品实现类.

1.2 工厂方法模式类图

笔者认为, 工厂方法模式类图应该添加一条线: Creator 接口依赖Product 接口

  • Product: 产品的抽象类或抽象接口
  • ConcreteProduct: 产品的实现类
  • Creator: 抽象工厂, 定义产品的抽象创建方法
  • ConcreateCreator: 具体创建工厂, 创建具体的产品.

image

1.3 工厂方法模式优点

  • 优点:
    • 扩展性强: 新增产品类时, 只需要新增工厂方法即可
    • 屏蔽产品类: 调用者只需要关注产品的抽象类即可,无须关系产品实现类. 隐藏了产品实现细节
    • 可维护性强:当需求变化时,可直接替换工厂实现类.
  • 缺点:
    • 新增一种产品时, 需要新增一个工厂类, 系统中类会增加.
    • 调试较复杂, 在深度解耦设计中,只有在运行时才知道真实的对象类型是什么

1.4 适用场景

  • 需要灵活的,可扩展,松耦合的框架时
  • 工厂方法模式在spring框架中,也广泛的使用.
  • 工厂方法模式应用非常广泛,而且有很多扩展模式.

2. 工厂方法模式

我们来设定这样一种场景, 要求使用jdbc 开发的应用,可同时在oracle 数据库和mysql等数据库环境中运行。 我们知道,对于oracle和mysql的一些sql写法是不同的,比如说分页查询. 对此我们便可以借助于标准工厂方法模式进行松耦合设计.

2.1 工厂方法模式类图

  • IBaseDao: 接口, 定义数据库基本操作的抽象方法
  • OracleBaseDao/MysqlBaseDao: 数据库基本操作实现类,分别对应于oracle数据库和mysql数据库的操作
  • IBaseDaoFactory: 接口, 定义IBaseDao 的抽象创建方法
  • OracleBaseFactory/MysqlBaseFactory: 分别用于创建 OracleBaseDao和MysqlBaseDao实例

[外链图片转存失败(img-3KxWHtI8-1566894742857)(https://raw.githubusercontent.com/zongf0504/blog-images/master/images/design-parttern/ldp-factorymethod-02.png)]

2.2 抽象产品类-IBaseDao

定义数据库基本基本操作的抽象方法

public interface IBaseDao {

    void save();
    
}

2.2 mysql实现类-MysqlBaseDao

提供mysql 数据库基本操作实现类

public class MysqlBaseDao implements IBaseDao {

    @Override
    public void save() {
        System.out.println("mysql 执行save操作...");
    }
    
}

2.3 oracle类-OracleBaseDao

提供oracle 数据库基本操作实现类

public class OracleBaseDao implements IBaseDao {

    @Override
    public void save() {
        System.out.println("oracle 执行save操作...");
    }
    
}

2.4 抽象工厂类-IBaseDaoFactory

定义获取BaseDao 的抽象工厂

public interface IBaseDaoFactory {

    IBaseDao getBaseDao();

}

2.5 mysql实现工厂-MysqlDaoFactory

public class MysqlDaoFactory implements IBaseDaoFactory {
    
    @Override
    public IBaseDao getBaseDao() {
        return new MysqlBaseDao();
    }
    
}

2.6 oracle实现工厂-OracleDaoFactory

public class OracleDaoFactory implements IBaseDaoFactory {
    
    @Override
    public IBaseDao getBaseDao() {
        return new OracleBaseDao();
    }
    
}

2.7 测试类

当切换数据库时,只需要修改工厂实例的创建一处地方即可:

  • 当使用OracleDaoFactory 创建baseDaoFactory 实例时, 便使用OracleBaseDao 对象操作oracle 数据库
  • 当使用MysqlDaoFactory 创建baseDaoFactory 实例时, 便使用MysqlBaseDao 对象操作mysql 数据库
 // 使用oracle 数据库时,创建OracleDaoFactory
@Test
public void test_mysql(){
    IBaseDaoFactory baseDaoFactory = new OracleDaoFactory();

    IBaseDao baseDao = baseDaoFactory.getBaseDao();

    baseDao.save();
}

// 使用mysql 数据库时,创建MysqlDaoFactory
@Test
public void test_oracle(){
    IBaseDaoFactory baseDaoFactory = new MysqlDaoFactory();

    IBaseDao baseDao = baseDaoFactory.getBaseDao();

    baseDao.save();
}

3. 工厂方法模式扩展-静态工厂方法模式

  • 静态方法模式, 也称简单方法模式, 是工厂方法模式的一种扩展模式。
  • 简单工厂方式就是移除了抽象工厂接口, 将获取对象的方法修改为static.

3.1 静态工厂方法模式优缺点

  • 优点: 调用简单, 直接通过类名调用即可
  • 扩展性较差: 主要体现在Factory的扩展性差,当我们能明确抽象工厂只有一种实现时, 便可以采用静态工厂方法模式。

3.2 静态工厂类

当不考虑扩展性时, 静态工厂方法模式完全可以不依赖于IBaseDao,与OracleBaseDao和MysqlBaseDao 直接打交道

public class BaseDaoFactory {

    public static IBaseDao getOracleBaseDao() {
        return new OracleBaseDao();
    }

    public static IBaseDao getMysqlBaseDao() {
        return new MysqlBaseDao();
    }

}

3.3 测试

@Test
public void test_static(){
    IBaseDao baseDao;

    // 使用mysql
    baseDao = BaseDaoFactory.getMysqlBaseDao();
    baseDao.save();

    // 使用oracle
    baseDao = BaseDaoFactory.getOracleBaseDao();
    baseDao.save();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值