文章来自《Offer来了:Java面试核心知识点精讲(原理篇》

工厂模式(Factory Pattern)是最常见的设计模式,该模式设属于创建型模式,它提供了一种简单、快速、高效而安全地创建对象的方式。工厂模式在接口中定义了创建对象的方法,而将具体的创建对象的过程在子类中实现,用户只需通过接口创建需要的对象即可,不用关注对象的具体创建过程。同时,不同的子类可根据需求灵活实现创建对象的不同方法。

通俗地讲,工厂模式的本质就是用工厂方法代替new操作创建一种实例化对象的方式,以提供一种方便地创建有同种类型接口的产品的复杂对象。

如下代码通过new关键字实例化类Class的一个实例class,但如果Class类在实例化时需要一些初始化参数,而这些参数需要其他类的信息,则直接通过new关键字实例化对象会增加代码的耦合度,不利于维护,因此需要通过工厂模式将创建实例和使用实例分开。将创建实例化对象的过程封装到工厂方法中,我们在使用时直接通过调用工厂来获取,不需要关心具体的负载实现过程:

Class class = new Class();

以创建手机为例,假设手机的品牌有华为和苹果两种类型,我们要实现的是根据不同的传入参数实例化不同的手机,则其具体的UML设计如图9-1所示。

https://cdn.nlark.com/yuque/0/2020/png/576791/1598451975511-82ea6027-c4b3-4c45-8ea3-451d480e1bf6.png

其具体实现如下。

(1)定义接口:

public interface Phone {

    // 品牌
    String brand();

}

以上代码定义了一个Phone接口,并在接口中定义了brand(),用来返回手机的品牌。

(2)定义实现类:

public class IPhone implements Phone{

    @Override
    public String brand() {
        return "this is a Apple phone";
    }

}

public class HuaWei implements Phone{

    @Override
    public String brand() {
        return "this is a huawei phone";
    }

}

以上代码定义了两个Phone的实现类Iphone和HuaWei来表示两个品牌的手机,两个品牌的手机通过实现brand()打印自己的商标。

(3)定义工厂类:

/**
 * @Description 工厂类
 * @Author Gao Hang Hang
 * @Date 2020-08-26 22:30
 **/
public class Factory {

    public Phone createPhone(String phoneName) {
        if ("HuaWei".equals(phoneName)) {
            return new HuaWei();
        } else if ("Apple".equals(phoneName)) {
            return new IPhone();
        } else {
            return null;
        }
    }

}

以上代码定义了名为Factory的工厂类,工厂类有一个方法createPhone(),用来根据不同的参数实例化不同品牌的手机类并返回。在createPhone()的参数为“HuaWei”时,工厂类为我们实例化一个HuaWei类的实例并返回;在createPhone()的参数为“Apple”时,工厂类为我们实例化一个Iphone类的实例并返回。这样便实现了工厂类根据不同的参数创建不同的实例,对调用者来说屏蔽了实例化的细节。

(4)使用工厂模式: