团结-依赖注入和单行为的斗争

时间:2019-10-31 11:37:57

标签: c# unity3d dependency-injection

因此,我正在尝试DI并尝试创建GameObject Generator。 GameObject Generator会根据一些内部逻辑在场景内生成GameObject。

生成哪种类型的游戏对象会有所不同,逻辑也会有所不同。

我认为我可以创建一个接口,并能够根据“唯一逻辑”创建一个类(即,对于每种生成器行为,我都会创建一个类,并且可以在生成许多小对象和几个大对象之间进行切换,而无需必须使用if语句,而必须使用多态的功能。

所以我有类似的东西

GameObjectGenerator : Monobehaviour
IGeneratorType

SmallGenerator : Monobehaviour, IGeneratorType
BigGenerator : Monobehaviour, IGeneratorType

从逻辑上讲,这似乎是有道理的。

从这些生成器过渡时,问题再次出现。 我想要某种条件,从IGeneratorType调用方法“ TransitionGenerator” 返回一个新的IGeneratorType。从逻辑上讲,它也在工作。

但是,我想跟踪生成的对象(例如在列表中),因为以后需要销毁它们。 过渡时,需要将生成的对象列表传递给新的IGeneratorType。 这是我发现自己挣扎的地方。

从IGeneratorType实现的类也需要扩展Monobehaviour,因为我需要调用Instantinate和Destroy。

但是由于它们是从Monobehaviour扩展而来的,所以我似乎无法创建构造函数。

经过一些研究,我发现很多人都指向“唤醒/启动”或创建Init方法。

问题是,使用“唤醒/启动”我无法传递任何内容,而使用Init,则需要将其也放入接口,从设计的角度来看,这对我来说并没有太多意义。

示例代码:

public class GameObjectGenerator : Monobehaviour{
    private IGeneratorType generator;
    public void Start(){
        generator = new SmallGenerator();
    }

    public void Update(){
        generator.Generate();
        if(somecondition){
            generator = generator.Transition();
        }
    }
}

public interface IGeneratorType{
    void Generate();
    IGeneratorType Transition();
}

public class SmallGenerator : Monobehaviour, IGeneratorType{
    private List<GameObject> generatedObjects;
    public SmallGenerator(/*List<GameObject> previousObjects*/){
        //generatedObjects = previousObjects;
    }

    public void Generate(){
        //...
        if(somespecificcond){
            generatedObjects.Add(Instantiate(...));
        }
        if(somecondition){
            Destroy(generatedObjects[0])
        }
    }

    public IGeneratorType Transition(){
        return new BigGenerator(/*generatedObjects*/);
    }
}


public class BigGenerator : Monobehaviour, IGeneratorType{
    private List<GameObject> generatedObjects;
    public BigGenerator(/*List<GameObject> previousObjects*/){
        //generatedObjects = previousObjects;
    }

    public void Generate(){
        //...
        if(somespecificothercond){
            generatedObjects.Add(Instantiate(...));
        }
        if(somecondition){
            Destroy(generatedObjects[0])
        }
    }

    public IGeneratorType Transition(){
        return new SmallGenerator(/*generatedObjects*/);
    }
}

1 个答案:

答案 0 :(得分:0)

我刚刚找到了针对此特定情况的最简单的解决方法:

public class BigGenerator : IGeneratorType{
    private List<GameObject> generatedObjects;
    public BigGenerator(/*List<GameObject> previousObjects*/){
        //generatedObjects = previousObjects;
    }

    public void Generate(){
        //...
        if(somespecificothercond){
            generatedObjects.Add(Object.Instantiate(...));
        }
        if(somecondition){
            Object.Destroy(generatedObjects[0])
        }
    }

    public IGeneratorType Transition(){
        return new SmallGenerator(/*generatedObjects*/);
    }
}

之所以可行,是因为“实例化”和“销毁”是“对象”的静态方法,“游戏对象”继承了该方法。

但是,如果一个人确实必须继承单行为,这并不能解决问题