繁体   English   中英

调用实现的接口方法,但区分它们对某些对象的调用

[英]Call implemented interface methods, but distinguish their calls on certain objects

我正面临一个设计问题,在该问题中,我试图调用实现具有方法“ Initialize”的特定接口IInitialize的所有对象。

“ IInitialize”可以实现多个类,例如GameManager,Player,Enemy等。

但是,IInitialize也可以在其他类中实现,这些类不必在我想说重新启动游戏的那一刻就进行初始化,因此我需要对Init调用进行某种“分类”,以便其他类不会得到在不需要他们时打电话给我。

因此,在这里我几乎没有其他选择,例如创建另一个空的“ IInitialize”子类,然后仅通过此类型调用“ Initialize”。 实现子类的所有类都将获得此调用。 (它有效,但这是一种正确的方法-没有代码气味?)。

另一种选择是创建一个通用的“ Initialize”接口,然后仅传递字符串或类似内容以区分调用。

回顾一下:我实现了各种类的接口,假设“ ILife”在类中实现了“ Die”方法。 但是,我不希望所有类型的对象都在某个特定时间死掉,而只是要求的对象死掉。

还有其他想法还是我走错了方向?

提前致谢!

由于此问题被标记为C#,因此我将在代码示例中使用C#。 但是这些解决方案也适用于任何面向对象的语言。

这是设计问题。 您有很多解决方案。 我将展示三个:

1.使用适合特定情况的单独接口

interface IInitializable
{
  void Initialize();
}

interface IGameStartInitializable : IInitialize
{
}

如果两个接口绝对共享相同的成员,则此解决方案,尤其是IGameStartInitializable接口,将具有标记接口的特性和不良设计的证明。

我不推荐这种解决方案。

2.为对象使用单独的容器

public List<IInitialize> DefaultInitializables = new List<IInitialize>();

public List<IInitialize> GameStartupInitializables = new List<IInitialize>();

现在,您已将每个对象添加到相应的集合中,您可以轻松地遍历它们。 这比第一种解决方案更为优雅。

3.使用事件

引入GameStartingGameStarted事件会将初始化委托给类型本身。 IInitialize类型的对应实例订阅此事件。 他们的事件处理程序将自行调用IInitialize.Initialize()

class Player : IInitialize
{
  public Player(IGameEngine gameEngine)
  {
    gameEngine.Starting += InitializeOnGameStarting;
  }

  private void InitializeOnGameStarting(object sender, EventArgs e)
  {
    gameEngine.Starting -= InitializeOnGameStarting;

    // Invoke the implemented member of IInitialize
    Initialize();
  }
}

这是最优雅的方式。 它是可扩展的,因为每个实现都处理自己的初始化。 无需过滤或排序(将实现添加到正确的集合中)和迭代。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM