簡體   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