工厂方法模式

2016年11月17日

介绍

解决问题: 主要解决接口选择的问题。(在下面的例子中如果不使用ShapeFactory,则具体使用 Square 还是 Rectangle 的判断逻辑就会需要写在 使用 ShapeFactory 的地方,这样不管是新增还是修改,都需要对该源码进行改动)

优点: 1. 扩展性好,新增功能时,只需扩展工厂类. 2. 屏蔽接口实现具体的创建过程,使调用方逻辑更加清晰(仅适用复杂对象的创建, 简单对象就别用这个了,用了反而把系统搞复杂了).

缺点: 新增产品,都需要新增具体类和对象实现工厂,在一定程度上增加了系统的复杂度.

使用场景: 1. 日志记录器(slf4j日志框架的动态绑定) 2. 数据库访问

例子

一个 Shape 接口, 有两个实现 Square 和 Rectangle , 通过ShapeFactory工厂类来实例化具体的类.

代码

接口以及对应的实现

Shape 接口

    public interface Shape {
      void draw();
    }

Rectangle 接口实现

    public class Rectangle implements Shape {
        public void draw() {
            System.out.println("Rectangle:draw()");
        }
    }

Square 接口实现

    public class Square implements Shape {
        public void draw() {
            System.out.println("Square:draw()");
        }
    }

ShapeFactory 工厂类

    public class ShapeFactory {

        public static Shape createShape(String shapeType) {

            if ("rectangle".equalsIgnoreCase(shapeType)) {
                return new Rectangle();

            } else if ("square".equalsIgnoreCase(shapeType)) {
                return new Square();
            }

            return null;
        }

    }

则在使用时, 可直接使用如下方式:

    ShapeFactory.createShape("square").draw();

其他

在实际运用中,有这样一些使用的例子

  • 在spring中的 FactoryBean 用来创建某种指定的类, 可在创建时对创建的对象实现定制化, 向调用方屏蔽具体的创建过程

  • 常用的 slf4j 日志框架 的 LoggerFactory 日志工厂类, 屏蔽查找具体使用的日志框架, 使替换日志框架时,可无缝替换.