2014-04-05 31 views
1

我需要一個描述行星系統的類的系統。C#:幫助設計嵌套類的結構

我第一類是atomary空間體:

public class SpaceBody 
{ 
    public string Name; 
    public float Mass; 
    // and so on 
} 

第二個是空間機構的系統,它也是SpaceBody:

public class SpaceBodySystem<ChildType>: SpaceBody where ChildType: SpaceBody, new() 
{ 
    // ... 
    public List<ChildType> Children; 
    // ... 
} 

接下來,我有一個明星:

public class Star: SpaceBodySystem<SpaceBody> 
{ 
    public float Intencity; 
    // ... 
} 

最後,整個明星系統是這樣的 (它可以hav Ë不止一星):

public class StarSystem: SpaceBodySystem<Star> 
{ 
    public bool OccupiedByAliens; 
    // ... 
} 

的問題是: 星星應該有這反過來,可能有他們的衛星的行星(SpaceBodySystem)和這些衛星也可以有自己的衛星等方面。嵌套深度是無限的。

這對我目前的班級制度來說是不可能的。 我必須寫這樣的東西,但這個醜陋的解決方案有限制的層次。

public class StarSystem: SpaceBodySystem<SpaceBodySystem<SpaceBodySystem<SpaceBody>>> 
{ 
    public float Intencity; 
    // ... 
} 

我問社區給我一些建議如何改善這種結構。 我想過其他方案(接口,組合+委派),並沒有設法得到一個可接受的解決方案。

非常感謝您的幫助。

+0

這個問題似乎是題外話,因爲它需要一個代碼審查 - 嘗試codereview.stackexchange.com –

+0

待辦事項BDD光想象,將使用此API一個人爲的開發。也許他們會自動化在發生系統間飛行的發電船。他的劇本會是什麼樣子? (發射船,出口太陽能系統,檢查船員是否還活着,如果死亡,返回家園,如果目的地不適宜居住,請轉到下一步)寫下該劇本,看看班級是否有助於或傷害該使用場景。 – MatthewMartin

回答

1

如果你需要的可能有多個太陽在一個系統中,也許你還想要兩個行星共用一個月亮的可能性。

在這種情況下,也許你應該有一個子系統,它有一個主體陣列和一個衛星陣列。在太陽系中,可以使用星體作爲主體,使用行星作爲衛星。在星系中,也許你可以定義一些抽象的中心點/航點作爲主體,所有的太陽系都是衛星。

因此,對於我們的太陽系,您已經擁有了子系統'SolarSystem',其主體是Sun和sattelites行星,每個行星都是子系統。子系統地球有一個主體地球和一個衛星月球。

擁有一個帶有一個MainBody Earth的SubSystem Earth可能聽起來有點多餘,但也許你可以通過使用接口來解決這個問題,所以像這樣的簡單子系統(有一個主體)可以由一個類來實現, ISubSystem和IMainBody。

或者您可以保持實施更容易,並使地球(系統)成爲一個單獨的子系統,其中一個主體是地球(行星),另一個是具有一個衛星的陣列,它是子系統月球(系統)包含主體月球和沒有衛星。

+0

你對主體和衛星單獨陣列子系統的想法聽起來很合理。 我想我可以得到這個工作與兩個通用參數:MainBodyType和SatteliteType。 似乎 類StarSytem:子系統<星,子系統> 解決了我的「嵌套深度」的問題,不輸多態性從JSON文件加載系統,讓您上面提到的一些優點(兩顆星可以影響一個星球等等)。 謝謝,現在就執行它) – Papirosnik

0

我認爲一個班會做建立一個行星系統:

public class SpaceBody 
{ 
    public string Name; 
    public float Mass; 
    public float Distance; 
    public bool clockwise; 
    //... 
    public SpaceBody RevolvesAround; 
    List<SpaceBody> Satellites; 

} 
+0

它不適合我的情況。 我必須從json文件加載系統(在加載期間創建層次結構),並且此解決方案缺少多態性。 – Papirosnik

0

如果您的系統的基類可以擁有本身是同一基類的實例或派生自其子類的子類,那麼您不需要這樣嵌套。讓我舉一個例子:

public class SpaceBodySystem<ChildType>: SpaceBody where ChildType: SpaceBody, new() 
{ 
    public List<ChildType> Children; 
} 

所以,一個SpaceBodySystem有是SpaceBody類型的孩子,這本身就是一個SpaceBody

public class StarSystem : SpaceBodySystem<Star> 
{ 
} 

這個類可以代表一顆星,或者一對二星,或者任何其他的星。

public class PlanetarySystem : SpaceBodySystem<Moon> 
{ 
    public Planet CentralPlanet; 
} 

這可以代表與任何數量的衛星,從其中SpaceBody繼承Planet行星。

public class SolarSystem : SpaceBodySystem<PlanetarySystem> 
{ 
    public StarSystem CoreStar; 
} 

這個班的學生可以代表與孩子這是可能有衛星所有行星的恆星一些配置,以及太陽能系統。

總之,你並不需要保存從SpaceBody築巢SpaceBodySystem<SpaceBodySystem<SpaceBodySystem<SpaceBody>>>因爲SpaceBodySystem繼承,所以如果你只是有SpaceBodySystem<SpaceBody>,那麼內SpaceBody可能SpaceBodySystem,這威力有進一步的孩子,但你不需要知道。這就是多態的美妙之處。

+0

不,沒有嵌套聲明我不能在這種情況下得到遞歸多態行爲。請參閱我的帖子以獲取解釋。 – Papirosnik

0

需要說另外,我想從數據文件加載我的系統。 假設,我有這個輸入數據(在附件中)。 而且我有讀取並創建SapceBody對象的虛擬方法。

class SpaceBody... 
{ 
    ... 
    public virtual void CreateGameObject() 
    { 
     instance = new GameObject(); 
    } 
    ... 
} 

class SpaceBodySystem... 
{ 
    ... 
    public override void CreateGameObject() 
    { 
     base.GameObject(); 
     foreach(ChildType child in Children) 
     { 
      child.CreateGameObject(); 
     } 
    } 
    ... 
} 


class Star: SpaceBodySytem<SpaceBody> 
{ 
    ... 
    public override void CreateGameObject() 
    { 
     base.GameObject(); 
     doExtraWorkForTheStar(); 
    } 
    ... 
} 

StarSystem.CreateObject(); 
// for attached file, will load and create one star (Sun) and nine planets. 

因此,如果我使用anaximander提出的聲明,系統不會看到孩子的孩子。例如,地球是SpaceBody(但應該是SpaceBodySytem),在這種情況下不會創建月球。

GolezTrol的想法很好。

solarsystem.json