掘金 后端 ( ) • 2024-04-27 14:40

大家好,我是徒手敲代码。

今天来介绍一下工厂模式。

工厂模式是一个统称,总共分为简单工厂模式工厂方法模式抽象工厂模式。由于篇幅有限,本篇文章重点讲解简单工厂和工厂方法模式。

工厂模式的核心思想,就是让客户端在创建对象的时候,不需要关注具体的初始化细节,直接拿来就用。

就像我们去买一台手机,不用关心手机里面各个零部件是怎么制造出来的,只需要看手机的外观如何,功能是否完整。

首先,平时在创建对象的时候,一般通过直接new的方式,比如:

User user = new User();

是的,程序员就是在天天 new 对象。

一般情况下,这样创建是没问题的。但是如果这个对象在初始化的时候,需要执行一些其他的逻辑,比如:查询数据库、读取配置文件等,那么对象的构造函数,将会变得非常复杂。

这个时候,可以引入一个工厂类来解决问题。

假设在代码中,有一个汉堡包类,这个类需要在很多地方被初始化,而且初始化的逻辑相当复杂。

public class Burger {
    //构造函数
    public Burger(){
        // n行初始化代码
    }
}

此时,可以引入一个汉堡包的工厂类,负责创建汉堡包对象,将n多行的初始化代码,移到这里。

class BurgerFactory {
    public Burger makeBurger() {
        // n行初始化代码
    }
}

那么,如果业务需要拓展,推出了牛肉汉堡和鸡肉汉堡,又该如何解决呢?

可以抽象出Burger这个接口,然后有牛肉汉堡和鸡肉汉堡来实现这个接口,具体代码如下:

public interface Burger {
    Burger cook();
}

public class BeefBurger implements Burger {
    public BeefBurger cook() {
        System.out.println("这是一个牛肉汉堡");
    }
}

public class ChickenBurger implements Burger {
    public ChickenBurger cook() {
        System.out.println("这是一个鸡肉汉堡");
    }
}

那么工厂类,只需要在创建汉堡的时候,判断一下需要创建汉堡的类型,根据不同类型来调用不同的创建方法:

public class BurgerFactory {
    public Burger makeBurger(String type) {
        Burger burger = null;
        if ("牛肉汉堡".equals(type)) {
            burger = new BeefBurger();
            //省略初始化的n行代码
            //......
        } else if ("牛肉汉堡".equals(type)) {
            burger = new ChickenBurger();
            //省略初始化的n行代码
            //......
        } else {
            throw new IllegalArgumentException("未知的汉堡类型");
        }
        return burger;
    }
}

这个时候,客户端在创建汉堡的时候,只需要传入汉堡的类型即可:

public class Client {
    public static void main(String[] args) {
        BurgerFactory burgerFactory = new BurgerFactory();
        Burger beefBurger = burgerFactory.makeBurger("牛肉汉堡");
        Burger chickenBurger = burgerFactory.makeBurger("鸡肉汉堡");
    }
}

像这种,通过工厂类来创建对象,并且根据入参类型来决定创建对象类型的模式,就叫做简单工厂模式。

显然,这样写有个弊端。当业务需要继续拓展的时候,比如新增一个双层芝士汉堡的类,那么又要去修改工厂类的makeBurger方法,每次新增类,都要去新增一个if-else判断,不符合开闭原则。

针对这种情况,可以直接根据每个汉堡的类,都搞一个对应的工厂类,这个工厂类只创建一个类型的汉堡,代码如下:

public interface BurgerFactory {
    Burger makeBurger();
}

public class chickenBurgerFactory implements BurgerFactory{
    @Override
    public Burger makeBurger() {
        Burger chickenBurger = new ChickenBurger();
        //制作鸡肉汉堡的n行代码
        //....
        return chickenBurger;
    }
}

public class BeefBurgerFactory implements BurgerFactory{
    @Override
    public Burger makeBurger() {
        Burger beefBurger = new BeefBurger();
        //制作牛肉汉堡的n行代码
        //....
        return beefBurger;
    }
}

客户端只需要实例化不同的工厂类,就能创建出不同类型的汉堡:

public class Client {
    public static void main(String[] args) {
        BurgerFactory beefBurgerFactory = new BeefBurgerFactory();
        beefBurgerFactory.makeBurger();

        BurgerFactory chickenBurgerFactory = new chickenBurgerFactory();
        chickenBurgerFactory.makeBurger();
    }
}

像这样,一个类对应着一个工厂类,利用多态的特性去创建对象的模式,就是工厂方法模式。

那么,如果业务还需要继续拓展,除了汉堡之外,还有煲仔饭、披萨等其他的类,那么要继续创建一堆的工厂类吗?想要解决这个问题,我们在下一篇文章中,继续讲解!

今天的分享到这里结束了。

关注公众号“徒手敲代码”,免费领取腾讯大佬推荐的Java电子书!