摘要:并隱藏對象內與用戶無關的數據結構。有一種變化行為被稱為常量函數,它們會返回一個硬編碼的值。盡管常量函數有其用途,但若與子類中只有常量函數,實在沒有足夠的存在價值。你可以在超類中設計一個與常量函數返回值相應的字段,從而完全除去這樣的子類。
前言
前面已經對方法,類列舉了重構方法。現在該輪到字段了
注:值對象:不可變對象
引用對象:可變對象
你直接訪問一個字段,但與字段之間的耦合關系逐漸變得笨拙。
方法為這個字段建立取值/設值函數,并且只以這些函數來訪問字段。(getter和setter方法)
動機子類可以通過覆寫一個函數而改變獲取數據的途徑;它還支持更靈活的數據管理方式,例如延遲初始化。
Replace Data Value with Object 對象取代數據值 問題你有一個數據項,需要與其他數據和行為一起使用才有意義。
方法將數據項變成對象。
動機開發初期,一個用戶的信息只有名字,就用一個字符串來存,如果后期要添加用戶的信息。比如性別,年齡。會很難擴展
Change value to Reference 將值對象改為引用對象 問題希望將多個相等對象,替換為一個對象。
方法使用單例模式。保證該對象只有一個
動機當你希望在值對象中加一些可修改的字段時。保證所有對象都能被修改
Change Reference to Value 將引用對象改為值對象 問題你有一個引用對象,很小且不可變,而且不易管理。將它變成一個值對象。
注: 要在引用對象和值對象之間做選擇,有時并不容易。做出選擇后,你常會需要一條回頭路,
引用對象改為值對象
動機當引用對象變得難以使用(比如因為同步問題)。就變回值對象
Replace Array with Object 以對象取代數組 問題你有一個數組,其中的元素各自代表不同的東西。以對象替換數組,對于數組中的每個元素,以一個字段來表示。方法
將每個元素用對象封裝
動機注:我覺得java程序員應該很少這么用。一般都不會把不同的元素存到數組中。
Duplicate Observed data 復制被監視數據 問題你有一些領域數據置身于GUI控件中,而領域函數需要訪問這些數據。
方法將該數據復制到一個領域對象中。建立一個觀察者模式,用以同步領域對象和GUI對象內的重復數據。
動機業務邏輯和用戶界面不能寫在一起,因為這樣用戶類就會有兩種職責。用戶類就變得很復雜。
Change Unidirection Association to Bidirectional 將單向關聯改為雙向關聯(特定情況使用) 問題兩個類都需要使用對方特性,但其間只有一條單向連接。
方法添加一個反向指針,并使修改函數能夠同時更新2條連接。
動機兩個類都需要使用對方特性,本重構運用反向指針實現雙向關聯,其他技術需要其他重構手法。
Change Bidirectional Association to Unidirection將雙向關聯改為單向關聯(特殊情況使用) 問題兩個類之間有雙向關聯,但其中一個類如今不再需要另一個類的特性。
方法去除不必要的關聯。
動機雙向關聯很有用,但你必須為它付出代價,那就是維護雙向連接、確保對象被正確創建和刪除而增加的復雜度。而且,由于很多程序員并不習慣使用雙向關聯,它往往成為錯誤之源。
大量的雙向連接也很容易造成“僵尸對象”:某個對象本來應該死亡了,卻仍然保留在系統中,因為對它的引用沒有完全清除。
此外,雙向關聯也迫使2個類之間有了依賴:對其中任一個類的任何修改,都可能引發另一個類的變化。如果這2個類位于不同的程序集,這種依賴就是程序集之間的相依。過多的跨程序集依賴會造就緊耦合的系統,使得任何一點小小改動就可能造成許多無法預知的后果。
只有在真正需要雙向關聯的時候,才該使用它。如果發現雙向關聯不再有存在價值,就應該去掉不必要的一條關聯。
你有一個字面數值,帶有特別含義。
方法創建一個常量,根據其意義為它命名,并將上述的字面數值替換為這個常量。
動機在計算科學中,魔法數是歷史悠久的不良現象之一。所謂魔法數是指擁有特殊意義,卻又不能明確表現出這種意義的數字。如果你需要在不同的地點引用同一個邏輯數,魔法數會讓你煩惱不已,因為一旦這些數發生變化,你就必須在程序中找到所有魔法數,并將它們全部修改一遍。就算你不需要修改,要準確指出每個魔法數的用途,也會讓你頗費腦筋。
Encapsulate Field 封裝字段 問題你的類中存在一個public字段。
方法將它聲明為private,并且提供相應的訪問函數。
面向對象的首要原則之一就是封裝,或者稱為“數據隱藏”。按此原則,你絕不應該將數據聲明為public,否則其他對象就有可能訪問甚至修改這項數據,而擁有該數據的對象卻毫無察覺。于是,數據和行為就被分開了。
Encapsulate Collection 封裝集合 問題有一個函數返回一個集合。
方法讓這個函數返回該集合的一個只讀副本,并在這個類中提供添加/移除集合元素的函數。
動機我們常常會在一個類中使用集合來保存一組實例。這樣的類通常也會提供針對該集合的取值/設值函數。
但是,集合的處理方式應該和其他種類的數據略有不同。取值函數不該返回集合自身,因為這會讓用戶得以修改集合內容而集合擁有者卻一無所悉。也會對用戶暴露過多對象內部數據結構信息。如果一個取值函數確實需要返回多個值,它應該避免用戶直接操作對象內所保存的集合。并隱藏對象內與用戶無關的數據結構。
另外,不應該為這整個集合提供設值函數,但應該提供用以為集合添加/移除元素的函數。這樣,集合擁有者就可以控制集合元素的添加和移除。
這條我還真沒懂
Replace Type Code with Class 以類來取代類型碼 問題類之中有一個數值類型碼,但它并不影響類的行為(不會因為他的改變而調用不同的邏輯)
方法以一個新的類替換該數值類型碼。
動機任何接受類型碼作為參數的函數,所期望的實際上是一個數值,無法強制使用符號名。這會大大降低代碼的可讀性,從而成為bug之源。
Replace Type Code with Subclasses 以子類來取代類型碼 問題你有一個不可變的類型碼,它會影響類的行為。
方法以子類取代這個類型碼。
動機一般來說,這種情況的標志就是像switch這樣的條件表達式。這種條件表達式可能有2種表現形式:switch語句或者if –then-else結構。不論哪種形式,它們都是檢查類型碼值,并根據不同的值執行不同的動作。這種情況下,你應該以 Replace Conditional with Polymorphism (以多態取代條件表達式)進行重構。但為了那個順利進行那樣的重構,首先應該將類型碼替換為可擁有多態行為的繼承體系。這樣一個繼承體系應該以類型碼宿主類為基類,并針對每一種類型碼建立一個子類。
Replace Type Code with State/Strategy 以狀態/策略取代類型碼 問題你有一個類型碼,它會影響類的行為,但你無法提供繼承手法消除它。
方法以狀態對象取代類型碼。
本項重構和Replace Type Code with Subclass (以子類取代類型碼)類似,但如果“類型碼在對象生命期中發生變化”或“其他原因使得宿主類不能被繼承”,你也可以使用本重構。本重構使用State模式和Strategy模式。
State模式和Strategy模式非常相似,因此無論你選擇其中哪一個,重構過程都是一樣的。“選擇哪個模式”并非問題的關鍵所在,你只需要選擇更合適特定情境的模式就行了。如果你打算在完成本重構后再以Replace Conditional with Polymorphism (以多態取代條件表達式)簡化一個算法,那么選擇Strategy模式較合適;如果你打算搬移狀態相關的數據,而且你把新建對象視為一種變遷狀態,就應該選擇State模式。Replace Subclass with Fieldls 以字段取代子類 問題
你的各個子類的唯一差別只在“返回常量數據”的函數身上。
方法修改這些函數,使它們返回超類中的某個(新增)只讀,然后銷毀子類。
動機建立子類的目的,是為了增加新特性或變化其行為。有一種變化行為被稱為“常量函數”,它們會返回一個硬編碼的值。這東西有其用途:你可以讓不同的子類中的同一個訪問函數返回不同的值。你可以在超類中將訪問函數聲明為抽象函數,并在不同子類中讓它返回不同的值。
盡管常量函數有其用途,但若與子類中只有常量函數,實在沒有足夠的存在價值。你可以在超類中設計一個與常量函數返回值相應的字段,從而完全除去這樣的子類。如此一來就可以避免因繼承而帶來的額外復雜性。
注:這好像和以子類取代狀態碼有一定沖突
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69736.html
摘要:函數重構重構有很大一部分都是在重構函數。這條也要具體情況具體使用函數對象取代函數函數對象代替函數大函數變成類你有一個大型函數,其中對局部變量的使用使你無法采用提煉函數。將這個大型函數放進一個單獨對象中,如此一來局部變量就成了對象內的字段。 函數重構 重構有很大一部分都是在重構函數。尤其是長函數。這是問題的根源。以下是重構方法 Extract Method 提煉函數 提煉函數:(由復雜的...
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:重構在不改變代碼的外在的行為的前提下對代碼進行修改最大限度的減少錯誤的幾率本質上,就是代碼寫好之后修改它的設計。重構可以深入理解代碼并且幫助找到。同時重構可以減少引入的機率,方便日后擴展。平行繼承目的在于消除類之間的重復代碼。 重構 (refactoring) 在不改變代碼的外在的行為的前提下 對代碼進行修改最大限度的減少錯誤的幾率 本質上, 就是代碼寫好之后 修改它的設計。 1,書中...
摘要:為何重構重構有四大好處重構改進軟件設計如果沒有重構,程序的設計會逐漸腐敗變質。經常性的重構可以幫助維持自己該有的形態。你有一個大型函數,其中對局部變量的使用使你無法采用。將這個函數放進一個單獨對象中,如此一來局部變量就成了對象內的字段。 哪有什么天生如此,只是我們天天堅持。 -Zhiyuan 國慶抽出時間來閱讀這本從師傅那里借來的書,聽說還是程序員的必讀書籍。 關于書的高清下載連...
閱讀 2931·2023-04-26 02:22
閱讀 2290·2021-11-17 09:33
閱讀 3134·2021-09-22 16:06
閱讀 1072·2021-09-22 15:54
閱讀 3536·2019-08-29 13:44
閱讀 1914·2019-08-29 12:37
閱讀 1321·2019-08-26 14:04
閱讀 1914·2019-08-26 11:57