设计模式之抽象工厂模式
Contents
需求
暂且不提工厂模式, 我们先了解一个简单的需求, 然后通过这个需求的改进过程了解工厂模式。 需求如下 :
假设现在,我有一辆车Car,它有一个 go() 方法, 代码很简单,如下 :
|
|
我们同时有一辆新的交通工具飞机 Airplane, 同样也有一个 go() 方法, 代码如下 :
|
|
这时,如果我们第一次坐🚗Car, 然后再坐✈️飞机,代码就得这样写:
|
|
在坐车时, new一个 🚗对象,🚗.go().
在坐飞机时,new 一个✈️对象, ✈️go().
这时候,如果我们又要坐火车🚄呢?
我们要做的就是,再添加一个 Train类,并实现 🚄的 go() 方法。 并在 main 函数中 new 一个🚄对象,🚄.go();
所以,每次添加一种交通工具,我们都需要添加类,并实现 go() 方法。 有没有更好的方法,可扩展性更好呢?
答案就是,为交通工具建一个父类。利用面向对象的多态,增加可扩展性。
- 在Java中,我们可以使用 抽象父类 abstract class 解决
- 也可以使用 interface接口解决,这里我们使用 interface解决
- 新建一个 interface 接口 Moveable,其中添加一个方法 go()
- 并且让我们所有的交通工具都实现 Moveable 接口的方法 go()
|
|
|
|
|
|
这时,Main函数中的代码就可以这样写
|
|
以上是多态的简单运用。
我们又有新的需求? 定制生产过程, 也就是,在 new Car() 的前后,需要做一些事情。 如果按照上边方法做,就需要在main 函数中一通修改。如果更方便的定制生产过程? 引入了我们的主角,工厂模式。
定义
什么是工厂呢?
- 任何可以产生对象的方法或类,都可以称之为工厂
- 单例也是一种工厂
- 工厂主要有三种
- 简单工厂
- 工厂方法
- 抽象工厂
一,简单工厂
接下来,我们通过,简单工厂模式,来解决 定制生产过程 的问题
- 我们创建一个 VehicelFactory ,此类专门用来生产各种交通工具
- 这样,我们就可以在 工厂类中,定制生产交通工具时业务逻辑所需要的过程
|
|
我们main 函数处的代码就简单了
|
|
- 以上就是简单工厂模式的一个应用
- 有一些缺点
- 扩展性并不好
- 增加一种交通工具,就需要在 VehicelFactory中创建方法,和一大堆的业务逻辑
- 随着业务逻辑变多,VehicelFactory 会变得越来越庞大,难以维护
- 扩展性并不好
如何解决,VehicelFactory 不好扩展的问题呢 ? 答案就是: 工厂方法
二,工厂方法
- 工厂方法,也是使用工厂类创建交通工具
- 不同之处在于,工厂方法中,我们为每个类,创建一个 Factory用于定制其生产过程。
- 比如,我们为 Car创建一个 CarFactory 类生产 🚗
- 为 Airplane创建一个 AirplaneFactory类 生产 ✈️
- 很显然,工厂方法不会产生庞大的 VehicelFactory 工厂
- 增加一种交通工具时,为新的交通工具创建对应的 Factory 即可
代码如下 :
|
|
|
|
|
|
- 这样我们就解决了,在交通工具类很多时扩展性的问题
现在, 我们又有新需求了。 如何定制一系列的产品呢?
比如一个现实世界的人,可以一辆车,可以拿武器AK47,可以吃面包
而一个魔法世界的人,可以 骑扫帚,可以拿武器魔法棒, 可以吃蘑菇
…
如何来定制这一类人对应的一系列产品呢 ? 答案就是,抽象工厂模式
三,抽象工厂模式(Abstract Factory)
这里的一系列产品,是一个 产品族 的概念,接下来我们使用抽象工厂来实现灵活的扩展产品族。
- 我们先定义一个 抽象工厂 AbstractFactory,并且此类中,有以下三个抽象方法
|
|
-
再定义两个 类型的工厂 ,都继承自 AbstractFactory,并且实现 AbstractFactory 的三个抽象方法
-
现代人的工厂 MordernFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public class MordernFactory extends AbstractFactory{ @Override Food createFood() { return new Bread(); } @Override Vehicle createVehicle() { return new Car(); } @Override Weapon createWeapon() { return new AK47(); } }
-
魔法世界的人的工厂 MagicFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public class MagicFactory extends AbstractFactory { @Override Food createFood() { return new MushRoom(); } @Override Vehicle createVehicle() { return new Broom(); } @Override Weapon createWeapon() { return new MagicStick(); } }
-
…
-
定义三个 抽象类
- Food 抽象的食物类, 并且其中有 eat() 抽象方法
- 使MushRoom 和 Bread 都继承 Food。并且实现 eat() 方法
- Weapon 抽象的武器类,并且其中有 attack() 抽象方法
- 使AK47 和 MagicStick都继承自 Weapon。并且实现 attack() 方法
- Vehicle 抽象的交通工具类,并且有 go() 抽象方法
- 使Car 和 Broom 都继承自 Vehile。 并且实现 go() 方法
- Food 抽象的食物类, 并且其中有 eat() 抽象方法
-
在main函数中使用时,我们只需要,使用对应的具体的工厂,调用方法即可.
1 2 3 4 5 6 7
public static void main(String[] args) { // AbstractFactory abstractFactory = new MagicFactory(); AbstractFactory abstractFactory = new MordernFactory(); abstractFactory.createFood().eat(); abstractFactory.createVehicle().go(); abstractFactory.createWeapon().attack(); }
-
以上就是,三种工厂模式的使用例子。
总结
以上三种工厂模式有什么优缺点呢?
- 工厂方法,方便的是产品的扩展
- 优点 : 增加新的产品类时无须修改现有系统,并封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性
- 缺点 : 在于增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。
- 抽象工厂方法,方便的是产品族的扩展
- 优点 : 增加新的工厂和产品族容易
- 缺点 : 增加新的产品等级结构麻烦
- 两者都有自己的局限性
Author 飞熊
LastMod Jul 04