[英]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.使用事件
引入GameStarting
和GameStarted
事件會將初始化委托給類型本身。 讓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.