You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带工厂创建器的工厂初始化器?优化多参数实例化

嗨,我来帮你搞定这两个问题——先聊聊带工厂创建器的工厂初始化器怎么实现,再给你拆解多参数实例化的优化思路,结合你提供的代码来具体说明~

一、实现带工厂创建器的工厂初始化器

简单来说,带工厂创建器的工厂模式就是「工厂的工厂」:我们先定义抽象的工厂接口,再实现多个具体工厂(每个工厂负责创建一类对象),最后用一个「工厂创建器」来根据需求返回对应的具体工厂,再由这些工厂去创建业务对象。这样能把对象创建的逻辑进一步解耦,尤其是当你有多个类似的类需要创建时,扩展性会更强。

结合你的MyClass,咱们来写个具体实现:

第一步:定义抽象工厂接口

先给工厂定一个统一的创建标准:

public interface IObjectFactory
{
    object Create(object initParams);
}

第二步:实现具体工厂(针对MyClass)

这个工厂专门负责创建和初始化MyClass:

public class MyClassFactory : IObjectFactory
{
    public object Create(object initParams)
    {
        if (initParams is MyClassInitParams param)
        {
            MyClass instance = new MyClass();
            if (instance != null && instance.Initialize(param))
            {
                return instance;
            }
        }
        return null;
    }
}

第三步:实现工厂创建器

这个类负责根据你传入的标识(比如类型名、枚举)返回对应的具体工厂:

public static class FactoryCreator
{
    public static IObjectFactory GetFactory(string factoryType)
    {
        switch (factoryType)
        {
            case "MyClass":
                return new MyClassFactory();
            // 以后新增其他类的工厂,直接在这里加case就行
            default:
                throw new System.ArgumentException("Unsupported factory type");
        }
    }
}

第四步:改造你的MyClass适配新结构

把原来的多参数Initialize改成接收参数对象的形式(后面会详细说这个优化):

using UnityEngine;

public class MyClass
{
    float myFloat;
    int myInt;
    object[] myObjects;

    public bool Initialize(MyClassInitParams param)
    {
        myFloat = param.MyFloat;
        myInt = param.MyInt;
        myObjects = param.MyObjects;
        return true;
    }
}

// 定义参数对象,后面会用到
public class MyClassInitParams
{
    public float MyFloat { get; set; }
    public int MyInt { get; set; }
    public object[] MyObjects { get; set; }
}

调用示例

现在你可以通过工厂创建器拿到工厂,再创建对象:

// 1. 获取对应工厂
var factory = FactoryCreator.GetFactory("MyClass");
// 2. 准备初始化参数
var paramsObj = new MyClassInitParams
{
    MyFloat = 3.14f,
    MyInt = 100,
    MyObjects = new object[] { "a", 1, true }
};
// 3. 创建实例
MyClass myInstance = factory.Create(paramsObj) as MyClass;

这样一来,以后你新增其他需要工厂创建的类,只需要新增对应的工厂类和参数类,然后在FactoryCreator里加个case就行,完全符合开闭原则~

二、多参数实例化的优化方案

你提到要传10个参数的情况确实很头疼,这里给你几个实用的优化思路,按场景选就行:

1. 最常用:参数对象(Parameter Object)模式

这是解决多参数最直接的方法——把所有初始化参数封装成一个独立的类,这样不管多少个参数,只需要传一个对象就行,而且后续修改参数也不用改Create和Initialize的方法签名。

比如刚才上面用到的MyClassInitParams就是这个思路,改造后你的Create方法会变成这样:

public static MyClass Create(MyClassInitParams param)
{
    MyClass instance = new MyClass();
    if (instance != null && instance.Initialize(param))
    {
        return instance;
    }
    return null;
}

调用的时候只需要创建并赋值参数对象,可读性和维护性都大大提升。

2. 适合有默认值的场景:可选参数+默认值

如果你的部分参数有合理的默认值,可以给方法参数设置默认值,这样调用的时候只需要传必要的参数:

public static MyClass Create(
    float in_somefloat = 0f, 
    int in_someInt = 0, 
    object[] someObject = null)
{
    MyClass instance = new MyClass();
    if (instance != null && instance.Initialize(in_somefloat, in_someInt, someObject ?? new object[0]))
    {
        return instance;
    }
    return null;
}

// 调用示例:只传需要的参数
var instance1 = MyClass.Create(in_somefloat: 5.2f);
var instance2 = MyClass.Create(in_someInt: 200, someObject: new object[] { "test" });

不过这个方案适合参数不多且默认值明确的情况,参数太多的话还是参数对象更清晰。

3. 适合复杂配置场景:构建者(Builder)模式

如果你的参数不仅多,而且很多是可选的,或者需要分步配置,构建者模式会非常合适。咱们给MyClass写个构建者:

public class MyClassBuilder
{
    private float _myFloat = 0f;
    private int _myInt = 0;
    private object[] _myObjects = new object[0];

    public MyClassBuilder SetFloat(float value)
    {
        _myFloat = value;
        return this; // 链式调用
    }

    public MyClassBuilder SetInt(int value)
    {
        _myInt = value;
        return this;
    }

    public MyClassBuilder SetObjects(object[] value)
    {
        _myObjects = value ?? new object[0];
        return this;
    }

    public MyClass Build()
    {
        MyClass instance = new MyClass();
        instance.Initialize(_myFloat, _myInt, _myObjects);
        return instance;
    }
}

// 调用示例:链式设置参数,清晰直观
var myInstance = new MyClassBuilder()
    .SetFloat(3.14f)
    .SetInt(100)
    .SetObjects(new object[] { "a", 1 })
    .Build();

这种方式的好处是可以灵活组合参数,而且代码可读性极高,尤其适合参数有多种组合的场景。

4. 适合依赖服务的场景:依赖注入(DI)

如果你的参数里有很多是依赖的服务(比如其他Manager、工具类),可以用Unity的依赖注入(或者第三方容器比如Zenject)来自动注入,不用手动传参。比如:

// 假设MyClass依赖一个IMyService
public class MyClass
{
    private IMyService _myService;
    float myFloat;
    int myInt;

    // 构造函数注入
    public MyClass(IMyService myService)
    {
        _myService = myService;
    }

    public bool Initialize(float in_somefloat, int in_someInt)
    {
        myFloat = in_somefloat;
        myInt = in_someInt;
        return true;
    }
}

然后在Unity里配置DI容器,创建实例时容器会自动注入IMyService的实现,你只需要传必要的业务参数就行。


内容的提问来源于stack exchange,提问作者user9673893

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:57:01