我想我會在我的代碼中使用一個案例研究作爲我的意思的例子。.Net中的接口繼承/層次結構 - 有更好的方法嗎?
現在,我正在研究基於組件的遊戲系統的行爲/操作系統。 GameObjects可以有一個IBehaviorComponent以及附屬於他們的IActionComponent,其中,只顯示相關細節,暴露了以下內容:
public interface IBehaviorComponent : IBaseComponent
{
IBehavior Behavior { get; }
}
public interface IActionComponent : IBaseComponent
{
IAction Action { get; }
void ExecuteAction(IGameObject target = null);
}
現在,這是所有罰款至今(至少對我來說!)。但是,當我查看IActionComponent的實現時,麻煩開始釀成。
例如,一個簡單的IActionComponent實現:
public class SimpleActionComponent : IActionComponent
{
public IAction Action { get; protected set; }
public void ExecuteAction(IGameObject target = null)
{
Action.Execute(target);
}
public void Update(float deltaTime) { } //from IBaseComponent
}
但是,讓我們說,我想介紹一個更復雜的IActionComponent實現,它允許在一個定時的時間表來執行的動作:
public class TimedActionComponent : IActionComponent
{
public IAction Action { get; protected set; }
public float IdleTime { get; set; }
public float IdleTimeRemaining { get; protected set; }
public void ExecuteAction(IGameObject target = null)
{
IdleTimeRemaining = IdleTime;
}
public void Update(float deltaTime)
{
if (IdleTimeRemaining > 0f)
{
IdleTimeRemaining -= deltaTime;
}
else
{
Action.Execute(target);
}
}
}
現在,我們假設我想公開IdleTime,以便可以通過外部影響來改變它。我起初的想法是創建一個新的接口:
public interface ITimedActionComponent : IActionComponent
{
float IdleTime { get; set; }
float IdleTimeRemaining { get; set; }
}
然而,這裏的問題是,我的組件系統存儲從IBaseComponent一個級別了一切。因此,GameObject的操作組件被檢索爲IActionComponent,而不是像ITimedActionComponent或IRandomizedActionComponent,甚至是ICrashTheProgramActionComponent。我希望這個原因很明顯,因爲我希望能夠查詢GameObject的某個組件,而不必知道組件的基本類型(IActionComponent,IRenderableComponent,IPhysicsComponent等)的確切需求。
是否有一個更簡潔的方式來處理這個問題,這將允許我公開在子類中定義的這些屬性,而不必將所有檢索到的IActionComponent轉換爲它感興趣的類型?或者,這只是實現這一點的唯一/最好的方式。喜歡的東西:
public void IWantYouToAttackSuperSlow(IGameObject target)
{
//Let's get the action component for the gameobject and test if it's an ITimedActionComponent...
ITimedActionComponent actionComponent = target.GetComponent<IActionComponent>() as ITimedActionComponent;
if (actionComponent != null) //We're okay!
{
actionComponent.IdleTime = int.MaxValue; //Mwhaha
}
}
現在,我想這是必由之路,但我想我會看看有沒有躲在我是無知的,或木製品的模式,如果任何人都可以提出一個更好的方法來完成這個開始。
謝謝!
我的另一個想法是內部使用另一個對象,如IActionComponentExecutor,這將決定何時調用Action.Execute(),但我認爲這讓我回到了圓桌會議的方式 - 外部對象將不得不追蹤IActionComponentTimedExecutor(哦〜我們現在正在開始enterprise-y !)更改IdleTime。 – Terminal8
出於興趣 - ActionComponent.IdleTime是否存儲在某種通用包中?如果是這樣,你可以在你的基本界面上使用'應用(BagData bag)'和'存儲(BagData bag)'方法。也就是說,您可能還需要考慮一些元數據類型系統,您可以使用它來查詢屬性,但需要知道派生類型。 「TypeDescriptor」是物業網格等東西使用的現成捲起點。 –
不,目前不是。我對這個概念並不完全熟悉 - 有沒有可能提供的參考? – Terminal8