使用接口将Singleton公开给其他类

时间:2017-01-29 19:14:20

标签: c# design-patterns unity3d

我正在使用 Singleton GameManager在Unity C#中制作游戏,我被警告说在GameManager.instance.someVar等其他脚本中使用该类的引用会使代码变得脆弱以后很难编辑。所以我找了如何访问带有接口的单例但是还没找到我想要的东西。由于我希望正确编码,我希望有人指出一个合适的来源告诉我该怎么做,或让他/她简要地告诉我。

3 个答案:

答案 0 :(得分:1)

对此有一个通用的解决方案,我不确定它对你有多可行。

假设我们有一个真正的单身人士:

public static class Highlander //cos, there can be only one. Sorry. couldn't resist
{
   public static void Quicken(string name)
   {
      Console.WriteLine("{0} gets their quickening on",name);
   }
}

假设我们希望能够使用Interfaces以抽象的方式传递它。

public interface IImmortal
{
    void Quicken();
}

好吧,你不能在静态类或成员上实现接口,那么如何通过接口传递对这个类的引用呢?

简单 - 创建一个实现所需接口的包装器/适配器类:

public class McLeod: IImortal
{
   public void Quicken()
   {
       Highlander.Quicken("Conor");
   }
}

public class Kurgen: IImortal
{
   public void Quicken()
   {
       Highlander.Quicken("The Kurgen");
   }
}

现在你可以传递IImortal,并且包装实现只需要调用Singleton。请注意Wrapper如何从内部向Singleton提供数据,如上所述,在这种情况下,它更像是Adapter。但这个概念是一样的。

  

在Unity的情况下,我不知道这是否适合,因为GameManager类可能会暴露大量其他属性和方法,你也需要包装/适应 - 可能不值得创建包装器接口所有这些,所以也许考虑在这种情况下你需要拥抱它:)

答案 1 :(得分:0)

Singletons,是静态的,不支持接口。也许您的其他来源可能意味着您应该使用工厂模式或可能使用控制反转(IOC)方法。在这些情况下,Factory看起来像GameManagerFactory.GetGameInstance()而不是引用GameManager的Instance静态属性。

Singlton编程的真正局限在于单元测试 - 因为您的代码直接绑定到特定类“GameManager”,您无法在单元测试中将其替换为GameManager的另一个“测试版本”。为了支持单元测试,您应该尝试确保代码所依赖的任何重要类都可以替换为类的测试版本,而无需您的代码关注。当使用单身人士时,这很难(如果不是不可能的话)。

答案 2 :(得分:0)

通常我倾向于创建一个空的GameObject,给它一个正确的名称或标签并附加一个脚本组件。

这样我就可以轻松地在任何可能需要它的GameObject中获取引用并从中检索脚本组件。