设计模式之工厂方法模式

factory method design pattern

工厂方法模式的概念、工厂方法模式的结构、工厂方法模式的优缺点、工厂方法模式的使用场景、工厂方法模式的实现示例、工厂方法模式的源码分析


1、工厂方法的概念

  工厂方法模式,及简单工厂模式的升级版,其抽象了对象的创建,将对象的具体创建延迟到了其子类中。这样,当有新产品加入时,不用再修改已有的工厂类,只需要增加新产品的实现和新产品对应工厂的实现即刻。

2、工厂方法的结构

  • 抽象产品:定义产品的行为。
  • 具体产品:实现抽象产品,使产品具像化。
  • 抽象工厂:定义生产产品的行为。
  • 具体工厂:实现抽象工厂,来创建一个具体产品的对象实例。其与具体产品是一对一的关系。

factory-method-class

3、工厂方法的优缺点

  • 优点:
    • 用户只需要知道具体的产品工厂即刻得到产品,无需了解产品的创建过程。
    • 新增产品时只需要新增具体产品类和其对应的具体工厂类即刻,无需对已有的工厂类进行修改,符合开闭原则的要求。
  • 缺点:
    • 当系统中产品过多时,会使系统过于复杂。

4、工厂方法的使用场景

  • 需要创建对象的地方。
  • 需要灵活的、可扩展的框架。
  • 针对同种类不同属性的操作,如数据库中的 mysql、oracle 等。

5、工厂方法的实现示例

抽象产品:

public interface Product {

    /**
     * 定义产品行为
     */
    void behavior();
}

具体产品一:

public class OneProduct implements Product {

    @Override
    public void behavior() {
        System.out.println("我是产品一");
    }
}

具体产品二:

public class TwoProduct implements Product {

    @Override
    public void behavior() {
        System.out.println("我是产品二");
    }
}

抽象工厂:

public interface Factory {

    /**
     * 生产
     * @return
     */
    Product product();
}

具体工厂一:

public class OneFactory implements Factory {

    @Override
    public Product product() {
        return new OneProduct();
    }
}

具体工厂二:

public class TwoFactory implements Factory {

    @Override
    public Product product() {
        return new TwoProduct();
    }
}

测试:

public class FactoryMethodTest {

    public static void main(String[] args) {
        Factory oneFactory = new OneFactory();
        Factory twoFactory = new TwoFactory();

        Product oneProduct = oneFactory.product();
        Product twoProduct = twoFactory.product();

        oneProduct.behavior();
        twoProduct.behavior();
    }
}

测试结果:

我是产品一
我是产品二

6、工厂方法的源码分析

  slf4j 中的 Logger logger = LoggerFactory.getLogger(FactoryMethodTest.class) 就是工厂方法模式的实现体现。其中 Logger 接口就是抽象产品接口,具体产品类如 EventRecodingLogger、SubstituteLogger 等;ILoggerFactory 抽象类就是抽象工厂,SubstituteLoggerFactory 等就是具体工厂类。
  另外 spring 中的 FactoryBean、java.util.concurrent 中的 ThreadFactory、mybatis 中的 SqlSessionFactory 等就是工厂方法模式。

public interface Logger {
  	...
}
public interface ILoggerFactory {

    /**
     * Return an appropriate {@link Logger} instance as specified by the
     * <code>name</code> parameter.
     * 
     * <p>If the name parameter is equal to {@link Logger#ROOT_LOGGER_NAME}, that is 
     * the string value "ROOT" (case insensitive), then the root logger of the 
     * underlying logging system is returned.
     * 
     * <p>Null-valued name arguments are considered invalid.
     *
     * <p>Certain extremely simple logging systems, e.g. NOP, may always
     * return the same logger instance regardless of the requested name.
     * 
     * @param name the name of the Logger to return
     * @return a Logger instance 
     */
    public Logger getLogger(String name);
}
public class SubstituteLoggerFactory implements ILoggerFactory {
  
  	...

    public synchronized Logger getLogger(String name) {
        SubstituteLogger logger = (SubstituteLogger)this.loggers.get(name);
        if (logger == null) {
            logger = new SubstituteLogger(name, this.eventQueue, this.postInitialization);
            this.loggers.put(name, logger);
        }

        return logger;
    }
  
  	...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值