「补课」进行时:设计模式(2)——通过一个超级汽车工厂来了解工厂模式

it2025-07-09  6

1. 超级汽车工厂

汽车相信大家都不陌生,我们现在最常用的交通工具得益于在奔驰在 1885 年研制的第一辆「三轮车」,就是下面这个家伙:

今天我来试一下使用程序通过汽车工厂来造汽车。

1.1 定义一辆汽车

public interface Car { void name(); void drive(); }

身为一辆汽车,首先要有自己的名字,其次是要能开,有了这两个东西,基本上就能叫一辆汽车了。

1.2 定义一辆特斯拉、一辆奔驰、一辆奥迪

public class Tesla implements Car { @Override public void name() { System.out.println("我是特斯拉!!!"); } @Override public void drive() { System.out.println("我是特斯拉,速度贼快!!!"); } } public class Benz implements Car { @Override public void name() { System.out.println("我是奔驰!!!"); } @Override public void drive() { System.out.println("我是奔驰,内饰豪华!!!"); } } public class Audi implements Car { @Override public void name() { System.out.println("我是奥迪!!!"); } @Override public void drive() { System.out.println("我是奥迪,科技感十足!!!"); } }

这里定义了三辆汽车,分别实现了他们的父亲的两个方法。

1.3 定义抽象汽车工厂

身为一个超级汽车工厂,当然是要能造汽车,我们创建汽车的时候,肯定是希望直接告诉工厂,我要造一辆特斯拉还是造一辆奥迪。

如果是使用特斯拉或者是奥迪作为输入参数,那么创建的方法我们就需要分别写 3 个了,在 Java 中,这里可以使用泛型来作为输入参数,控制参数的输入类型。

public abstract class AbstractCarFactory { public abstract <T extends Car> T createCar(Class<T> clazz); }

这里使用泛型首先定义了泛型 T 是 Car 的子类,限制了 T 的类型,其次是输入参数必须是 Class 类型。

1.4 汽车创建工厂

接下来,我们定义一个实际的汽车创建工厂:

public class CarFactory extends AbstractCarFactory { @Override public <T extends Car> T createCar(Class<T> clazz) { Car car = null; try { car = (T)Class.forName(clazz.getName()).newInstance(); } catch (Exception e) { System.out.println("汽车生产出错啦,请回炉重造!"); } return (T) car; } }

1.5 开始生产汽车

public class Test { public static void main(String[] args) { AbstractCarFactory carFactory = new CarFactory(); System.out.println("-- 第一辆车生产特斯拉 --"); Car tesla = carFactory.createCar(Tesla.class); tesla.name(); tesla.drive(); System.out.println("-- 第二辆车生产奔驰 --"); Car benz = carFactory.createCar(Benz.class); benz.name(); benz.drive(); System.out.println("-- 第三辆车生产奥迪 --"); Car audi = carFactory.createCar(Audi.class); audi.name(); audi.drive(); } }

生产的结果如下:

-- 第一辆车生产特斯拉 -- 我是特斯拉!!! 我是特斯拉,速度贼快!!! -- 第二辆车生产奔驰 -- 我是奔驰!!! 我是奔驰,内饰豪华!!! -- 第三辆车生产奥迪 -- 我是奥迪!!! 我是奥迪,科技感十足!!!

2. 工厂模式

首先是工厂模式的定义:

Define an interface for creating an object,but let subclasses decide whichclass to instantiate.Factory Method lets a class defer instantiation tosubclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)

下面是一个通用类图:

Product: 用于定义产品特性,实现对事物最抽象的定义,就像上面定义的 Car 。ConcreteProduct: 具体对产品定义的实现,就上上面定义的特斯拉和奥迪。Creator: 抽象工厂,用于最抽象对 Product 的构造的定义。ConcreteCreator: Creator 的具体实现,具体实现如何创建产品类。

2.1 抽象产品类

public abstract class Product { public void method1() { } public abstract void method2(); }

2.2 具体产品类

public class ConcreteProduct1 extends Product { @Override public void method2() { } } public class ConcreteProduct2 extends Product { @Override public void method2() { } }

具体的产品类可以有多个,都继承于抽象的产品类。

2.3 抽象工厂类

public abstract class Creator { public abstract <T extends Product> T createProduct(Class<T> clazz); }

2.4 具体工厂类

public class ConcreteCreator extends Creator { @Override public <T extends Product> T createProduct(Class<T> clazz) { Product product = null; try { product = (Product) Class.forName(clazz.getName()).newInstance(); } catch (Exception e) { // 异常处理 } return (T) product; } }

具体如何产生一个产品的对象的实现,是由具体的工厂类进行实现的,具体的工厂类可以有多个,用于实现多条产品线的生产。

2.5 优点

良好的封装性,代码结构清晰。良好的扩展性。如果我们需要增加产品类,只需要修改具体的工厂类或者扩展一个新的具体工厂类即可。屏蔽产品类。工厂模式是点型的解耦框架,高层次的模块只需要知道产品的抽象类,其他的实现类都不需要关心。

3. 工厂模式扩展——多个工厂类

前面说工厂模式可以有多个具体工厂,如果项目复杂度足够高,将所有的产品都放在一个工厂类中做初始化有点不够清晰,那么我们可以实现多个工厂类,由每一个工厂类对应不同的业务规则做对应的产品类的初始化操作。

我如果把上面的那个超级汽车工厂改成多工厂类,先画一个类图:

这个代码我就不写了,和上面的差不多,就是从原来的一个工厂生产三种车变成了三个专属工厂生产三种车。

您的扫码关注,是对小编坚持原创的最大鼓励:) 极客挖掘机 认证博客专家 Redis Java Spring 一个来自十八线城乡结合部破写代码的,平时喜欢读读书、写写代码,从2019年开始运营有自己的个人公众号:极客挖掘机,想交流的朋友可以来公众号找我聊天。
最新回复(0)