Unity-工厂设计模式

发布时间 2023-11-14 19:18:05作者: Daliuteliu

Unity-工厂设计模式

原文出处:工厂方法设计模式 (refactoringguru.cn)

简介

工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。

工厂(方法)模式

问题引入

​ 假设你正在开发一款物流管理应用。 最初版本只能处理卡车运输, 因此大部分代码都在位于名为 卡车的类中。

​ 一段时间后, 这款应用变得极受欢迎。 你每天都能收到十几次来自海运公司的请求, 希望应用能够支持海上物流功能。

​ 这可是个好消息。 但是代码问题该如何处理呢? 目前, 大部分代码都与 卡车类相关。 在程序中添加 轮船类需要修改全部代码。 更糟糕的是, 如果你以后需要在程序中支持另外一种运输方式, 很可能需要再次对这些代码进行大幅修改。

问题解决

​ 为了解决上述问题,而又不需要大幅修改卡车类的原代码,我们就需要使用工厂方法模式。

​ 要使用工厂方法模式,就需要使用特殊的工厂方法来代替对构造函数的直接调用(即直接使用 new 运算符)。对象仍然通过 new 运算符创建,只是 new 运算符的调用改在工厂方法中调用罢了。工厂方法返回的对象通常被称作 “产品”。

​ 更加具体的说,我们需要在一开始创建一个工厂父类,里面包括一个抽象方法——工厂方法,要求工厂继承该父类时,必须实现这个抽象的工厂方法,以完成创建对应产品的任务。

image-20220509210712825

根据上述图片可以写出如下代码:

public abstract class Factory //工厂父类 供子类继承
{
    public abstract Product CreateProduct();//提供一个抽象方法,要求子类必须实现
}

//下面是Car、Boat两个子类,都继承了Factory父类,同时实现了不同的方法
public class Car : Factory
{
    public override Product CreateProduct()
    {
        return new ProductA();//创建产品子类A
    }
}
public class Boat: Factory
{
    public override Product CreateProduct()
    {
        return new ProductB();//创建产品子类B
    }
}

//产品接口,给产品子类继承并实现方法
public interface Product
{
     void doStuff();
}

//两个产品子类,实现了不同的doSutff方法
public class ProductA : Product
{
    public void doStuff()
    {
        Debug.Log("填装卡车");
    }
}
public class ProductB : Product
{
    public void doStuff()
    {
        Debug.Log("填装轮船");
    }
}

//主类,用于调用工厂
public class MainClass: MonoBehaviour
{
    private void Start() 
    {
        CreateAndDo();
    }

    void CreateAndDo()
    {
        //创建汽车工厂并调用doStuff函数
        Factory car = new Car();
        car.CreateProduct().doStuff();

        //创建轮船工厂并调用doStuff函数
        Factory boat = new Boat();
        boat.CreateProduct().doStuff();
    }
}

最终效果:

image-20220509210620122

​ 可以看见我不需要知道工厂具体创建了什么对象,就可以直接调用其创建的对象中包含的函数。在很多正式的项目中,产品子类划分的更具体,子类个数也更多,使用工厂设计模式可以很好的将代码进行封装。这样极大的提高了代码的复用性可拓展性

工厂方法模式适用范围

  1. 当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
  2. 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
  3. 如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。(实现多对象池)

抽象工厂

抽象工厂 也就是工厂方法模式的拓展。在真实的项目中,很少有一个工厂只创建一个对应类的情况,很多时候都是 一个工厂同时可以创建同种风格的不同产品

​ 例如:一个家具工厂,同时可以制作椅子、桌子、床等日常家具,但又根据家具工厂所处的地域不同,所制作的家具风格可能大不相同,但是不管是什么风格的椅子,都可以满足人坐在椅子上的需要。

​ 要实现抽象工厂的设计模式,只需要多创建一个不同的产品类接口不同风格的对应产品继承并实现该接口,同时在抽象工厂类中多写一个创建该产品类的函数即可。

image-20220510205708457

(对比上图与之前工厂方法模式的图,我们不难发现,不相同的地方只有抽象工厂里多了一个可以创建产品b的函数,和一个新的产品接口。上述函数同样可以由工厂子类重写,生产出对应的产品)

需注意的点

​ 通过工厂类创建对象,根据 外部传入的信息 创建对应的工厂或产品,而不是自身创建。

​ 例如:

一个日本人来到餐厅,说要吃一顿午餐,老板看见他是日本人,就叫日本厨师做了几道日本菜给这位日本客人。

​ 在这个例子中,餐厅就是工厂,日本人就是信息,老板就是调配工厂类,厨师就是工厂,而菜是产品。

外部函数将自身信息作为参数,调用调配工厂类中的函数,以创建对应的产品