簡體   English   中英

單例或將指針傳遞給管理器中的靜態引用

[英]Singleton or passing pointers to static reference in manager

我有一個連接管理器,該連接管理器目前具有對該類的靜態引用,該引用保留在該類的私有部分的連接管理器中。 指向此類的指針將傳遞給所有連接,並且它們可以將其用於實用程序。

現在,該類指針對孩子們並不立即有用,但是對孩子自己的孩子很有用,因此所有發生的就是傳遞它。

現在,我想知道既然該實用工具類只有1個實例,我應該煩惱所有這些指針傳遞,還是將類做成單例,並且每個需要它的類都可以簡單地使用改為使用靜態getInstance()方法。 這意味着不需要關心它的類就不需要知道它。

連接的類型很多(超過30種),它們都不關心實用程序類。 但是,它們將使用關心實用程序類的類(目前只有2個)。

我不確定每種連接類型是否都應該負擔一些自己不關心的東西,僅僅是為了(可能)使用幾個類。

單例和靜態場通常被認為是邪惡的。 為什么仍然是靜態的? 它可能會發生,因此有一天您將需要每個連接管理器都有自己的引用。

我能想到的最好的主意是首先使參考成為非靜態的。 然后,忘記使用單例。 從這一點開始,您應該開始考慮如何以最優雅的方式實現這一目標。

我不知道您的類的性質,但對我來說合理的是,每個連接都應具有指向管理該類的連接管理器的引用(或指針)。 以防萬一。

然后,連接管理器可能應該為任何想要訪問該實用工具類的人提供一個吸氣劑。 連接本身應該將引用傳遞給連接管理器或實用程序類,這取決於更有意義的內容。

如果對連接管理器的引用(應該存在),則將對連接管理器的引用傳遞給連接的公共祖先的構造函數。 這樣,您不再有30多個類引用它們真正不需要的東西,而只是它們所基於的一個抽象類。

而且,如果您確實想做類似單例的事情,那么最好有一種帶有返回引用的參數的靜態方法,而不是僅使用靜態方法:

static UtilityClass *getInstance(int id);
// not static UtilityClass *getInstance();

即使您現在不使用id參數,以后在需要多個實例時也可能會非常有用。 您可能會有某種表或哈希映射,將ID映射到實例。 您甚至可以添加一種方法來創建或替換具有特定ID的實例,這對於單元測試可能非常有用。 請注意,此方法至少仍然具有單例模式的以下缺點:

  • 它容易出現各種線程問題。
  • 它仍然隱藏了類的依賴關系:也就是說,僅通過查看其API就無法說出一個類使用了什么。

不看代碼就很難給出更多建議。

如果我對您的理解正確,則在頂層有一個連接管理器。 它包含一個靜態類,稍后將使用。

下一層是一個類的許多實例,這些實例的存在是為上述管理器管理的每個連接提供服務。

其中的每個可能依次使用一些實用程序類實例,這些實例希望從連接管理器訪問信息(在本例中,您將其包裝為靜態對象)。

問題是,第3層以下應該如何最好地訪問Connection Manager包含的信息。

我稱它們為:Manager(包含“靜態類”)-> Connection-> Utility

我的建議是讓連接引用擁有它們的管理器。 沒有它們,它們就不能存在或不應該存在,並且由它管理。 反過來,他們需要構造需要連接管理器(其中包含的靜態類)的特定信息的對象。

因此,當Connection構造Utility類時,Utility類將只需要它們需要操作的一些信息(在這種情況下,該類的參考參數在Manager中是靜態的)。 他們也應參考這一點。 Connection具有Manager類參考,並且能夠為Utility的構造函數提供它需要操作的一些信息。

我建議使用這種方法的原因是:

  • 連接/實用程序類不關心管理器是否為單例(如果需要多個管理器,則在以后打開可能性)
  • 實用程序不關心靜態類是否為靜態。 他們只需要引用他們需要的特定類。
  • 管理器決定如何分配它或其包含的數據。

最后:

  • 唯一有理由了解其他兩個主要類的類是Connections類。 可能知道哪個經理在管理它似乎很有道理(因此也有一些界面信息)。 它還知道它將需要哪些Utility類,以及在構造參數和其他接口要求方面它們將需要什么。

要進行此設置,可能需要對include和class進行一些調整,而類可能必須彼此公開接口,但是無論如何,這僅僅是標准費用。

我的2c。

單例與靜態

單例用法的一個很好的例子:您希望一個類只運行一個實例,例如紋理管理器,着色器管理器,連接池管理器等(請參見出現的模式:)

作為示例,讓我們使用一個連接池管理器:我們想要創建一個連接池,該連接池由代碼中需要連接的任何其他對象管理和重用,因此我們創建一個ConnectionPoolManager單例類,例如32連接。 現在,這允許每個需要連接的對象使用ConnectionPoolManager單例中的方法(例如getFreeConnection來檢索有效的連接,然后可以根據需要使用該連接。 這使ConnectionPoolManager成為代碼中唯一與開始停止和管理代碼連接有關的任何部分。

單例和靜態類都可以以線程安全的方式實現,但是單例具有優勢,因為它們可以實現接口(公共),派生自其他類(較不常見),並且可以在內部傳遞單例。與其他任何對象(至少是對其的引用)完全相同的方式,其中靜態類只能實現靜態方法。

關於您的特定情況,您指出從30多個類中只有一對需要實用程序類:對singletonstatic class的依賴完全取決於您的設計和風格。 如果您希望采用一種通用的方式來做,並在以后有改變的潛力,那么我將使用單例。 如果您知道靜態類就足夠了,以后就不需要重新設計了,那就去做吧,或者,如果您特別喜歡一個或另一個,請使用該類。 可能還存在一些硬件/軟件限制和詳細信息,它們相互推薦,但是目前看來並非如此。

讓我知道您是否需要更多信息,或者是否有任何您認為可能會影響您選擇的細節,我可以為您提供每種方法的優缺點信息,以適合您的需求:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM