该用简单工厂模式还是工厂方法模式

燃着的半支烟 2020年03月24日 57次浏览

工作中工厂模式很常用,半支烟估计小伙伴们大部分场景使用了简单工厂模式,那什么时候使用工厂方法模式呢?两者有啥区别呢?

话不多说,今天就来聊聊这个话题。

简单工厂模式

让我们先来看个场景:

某天下午半支烟在撩妹的时候,突然老板让我过去一趟,说我们平台要卖保险,顺手把我拉进了5个保险公司的群,我一下子蒙了,要对接5家保险公司呀,每家保险公司的下单、支付、退保、退款、换人等接口实现都不同。要是来一堆if else,那代码太臃肿了,也不便于后期的维护扩展,于是简单工厂模式上场。

代码实现:

//此处简化,只写了下单接口
public interface IOrder {
    void createOrder();
}
//平安保险
public class PaOrder implements IOrder {
    @Override
    public void createOrder() {
        System.out.println("平安保险下单");
    }
}
//人保保险
public class RbOrder implements IOrder {
    @Override
    public void createOrder() {
        System.out.println("人保保险下单");
    }
}
//太平洋保险
public class TpyOrder implements IOrder {
    @Override
    public void createOrder() {
        System.out.println("太平洋保险下单");
    }
}
//再来个创建不同实现类的工厂
public class OrderFactory {
    private static Map<String, IOrder> cachedCompany = new HashMap<>();

    static {
        cachedCompany.put("pa", new PaOrder());
        cachedCompany.put("rb", new RbOrder());
        cachedCompany.put("tpy", new TpyOrder());
    }

    public static IOrder getInsuranceOrder(String company) {
        if (StringUtils.isEmpty(company)) {
            throw new ArithmeticException("保险公司名称不能为空");
        }
        return cachedCompany.get(company);
    }
}
//再来一段调用
public static void main(String[] args) {
  //比如购买的是平安保险
  IOrder iOrder = OrderFactory.getInsuranceOrder("pa");
  iOrder.createOrder();
}

后续如果想扩展更多的保险公司,直接扩展新类实现IOrder接口,其他都不用改。符合对修改关闭,对扩展开放的设计原则。

不知道大家注意到没有,实现类的工厂,再创建类的时候,都只是简单的new操作,如果创建对象的过程很复杂呢,还要做一系列初始化的呢?那OrderFactory类岂不是变得很负责了?让我们继续解耦,工程方法模式登场!

工厂方法模式

还是刚才的场景,只是创建对象稍微复杂些:

比如在创建对象时,需要设置很多参数,还需要记录日志等一系列动作。

代码实现上,工厂方法模式简单工厂模式,多了2种代码:

  1. 一个创建工厂对象的工厂类,
  2. N个创建实现类的工厂

半支烟就不贴具体的代码了,文末附有git地址。此处就通过一张图比对,明显看出类的多少:

截屏2020-03-24下午11.44.57

总结

哪些区别?
  1. 简单工厂模式使用大部分场景,代码简洁,易理解。
  2. 工厂方法模式,代码量多,不易理解,为创建复杂实现类而生。
如何选择?
  1. 大部分场景选择简单工厂模式。
  2. 如果需要创建负责对象,则选择工厂方法模式。

最后附上代码地址