重構 改善既有代碼的設計


 最近接手一個項目,源代碼的架構和許多設計都有壞的味道。 想要重構,但是自己並沒有足夠的底氣.

一、重構的糾結:

(1)現有代碼可用,你重構后是否會比現在更有效率;

(2)項目進度比較緊,你是否要抽出時間做這種沒有KPI的工作;

(3)你重構后,別人需要重新閱讀你的源代碼,給同事帶來了重新學習代碼的工作量;

(4)項目是否能夠持續,如果沒有需求,不用了,你還重構什么?

(5)你是否要在這個公司待很久,等重構完后,你可能都不在了。

 

 二、如果不重構,確實會給開發帶來很大困難:

原代碼就像是一個打滿了補丁的棉襖,它可以保暖,但是很難定位到哪里漏風,即使定位到了,不過是新打些補丁,但是縫縫補補的工作可能沒有盡頭。

(1)修改很耗精力;

(2)BUG花樣迭出

(3)擴展性差,持續開發跟進需求很難;

(4)應變能力差,牽一發動全身。

 

重構或不重構,這是個問題,直到看了《重構 改善既有代碼的設計》,給了我很大啟發。粗略看了一遍,道理明白了一些,我之前的想法應該叫做重寫而不是重構。

重構是逐步改善的過程,是重寫與打補丁的中間選項。

當然看完書之后,我還是選擇了重寫,因為項目還不是很大,重寫做起來工作量更小一些。

重構的核心還是使代碼盡量遵循設計模式的六大原則:

(1)單一職責原則
(2)里氏替換原則
(3)依賴倒置原則
(4)接口隔離原則
(5)迪米特法則
(6)開閉原則

重構中用到的方法,是寫代碼過程中很好的參照。方法都寫在2-13章的目錄里了,意思比較明顯,閑來的時候看看,也大有裨益。

第2章 重構原則
2.1 何謂重構53
2.2 為何重構55
2.3 何時重構57
2.4 怎么對經理說60
2.5 重構的難題62
2.6 重構與設計66
2.7 重構與性能69
2.8 重構起源何處71
第3章 代碼的壞味道
3.1 DuplicatedCode(重復代碼)76
3.2 LongMethod(過長函數)76
3.3 LargeClass(過大的類)78
3.4 LongParameterList(過長參數列)78
3.5 DivergentChange(發散式變化)79
3.6 ShotgunSurgery(霰彈式修改)80
3.7 FeatureEnvy(依戀情結)80
3.8 DataClumps(數據泥團)81
3.9 PrimitiveObsession(基本類型偏執)81
3.10 SwitchStatements(switch驚悚現身)82
3.11 ParallelInheritanceHierarchies(平行繼承體系)83
3.12 LazyClass(冗贅類)83
3.13 SpeculativeGenerality(誇誇其談未來性)83
3.14 TemporaryField(令人迷惑的暫時字段)84
3.15 MessageChains(過度耦合的消息鏈)84
3.16 MiddleMan(中間人)85
3.17 InappropriateIntimacy(狎昵關系)85
3.18 AlternativeClasseswithDifferentInterfaces(異曲同工的類)85
3.19 IncompleteLibraryClass(不完美的庫類)86
3.20 DataClass(純稚的數據類)86
3.21 RefusedBequest(被拒絕的遺贈)87
3.22 Comments(過多的注釋)87
第4章 構築測試體系
4.1 自測試代碼的價值89
4.2 JUnit測試框架91
4.3 添加更多測試97
第5章 重構列表
5.1 重構的記錄格式103
5.2 尋找引用點105
5.3 這些重構手法有多成熟106
第6章 重新組織函數
6.1 ExtractMethod(提煉函數)110
6.2 InlineMethod(內聯函數)117
6.3 InlineTemp(內聯臨時變量)119
6.4 ReplaceTempwithQuery(以查詢取代臨時變量)120
6.5 IntroduceExplainingVariable(引入解釋性變量)124
6.6 SplitTemporaryVariable(分解臨時變量)128
6.7 RemoveAssignmentstoParameters(移除對參數的賦值)131
6.8 ReplaceMethodwithMethodObject(以函數對象取代函數)135
6.9 SubstituteAlgorithm(替換算法)139
第7章 在對象之間搬移特性
7.1 MoveMethod(搬移函數)142
7.2 MoveField(搬移字段)146
7.3 ExtractClass(提煉類)149
7.4 InlineClass(將類內聯化)154
7.5 HideDelegate(隱藏“委托關系”)157
7.6 RemoveMiddleMan(移除中間人)160
7.7 IntroduceForeignMethod(引入外加函數)162
7.8 IntroduceLocalExtension(引入本地擴展)164
第8章 重新組織數據
8.1 SelfEncapsulateField(自封裝字段)171
8.2 ReplaceDataValuewithObject(以對象取代數據值)175
8.3 ChangeValuetoReference(將值對象改為引用對象)179
8.4 ChangeReferencetoValue(將引用對象改為值對象)183
8.5 ReplaceArraywithObject(以對象取代數組)186
8.6 DuplicateObservedData(復制“被監視數據”)189
8.7 ChangeUnidirectionalAssociationtoBidirectional(將單向關聯改為雙向關聯)197
8.8 ChangeBidirectionalAssociationtoUnidirectional(將雙向關聯改為單向關聯)200
8.9 ReplaceMagicNumberwithSymbolicConstant(以字面常量取代魔法數)204
8.10 EncapsulateField(封裝字段)206
8.11 EncapsulateCollection(封裝集合)208
8.12 ReplaceRecordwithDataClass(以數據類取代記錄)217
8.13 ReplaceTypeCodewithClass(以類取代類型碼)218
8.14 ReplaceTypeCodewithSubclasses(以子類取代類型碼)223
8.15 ReplaceTypeCodewithState/Strategy(以State/Strategy取代類型碼)227
8.16 ReplaceSubclasswithFields(以字段取代子類)232
第9章 簡化條件表達式
9.1 DecomposeConditional(分解條件表達式)238
9.2 ConsolidateConditionalExpression(合並條件表達式)240
9.3 ConsolidateDuplicateConditionalFragments(合並重復的條件片段)243
9.4 RemoveControlFlag(移除控制標記)245
9.5 ReplaceNestedConditionalwithGuardClauses(以衛語句取代嵌套條件表達式)250
9.6 ReplaceConditionalwithPolymorphism(以多態取代條件表達式)255
9.7 IntroduceNullObject(引入Null對象)260
9.8 IntroduceAssertion(引入斷言)267
第10章 簡化函數調用
10.1 RenameMethod(函數改名)273
10.2 AddParameter(添加參數)275
10.3 RemoveParameter(移除參數)277
10.4 SeparateQueryfromModifier(將查詢函數和修改函數分離)279
10.5 ParameterizeMethod(令函數攜帶參數)283
10.6 ReplaceParameterwithExplicitMethods(以明確函數取代參數)285
10.7 PreserveWholeObject(保持對象完整)288
10.8 ReplaceParameterwithMethods(以函數取代參數)292
10.9 IntroduceParameterObject(引入參數對象)295
10.10 RemoveSettingMethod(移除設值函數)300
10.11 HideMethod(隱藏函數)303
10.12 ReplaceConstructorwithFactoryMethod(以工廠函數取代構造函數)304
10.13 EncapsulateDowncast(封裝向下轉型)308
10.14 ReplaceErrorCodewithException(以異常取代錯誤碼)310
10.15 ReplaceExceptionwithTest(以測試取代異常)315
第11章 處理概括關系
11.1 PullUpField(字段上移)320
11.2 PullUpMethod(函數上移)322
11.3 PullUpConstructorBody(構造函數本體上移)325
11.4 PushDownMethod(函數下移)328
11.5 PushDownField(字段下移)329
11.6 ExtractSubclass(提煉子類)330
11.7 Extract Superclass (提煉超類) 336
11.8 Extract Interface (提煉接口) 341
11.9 Collapse Hierarchy (折疊繼承體系) 344
11.10 FormTemplateMethod(塑造模板函數) 345
11.11 Replace Inheritance with Delegation(以委托取代繼承) 352
11.12 Replace Delegation with Inheritance (以繼承取代委托) 355
第12章 大型重構
12.1 Tease Apart Inheritance (梳理並分解繼承體系) 362
12.2 Convert Procedural Design to Objects (將過程化設計轉化為對象設計) 368
12.3 Separate Domain from Presentation (將領域和表述/顯示分離) 370
12.4 Extract Hierarchy (提煉繼承體系) 375

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM