2010-05-05 33 views
6

我寫的大多數程序都是相對可流程化的過程,有一個明確的開始和希望的結束。問題本身可能很複雜,但不容易傾向於集中使用對象和事件驅動的編程。通常,我只是通過大量不同批次的文本數據來產生不同的文本數據。我偶爾需要創建一個類:作爲一個例子,爲了跟蹤警告,錯誤和調試消息,我創建了一個具有一個實例(myErr)的類(Problems),我相信這是一個Singleton設計模式的示例。另一個因素是,我的同事比我更老(程序性),而且不熟悉面向對象編程,所以我不願意創造他們無法解決的問題。請儘量減少使用全局變量來描述你的工作

但我一次又一次地聽到,即使Singleton設計模式真的是反模式,應該避免,因爲全局變量不好。

小功能需要很少的參數傳遞給他們,並不需要知道配置(不變)或程序狀態(改變) - 我同意。然而,主要控制程序流程的鏈中間的函數需要大量的配置變量和一些程序狀態變量。我相信將一個或多個論點傳遞給一個函數是一個「解決方案」,但幾乎沒有吸引力。當然,我可以將變量壓縮到單個哈希/字典/關聯數組中,但這看起來像是作弊。

例如,連接到Active Directory以創建新帳戶,我需要配置變量作爲管理用戶名,密碼,目標OU,某些默認組,域等。我必須通過這些參數通過甚至不使用它們的各種功能,只是通過一個鏈最終導致實際上需要它們的功能將它們洗掉。

我至少會聲明配置變量是恆定的,以保護它們,但我最近選擇的語言(Python)沒有提供簡單的方法來做到這一點,儘管食譜確實存在作爲解決方法。

許多堆棧溢出問題已經打到了爲什麼?壞的和必要的迴避,但不要經常提到與這種準宗教限制一起生活的提示​​。你是如何解決全球變量和計劃狀態問題的,或者至少是和平的?你在哪裏做出妥協?除了圍繞函數的參數成羣之外,你有什麼技巧呢?

+0

好問題 - 您是否將類級變量(成員)分類爲全局變量? – 2010-05-05 15:27:05

回答

5

我認爲有一個單身模式或類似情況的時間和地點。要記住的關鍵是,一次又一次,許多人在使用全局/共享/靜態變量以及單例模式的「錯誤」選擇方面遇到了特定的恐懼。

就你而言,你正在專門討論配置。我認爲使用單例風格模式訪問這些配置項目並沒有什麼壞處。每個應用程序都有配置,它應該位於一個你可以調用的位置,不需要傳遞它,這比它幫助複雜。

這裏的關鍵是確保您確實需要信息只存在一次,配置是迄今爲止我發現使用這種類型的模式的最佳理由之一。

3

全局數據是不變的,或定義良好的全過程對象(例如日誌記錄),通常可以用作全局數據。配置數據,特別是如果它駐留在本地文件中,將屬於同一類別(整個過程/應用程序只有一個文件,與日誌類似)。

一般來說,如果你發現你必須傳遞額外的參數才能將它們傳遞給另一個函數,那麼你應該把這個函數調高,然後再調用另一個函數。說明這一點的另一個更實際的方法是測試驅動的開發,因爲它強制你傳遞依賴關係。

另一種考慮它的方式是:如果該函數不能輕易知道調用子函數的所有細節,則將該子函數拉起來,並強制一個更高的,更知道的圖層來獲取所需的信息。我發現這種技術對代碼質量具有高度的傳導性,因爲它構建了分隔的部分,而不是單片的動物。

在您對於活動目錄例如,代替繞參數傳遞到ad_connect,繞過處理該必要的邏輯的對象,則具有介導該對象和功能之間的相互作用的功能使用它

def create_user(name, ad_user, ad_pass, ad_ou, ...): 
    conn = ad_connect(ad_user, ad_pass, ...) 
    conn.CreateRecord(ad_user) 

def create_user_mediator(name, ad_controller): 
    ad_controller.CreateRecord("cn=%s" % name) 

這只是一種做法,當然也有其優點和缺點。它僅僅是一個例子,說明如何避免使用全局變量。