[設計模式整理筆記 八] 單例模式(Singleton)

[導讀][設計模式整理筆記 一] 基礎知識[設計模式整理筆記 二] 簡單原廠模式(Simple Factory)[設計模式整理筆記 三] 原廠模式(Factory)[設計模式整理筆記 四] 抽象原廠模式(Abstract Factory)[設計模式整理筆記 五] 建立者模式(Builder)[設計模式整理筆記 六] 原廠模式與建立者模式總結[設計模式整理筆記 七] 原型模式(ProtoType)[設計模式整理筆記 八] 單例模式(Singleton)[設計模式整理筆記

重構手法63:Extract Superclass (提煉超類)

2個類有相似特性。為這2個類建立一個超類,將相同特性移至超類。動機:重複代碼是系統中最糟糕的東西之一。如果你在不同地方做同一件事情,一旦需要修改那些動作,你就得平白做更多的修改。       重複代碼的某種形式就是:2個類以相同的方式做類似的事情,或者以不同的方式做類似的事情。對象提供了一種簡化這種情況的機制,那就是繼承。但是,在建立這些具有共通性的類之前,你往往無法發現這樣的共通性,因此常常會在具有共通性的類出現之後,再開始建立其間的繼承結構。       另一種選擇就是 Extract

重構手法52:Hide Method (隱藏函數)

有一個函數,從來沒有被其他任何類用到。將這個函數修改為private。動機:重構往往促使你修改函數的可見度。提高函數可見度的情況很容易想象:另一個類需要用到某個函數,因此你必須提高該函數的可見度。但是要指出一個函數的可見度是否過高,就稍微困難一些。理想狀態下,你可以使用工具檢查所有函數,指出可被隱藏起來的函數。即使沒有這樣的工具,你也應該時常進行這樣的檢查。      

重構手法31:Replace Type Code with Subclass (以子類取代類型碼)

 你有一個不可變的類型碼,它會影響類的行為。以子類取代這個類型碼。動機:如果你面對的類型碼不會影響宿主類的行為,可以使用Replace Type Code with Class (以類取代類型碼)來處理它們。但如果類型碼會影響宿主類的行為,那麼最後的辦法就是藉助多態來處理變化行為。       一般來說,這種情況的標誌就是像switch這樣的條件運算式。這種條件運算式可能有2種表現形式:switch語句或者if

重構手法41:Introduce Assertion (引入斷言)

某一段代碼需要對程式狀態做出某種假設。以斷言明確表現這種假設。動機:常常會有這樣一段代碼:只有當某個條件為真時,該段代碼才能正常運行。       這樣的假設通常並沒有在代碼中明確表現出來,你必須閱讀整個演算法才能看出。有時程式員會以注釋寫出這樣的假設。可以使用斷言明確標明這些假設。      

重構手法20:Change Value to Reference (將值對象改為引用對象)

 從一個類中衍生出許多彼此相等的執行個體,希望將它們替換為一個對象。將這個值對象變成引用對象。動機:在許多系統中,都可以對對象做一個有用的分類:引用對象和值對象。要在引用對象和值對象之間做選擇有時並不容易。有時候,你會從一個簡單的值對象開始,在其中儲存少量不可修改的資料。而後,你可能會希望給這個對象加入一些可修改資料,並確保對任何一個對象的修改都能影響到所引用此對象的地方。這時候你就需要將這個對象變成引用對象。做法:1、使用 Replace Constructor with Factory

代碼壞的味道10:switch 驚悚現身(Switch Statements)

  物件導向程式的一個最明顯特徵就是:少用switch或(case)語句。從本質上說,switch語句的問題在於重複。你常會發現switch語句散佈於不同地點。如果要為它添加一個新的case子句,就必須找到所有switch語句並修改它們。物件導向中的多態概念可為此帶來優雅的解決辦法。         大多數時候,一看到switch語句,就應該考慮以多態來替換它。問題是多態該出現在哪?switch語句常常根據類型碼進行選擇,你要的是“與該類型碼相關的函數或類”,所以應該使用 Extract

重構手法07:Remove Assignments to Parameters (移除對參數的賦值)

 代碼對一個 參數賦值。以一個臨時變數取代該參數的位置。     int Discount(int inputVal, int quantity, int yearTodate)        {            if (inputVal > 50)            {                inputVal -= 2;            }        } int Discount(int inputVal, int quantity, int

重構手法43:Add Parameter (添加參數)

某個函數需要從調用端得到更多資訊。為此函數添加一個對象參數,讓該對象帶進函數所需資訊。動機:Add Parameter (添加參數)是一個很常用的重構手法。使用這項重構的動機很簡單:你必須修改一個函數,而修改後的函數需要一些過去沒有的資訊,因此你需要給該函數添加一個參數。      

重構手法22:Replace Array with Object (以對象取代數組)

你有一個數組,其中的元素各自代表不同的東西。以對象替換數組,對於數組中的每個元素,以一個欄位來表示。動機:數組時一種常見的用以組織資料的結構。不過,它們應該只用於“以某種順序容納一組相似對象”。有時候你會發現,一個數組容納了多種不同對象,這會給使用者帶來麻煩,因為他們很難記住像“數組的第一個元素是人名”這樣的約定。對象就不同了,你可以運用欄位名和函數名來傳達這樣的資訊,因此你無需死記它,也無需依賴注釋。而且如果使用對象,你還可以將資訊封裝起來。並使用 Move Method

重構手法66:Form Template Method (塑造模板函數)

你有一些子類,其中相應的某些函數以相同的順序執行類似的操作,但各個操作的細節不同。將這些操作分別放進獨立的函數中,並保持它們都有相同的簽名,於是原函數也就變得相同了,然後將原函數上移至超類。動機:繼承是避免重複行為的一個強大工具。無論何時,只要你看見2個子類之中有類似的函數,就可以把它們提升到超類。但是如果這些函數並不完全相同該這麼辦?仍有必要盡量避免重複,但又必須保持這些函數之間的實質差異。      

重構手法55:Replace Error Code with Exception (以異常取代錯誤碼)

某個函數返回一個特定的代碼,用以表示某種錯誤情況。改用異常。動機:程式中發現錯誤的地方,並不一定知道如何處理錯誤。當一段子程式發現錯誤時,它需要讓它的調用者知道這個錯誤,而調用者也可能將這個錯誤繼續沿著調用鏈傳遞上去。許多程式都使用特殊輸出來表示錯誤。       可以使用更好的錯誤處理方式:異常。它清楚地將“普通程式”和“錯誤處理”分開了,這使得程式更容易理解:代碼的可理解性應該是我們追求的目標。 

重構手法64:Extract Interface (提煉介面)

若干客戶使用類介面中的同一子集,或者2個類的介面部分相同。將相同的子集提煉到一個獨立介面中。動機:類之間彼此互用的方式有若干種。“使用一個類”通常意味著用到該類的所有責任區。另一種情況是,某一組客戶只使用類責任區中的一個特定子集。再一種情況是,這個類需要與所有協助處理某些特定請求的類合作。       對於後2種情況,將真正用到的這部分責任分離出來通常很有意義,因為這樣可以使系統的用法更清晰,同時也更容易看清系統的責任劃分。如果新的類需要支援上述子集,也比較能夠看清子集內有些什麼東西。     

重構手法53:Replace Constructor with Factory Method (以工廠函數取代建構函式)

你希望在建立對象時不僅僅是做簡單的建構動作。將建構函式替換為工廠函數。動機:就是在派生子類的過程中以工廠函數取代類型碼。你可能常常需要根據類型碼建立相應的對象,現在,建立名單中還得加上子類,那些子類也是根據類型碼來建立。然而由於建構函式只能返回單一類型的對象,因此你需要將建構函式替換為工廠函數。       此外,如果建構函式的功能不能滿足你的需要,也可以使用工廠函數代替它。工廠函數也是Change Value to Reference

重構手法42:Rename Method (函數改名)

 函數的名稱未能揭示函數的用途。修改函數名稱。動機:大力提倡的一種編程風格是:將複雜的處理分解成小函數。但是,如果做得不好,這會使你費盡周折卻弄不清楚這些小函數各自的用途。要避免這種麻煩,關鍵就在於給函數起一個好名稱。函數的名稱應該準確表達它的用途。給函數命名有一個好辦法:首先考慮應該給這個函數寫上一句怎樣的注釋,然後想辦法將注釋變成函數名稱。      

重構手法21:Change Reference to Value (將引用對象改為值對象)

 你有一個引用對象,很小且不可變,而且不易管理。將它變成一個值對象。動機:要在引用對象和值對象之間做選擇,有時並不容易。做出選擇後,你常會需要一條回頭路,       如果引用對象開始變得難以使用,也許就應該將它改為值對象。引用對象必須被某種方式控制,你總是必須向其控制者請求適當的引用對象。它們可能造成記憶體地區之間錯綜複雜的關聯。在分布式和並發系統中,不可變的值對象特別有用,因為你無需考慮它們的同步問題。      

代碼壞的味道11:平行繼承體系(Parallel Inheritance Hierarchies)

  平行繼承體系其實是散彈式修改(Shotgun Surgery)的特殊情況。在這種情況下,每當你為某個類增加1個子類,必須也為另一個類相應增加1個子類。如果你發現某個繼承體系的類名首碼和另一個繼承體系的類名首碼完全相同,便是聞到了這種壞味道。         消除這種重複性的一般策略是:讓一個繼承體系的執行個體引用另一個繼承體系的執行個體。如果再接再厲運用 Move Method (搬移函數)和Move Field (搬移欄位),,就可以將引用端的繼承體系取消。

重構手法10:Move Method (搬移函數)

 你的程式中,有個函數與其所駐類之外的另一個類進行更多的交流:調用後者,或被後者調用。在該函數最常用引用的類中建立一個有著類似行為的新函數。將舊函數編程一個單純的委託函數,或是將舊函數完全移除。       動機:“搬移函數”是重構理論的支柱。如果一個類有太多行為,或如果一個類與另一個類有太多合作而形成高度耦合,就需要搬移函數。通過這種手段,可以使系統中的類更簡單,這些類最終也將更乾淨利落的實現系統交付的工作。      

重構手法54:Encapsulate Downcast (封裝向下轉型)

某個函數返回的對象,需要由函數調用者執行向下轉型(downcast)。將向下轉型動作移到函數中。動機:向下轉型也許是無法避免的,但你仍然應該儘可能少做。如果你的某個函數返回一個值,並且你知道所返回的物件類型比函數簽名所昭告的更特化,你便是在函數使用者身上強加了非必要的工作。這種情況下你不應該要求使用者承擔向下轉型的責任,應該盡量為他們提供準確的類型。      

重構手法33:Replace Subclass with Field (以欄位取代子類)

 你的各個子類的唯一差別只在“返回常量資料”的函數身上。修改這些函數,使它們返回超類中的某個(新增)唯讀,然後銷毀子類。動機:建立子類的目的,是為了增加新特性或變化其行為。有一種變化行為被稱為“常量函數”,它們會返回一個硬式編碼值。這東西有其用途:你可以讓不同的子類中的同一個訪問函數返回不同的值。你可以在超類中將訪問函式宣告為抽象函數,並在不同子類中讓它返回不同的值。      

總頁數: 61357 1 .... 6061 6062 6063 6064 6065 .... 61357 Go to: 前往

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.