2012-12-15 96 views
1

我一直在研究一個使用C++的小型項目(儘管這個問題可能被認爲是與語言無關的),我正在努力編寫我的程序,使其儘可能高效和封裝。我是一個自學成才,缺乏經驗的程序員,但我試圖在使用界面和麪向對象操作時教會自己良好的習慣。當涉及訪問充當另一個類的子系統的對象的方法時,我主要關注典型的「最佳」實踐。面向對象和設計實踐:訪問成員對象的功能?

首先,讓我解釋一下我的意思是:

ClassGame實例希望使用的ClassEngine私人ClassRenderer子系統呈現出一個2D精靈形象。 ClassGame只能訪問ClassEngine的接口,並且ClassRenderer應該是ClassEngine的子系統(位於抽象層之後)。

我的問題是基於ClassGame對象可以間接使用ClassRenderer的功能,同時仍然保持快速並在抽象層後面的方式。從我的經驗和別人的代碼示例所看到的,似乎有這樣的兩種基本方式:

  1. ,我通過了一系列關於面向對象設計的在線講座,學到的第一種方法是讓一個類在內部將任務委託給它的私有成員對象。 [在這個例子中,ClassGame會調用一個屬於ClassEngine的方法,並且ClassEngine會'祕密'通過調用其中一個方法將該請求傳遞給它的ClassRenderer子系統。 ]函數調用的「菊花鏈」。這對我來說很有意義,但似乎可能比其他選項慢。

  2. 我在其他人的代碼中看到的另一種方法是使用訪問器方法,該方法返回指向特定子系統位置的引用或指針。 [所以,ClassGame會在ClassEngine中調用一個簡單的方法,該方法將返回一個引用/指針指向構成其ClassRenderer子系統的對象]。這條路線對我來說似乎很方便,但它似乎也消除了讓私人成員充當更大班級的子組件的觀點。當然,這也意味着編寫更少的「無意識」的功能,只是通過一個特定的任務,因爲您可以爲每個獨立的子系統編寫一個getter函數。

考慮OO設計(抽象,封裝,模塊化,可用性,可擴展性,等)的各個重要方面,同時還考慮到的速度和性能,是它更好地使用所述第一或第二類型的方法將任務委託給子組件?

+1

你真的命名你的類'ClassGame'等等嗎?然後,一個簡單的(雖然不相關的)代碼改進就是放棄這些前綴 – carlpett

+0

不,我通常會將我的類命名爲Game,Engine,RenderSystem等。我認爲它在非牆代碼文本。雖然,我的命名約定可能遠沒有好...哈哈。 – MrKatSwordfish

+1

他們從投票櫃檯中拿出了大膽,所以你可以在你的問題中使用它? –

回答

1

有很多方法可以做你想做的事情,它確實取決於上下文(例如,項目有多大,你期望在其他項目中重複使用多少等等。)

您有三個類:遊戲,引擎和渲染器。你的兩個解決方案都會讓遊戲提交到引擎的界面。第二種解決方案也讓遊戲提交給渲染器的界面。顯然,你使用的接口越多,如果接口發生變化,你就必須改變的越多。

第三個選項如何:遊戲知道它在渲染方面的需求,因此您可以創建一個描述這些需求的抽象類。這將是遊戲承諾的唯一接口。我們稱之爲AbstractGameRenderer接口。

爲了將其與系統的其他部分聯繫起來,還有很多方法。一種選擇是: 1.使用現有的Renderer類實現這個抽象接口。所以我們有一個使用Renderer並實現了AbstractGameRenderer接口的類GameRenderer。 2.引擎創建Game對象和GameRenderer對象。 3.引擎將GameRenderer對象傳遞給Game對象(使用指向AbstractGameRenderer的指針)。

結果:遊戲可以使用渲染器來完成自己想要的任務。它不知道它來自哪裏,它如何呈現,誰擁有它 - 什麼也不知道。 GameRenderer是一個特定的實現,但其他實現(使用其他渲染器)可以稍後寫入。引擎「知道一切」(但這可能是可以接受的)。

之後,您想要將遊戲的邏輯用作另一款遊戲中的迷你遊戲。您只需創建適當的GameRenderer(實現AbstractGameRenderer)並將其傳遞給Game對象。遊戲對象並不在乎它是不同的遊戲,不同的引擎和不同的渲染器 - 它甚至不知道。

問題是有很多解決方案來設計問題。這個建議可能不合適或不可接受,也可能正是你需要的。我試圖遵循的原則是: 1.儘量不要承諾​​你無法控制的界面(如果它們發生變化,你將不得不改變) 2.儘量防止現在會出現後來的痛苦

在我的例子中,假設如果Renderer改變,改變GameRenderer的痛苦會比改變像Game這樣的大型組件更難。但最好堅持原則(並儘量減少疼痛),而不是盲目追隨模式。