




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第第1章章重構(gòu)與代碼味道重構(gòu)與代碼味道劉劉 偉偉 (Sunny)weiliu_內(nèi)容w 重構(gòu)w 代碼味道w 代碼味道識別工具重構(gòu) 軟件開發(fā)方法學(xué)的泰山北斗,是最早研究軟件開發(fā)模式和重構(gòu)的人之一,軟件開發(fā)方法學(xué)的泰山北斗,是最早研究軟件開發(fā)模式和重構(gòu)的人之一,是是敏捷開發(fā)的開創(chuàng)者之一敏捷開發(fā)的開創(chuàng)者之一,更是,更是極限編程極限編程(XP)和測試驅(qū)動開發(fā)和測試驅(qū)動開發(fā)(TDD)的的創(chuàng)始人創(chuàng)始人,同時還是,同時還是JUnit的作者,對當(dāng)今世界的軟件開發(fā)影響深遠(yuǎn)。的作者,對當(dāng)今世界的軟件開發(fā)影響深遠(yuǎn)。重構(gòu)國際著名面向?qū)ο髮<遥艚蓍_發(fā)方法的創(chuàng)始人之一,是國際著名面向?qū)ο髮<?,敏捷開發(fā)方法的創(chuàng)始人之一,是
2、面向?qū)ο蠓治雒嫦驅(qū)ο蠓治鲈O(shè)計、設(shè)計、UML、模式、軟件開發(fā)方法學(xué)、模式、軟件開發(fā)方法學(xué)、XP、重構(gòu)、重構(gòu)等領(lǐng)域的世界頂級專家,等領(lǐng)域的世界頂級專家,現(xiàn)為現(xiàn)為Thought Works公司的首席科學(xué)家。主要著作包括公司的首席科學(xué)家。主要著作包括分析模式分析模式、企業(yè)應(yīng)用架構(gòu)模式企業(yè)應(yīng)用架構(gòu)模式、UML精粹精粹和和重構(gòu)重構(gòu)等。等。重構(gòu)w 何謂重構(gòu)(Fowlers Definition)重構(gòu)(名詞):重構(gòu)(名詞):對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本。低其修改成
3、本。Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.重構(gòu)w 何謂重構(gòu)(Fowlers Definition)重構(gòu)(動詞):重構(gòu)(動詞):使用一系列重構(gòu)手法,在不改變軟件可使用一系列重構(gòu)手法,在不改變軟件可觀察行為的前提下,調(diào)整其結(jié)構(gòu)。觀察行為的前提下,調(diào)整其結(jié)構(gòu)。Refactor (verb): to restr
4、ucture software by applying a series of refactorings without changing its observable behavior.重構(gòu)w 何謂重構(gòu)(Fowlers Definition)重構(gòu)w 何謂重構(gòu)重構(gòu)重構(gòu)是是在不改變軟件現(xiàn)有功能的基礎(chǔ)上,通過調(diào)整程序在不改變軟件現(xiàn)有功能的基礎(chǔ)上,通過調(diào)整程序代碼改善軟件的質(zhì)量、性能,使程序的設(shè)計和架構(gòu)更趨代碼改善軟件的質(zhì)量、性能,使程序的設(shè)計和架構(gòu)更趨合理,進(jìn)而提高軟件的擴展性和維護性合理,進(jìn)而提高軟件的擴展性和維護性。 重構(gòu)w 重構(gòu)小實例(漫畫)重構(gòu)w 重構(gòu)小實例(漫畫)重構(gòu)w 為何重構(gòu)重構(gòu)改進(jìn)
5、軟件設(shè)計重構(gòu)改進(jìn)軟件設(shè)計(Refactoring Improves the Design of Software)重構(gòu)使軟件更容易理解重構(gòu)使軟件更容易理解 (Refactoring Makes Software Easier to Understand)重構(gòu)幫助找到缺陷重構(gòu)幫助找到缺陷 (Refactoring Helps You Find Bugs)重構(gòu)提高編程速度重構(gòu)提高編程速度 (Refactoring Helps You Program Faster)重構(gòu)w 何時重構(gòu)添加功能時重構(gòu)添加功能時重構(gòu) (Refactor When You Add Function)修補錯誤時重構(gòu)修補錯誤時重
6、構(gòu) (Refactor When You Need to Fix a Bug)復(fù)審代碼時重構(gòu)復(fù)審代碼時重構(gòu)(Refactor As You Do a Code Review)Three strikes and you refactor.代碼味道w 代碼味道代碼味道:代碼壞味道,代碼味道:代碼壞味道,Bad Smells in Code在在重構(gòu):改善既有代碼的設(shè)計重構(gòu):改善既有代碼的設(shè)計一書一書中,中,Kent Beck和和Martin Fowler一共一共定義了定義了22種種常用的代碼味道常用的代碼味道代碼味道是指程序中存在的一些代碼味道是指程序中存在的一些不良的不良的編程或設(shè)計方案編程或設(shè)計
7、方案代 碼 味 道 可 以 作 為代 碼 味 道 可 以 作 為 重 構(gòu) 的 指 示 劑重 構(gòu) 的 指 示 劑 (indicator)代碼味道w 代碼味道代碼味道w 代碼味道分類1. 類內(nèi)味道類內(nèi)味道1.1 Measured Smells(可度量的味道)(可度量的味道)1.2 Unneccessary Complexity(不必要的復(fù)雜性)(不必要的復(fù)雜性)1.3 Duplication(重復(fù))(重復(fù))1.4 Conditional Logic(條件邏輯)(條件邏輯)代碼味道w 代碼味道分類2. 類間味道類間味道2.1 Data(數(shù)據(jù))(數(shù)據(jù))2.2 Inheritance(繼承)(繼承)2.
8、3 Responsibility(職責(zé))(職責(zé))2.4 Accommodating Change(協(xié)調(diào)變化)(協(xié)調(diào)變化)2.5 Library Classes(庫類)(庫類)代碼味道w 1. 類內(nèi)味道1.1 可度量的味道可度量的味道1.1.1 Long Method(過長函數(shù))(過長函數(shù))1.1.2 Large Class(過大類)(過大類)1.1.3 Long Parameter List(過長參數(shù)列)(過長參數(shù)列)1.1.4 Comments(過多的注釋)(過多的注釋)1.2 不必要的復(fù)雜性不必要的復(fù)雜性1.2.1 Speculative Generality(夸夸其談的未來(夸夸其談的未
9、來性)性)代碼味道w 1. 類內(nèi)味道1.3 重復(fù)重復(fù)1.3.1 Duplicated Code(重復(fù)代碼)(重復(fù)代碼)1.3.2 Alternative Classes with Different Interfaces(異曲同工的類)(異曲同工的類)1.4 條件邏輯條件邏輯1.4.1 Switch Statements(Switch驚悚現(xiàn)身)驚悚現(xiàn)身)代碼味道w 2. 類間味道2.1 數(shù)據(jù)數(shù)據(jù)2.1.1 Primitive Obsession(基本類型偏執(zhí))(基本類型偏執(zhí))2.1.2 Data Class(純稚的數(shù)據(jù)類)(純稚的數(shù)據(jù)類)2.1.3 Data Clumps(數(shù)據(jù)泥團)(數(shù)據(jù)泥團
10、)2.1.4 Temporary Field(令人迷惑的暫時值域)(令人迷惑的暫時值域)代碼味道w 2. 類間味道2.2 繼承繼承2.2.1 Refused Bequest(被拒絕的遺贈)(被拒絕的遺贈)2.2.2 Inappropriate Intimacy(狎昵關(guān)系)(狎昵關(guān)系)2.2.3 Lazy Class(冗贅類)(冗贅類)2.3 職責(zé)職責(zé)2.3.1 Feature Envy(依戀情節(jié))(依戀情節(jié))2.3.2 Message Chains(過度耦合的消息鏈)(過度耦合的消息鏈)2.3.3 Middle Man(中間轉(zhuǎn)手人)(中間轉(zhuǎn)手人)代碼味道w 2. 類間味道2.4 協(xié)調(diào)變化協(xié)調(diào)變
11、化2.4.1 Divergent Change(發(fā)散式變化)(發(fā)散式變化)2.4.2 Shotgun Surgery(霰彈式修改)(霰彈式修改)2.4.3 Parallel Inheritance Hierarchies(平行繼(平行繼承體系)承體系)2.5 庫類庫類2.5.1 Incomplete Library Class(不完善的程序(不完善的程序庫類)庫類)代碼味道代碼味道w 1.1.1 過長函數(shù)(Long Method)代碼味道w 1.1.1 過長函數(shù)(Long Method)代碼味道w 1.1.1 過長函數(shù)(Long Method)代碼味道w 1.1.1 過長函數(shù)(Long Met
12、hod) 描述描述 A method is too long.(方法太長。)(方法太長。) 重構(gòu)手段重構(gòu)手段 把函數(shù)變?。喊押瘮?shù)變小:Extract Method(提煉函數(shù))(提煉函數(shù)) 函數(shù)內(nèi)有大量的參數(shù)和臨時變量:函數(shù)內(nèi)有大量的參數(shù)和臨時變量:Replace Temp with Query(以查(以查詢?nèi)〈R時變量)詢?nèi)〈R時變量) 參數(shù)太多:參數(shù)太多:Introduce Parameter Object(引入?yún)?shù)對象)、(引入?yún)?shù)對象)、Preserve Whole Object(保持對象完整)(保持對象完整) 太多臨時變量和注釋:太多臨時變量和注釋:Replace Method wit
13、h Method Object(以函(以函數(shù)對象取代函數(shù))數(shù)對象取代函數(shù)) 條件表達(dá)式和循環(huán):條件表達(dá)式和循環(huán):Decompose Conditional(分解條件表達(dá)式)(分解條件表達(dá)式)代碼味道w 1.1.1 過長函數(shù)(Long Method)代碼味道w 1.1.2 過大類(Large Class) 描述描述 A class is trying to do too much, it often shows up as too many instance variables.(一個類試圖做太多的事情,通常(一個類試圖做太多的事情,通常會出現(xiàn)太多的實例變量。)會出現(xiàn)太多的實例變量。) 重構(gòu)手段
14、重構(gòu)手段 太多實例變量或太多代碼:太多實例變量或太多代碼:Extract Class(提煉類)、(提煉類)、Extract Subclass(提煉子類)(提煉子類) 確定客戶端如何使用:確定客戶端如何使用:Extract Interface(提煉接口)(提煉接口) 把數(shù)據(jù)和行為移到一個獨立的領(lǐng)域?qū)ο?,但需要保留一些重?fù)把數(shù)據(jù)和行為移到一個獨立的領(lǐng)域?qū)ο?,但需要保留一些重?fù)數(shù)據(jù):數(shù)據(jù):Duplicate Observed Data(復(fù)制(復(fù)制“被監(jiān)視數(shù)據(jù)被監(jiān)視數(shù)據(jù)”)代碼味道w 1.1.2 過大類(Large Class) 實例實例public class JTable extends JCom
15、ponent implements Accessible, CellEditorListener, ListSelectionListener, Scrollable, TableColumnModelListener, TableModelListener/ Constantspublic static final int AUTO_RESIZE_ALL_COLUMNSpublic static final int AUTO_RESIZE_LAST_COLUMNpublic static final int AUTO_RESIZE_NEXT_COLUMNpublic static final
16、 int AUTO_RESIZE_OFFpublic static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS/ Constructorspublic JTable()public JTable(TableModel, TableColumnModel)public JTable(TableModel, TableColumnModel, ListSelectionModel)public JTable(int, int)public JTable(Object, Object)public JTable(java.util.Vector, java.ut
17、il.Vector)/ Methodspublic void addColumn(TableColumn column)public void addColumnSelectionInterval(int start, int finish)public void addNotify()public void addRowSelectionInterval(int start, int finish)public void clearSelection()public void columnAdded(TableColumnModelEvent event)public void column
18、AtPoint(Point p)public void columnMarginChanged(ChangeEvent event)public void columnMoved(TableColumnModelEvent event)public void columnRemoved(TableColumnModelEvent event)public void columnSelectionChanged(ListSelectionEvent event)public void convertColumnIndexToModel(int viewColumn)public void con
19、vertColumnIndexToView(int modelColumn)public void createDefaultColumnsFromModel()public boolean editCellAt(int row, int column)public boolean editCellAt(int row, int column, EventObject event)public void editingCanceled(ChangeEvent event)public void editingStopped(ChangeEvent event)public Accessible
20、Context getAccessibleContext()public boolean getAutoCreateColumnsFromModel()public int getAutoResizeMode()public TableCellEditor getCellEditor()public TableCellEditor getCellEditor(int row, int column)public Rectangle getCellRect(int row, int column, boolean includeSpacing)public boolean getCellSele
21、ctionEnabled()public TableColumn getColumn(Object object)public Class getColumnClass(int column)public int getColumnCount()public TableColumnModel getColumnModel()public String getColumnName(int column)public Boolean getColumnSelectionAllowed()public TableCellEditor getDefaultEditor(Class class)publ
22、ic TableCellRenderer getDefaultRenderer(Class class)public int getEditingColumn()public int getEditingRow()public Component getEditorComponent()public Color getGridColor()public Dimension getIntercellSpacing()public TableModel getModel()public Dimension getPreferredScrollableViewportSize()public int
23、 getRowCount()public int getRowHeight()public int getRowMargin()public Boolean getRowSelectionAllowed()public int getScrollableBlockIncrement(Rectangle visible, int orientation, int direction)public Boolean getScrollableTracksViewportHeight()public Boolean getScrollableTracksViewportWidth()public in
24、t getScrollableUnitIncrement(Rectangle visible, int orientation, int direction)public int getSelectedColumn()public int getSelectedColumnCount()public int getSelectedColumns()public int getSelectedRow()public int getSelectedRowCount()public int getSelectedRows()public Color getSelectionBackground()p
25、ublic Color getSelectionForeground()public ListSelectionModel getSelectionModel()public Boolean getShowHorizontalLines()public Boolean getShowVerticalLines()public JTableHeader getTableHeader()public String getToolTipText(MouseEvent event)public TableUI getUI()public String getUIClassID()public Obje
26、ct getValueAt(int row, int column)public Boolean isCellEditable(int row, int column)public Boolean isCellSelected(int row, int column)public Boolean isColumnSelected(int column)public Boolean isEditing()public boolean isManagingFocus()public Boolean isRowSelected(int row)public void moveColumn(int c
27、olumn, int newColumn)public Component prepareEditor(TableCellEditor editor, int row, int column)public Component prepareRenderer(TableCellRenderer renderer, int row, int column)public void removeColumn(TableColumn column)public void removeColumnSelectionInterval(int column1, int column2)public void
28、removeEditor()public void removeRowSelectionInterval(int row1, int row2)public void reshape(int x, int y, int width, int height)public int rowAtPoint(Point point)public void selectAll()public void setAutoCreateColumnsFromModel(Boolean doAutoCreate)public void setAutoResizeModel(int mode)public void
29、setCellEditor(TableCellEditor editor)public void setCellSelectionEnabled(Boolean maySelect)public void setColumnModel(TableColumnModel model)public void setColumnSelectionAllowed(Boolean maySelect)public void setColumnSelectionInterval(int column1, int column2)public void setDefaultEditor(Class clas
30、s, TableCellEditor editor)public void setDefaultRenderer(Class class, TableCellRenderer renderer)public void setEditingColumn(int column)public void setEditingRow(int row)public void setGridColor(Color color)public void setIntercellSpacing(Dimention dim)public void setModel(TableModel model)public v
31、oid setPreferredScrollableViewportSize(Dimension dim)public void setRowHeight(int height)public void setRowMargin(int margin)public void setRowSelectionAllowed(Boolean maySelect)public void setSelectionBackground(Color background)public void setSelectionForeground(Color foreground)public void setSel
32、ectionMode(int mode)public void setSelectionModel(ListSelectionModel model)public void setShowGrid(Boolean showing)public void setShowHorizontalLines(Boolean b)public void setShowVerticalLines(Boolean b)public void setTableHeader(JTableHeader header)public void setUI(TableUI ui)public void setValueA
33、t(Object value, int row, int column)public void sizeColumnsToFit(int resizingColumn)public void tableChanged(TableModelEvent event)public void updateUI()public void valueChanged(ListSelectionEvent)/ plus 22 protected variables/ plus 10 protected methods/ plus 97 methods inherited from JComponent (an
34、d fields etc.)/ plus about 35 methods from Container/ plus about 85 methods from Component/ plus 11 methods from Object代碼味道w 1.1.3 過長參數(shù)列(Long Parameter List)描述描述 A method needs passing too many parameters.(一(一個方法需要傳遞太多的參數(shù)。)個方法需要傳遞太多的參數(shù)。)重構(gòu)手段重構(gòu)手段 向已有對象發(fā)出一條請求就可以取代一個參數(shù):向已有對象發(fā)出一條請求就可以取代一個參數(shù):Replace Para
35、meter with Method(以函數(shù)取代參數(shù))(以函數(shù)取代參數(shù)) 參數(shù)缺乏合理的對象歸屬:參數(shù)缺乏合理的對象歸屬:Introduce Parameter Object(引(引入?yún)?shù)對象)入?yún)?shù)對象) 將來自同一個對象的一堆參數(shù)收集起來:將來自同一個對象的一堆參數(shù)收集起來:Preserve Whole Object(保持對象完整)(保持對象完整)代碼味道w 1.1.3 過長參數(shù)列(Long Parameter List)實例實例 java.swing.CellRendererPane public void paintComponent (Graphics gr, Component re
36、nderer, Container parent, int x, int y, int width, int height, Boolean shouldValidate) java.awt.Graphics public Boolean drawImage (Image image, int x1Dest, int y1Dest, int x2Dest, int y2Dest, int x1Source, int y1Source, int x2Source, int y2Source, Color color, ImageObserver obs)代碼味道w 1.1.4 過多的注釋(Com
37、ments)描述描述 Do not write comments when it is unnecessary. When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous.(在非必要的情況下不要寫注釋。當(dāng)你覺(在非必要的情況下不要寫注釋。當(dāng)你覺得需要去寫一段注釋時,你首先應(yīng)該嘗試去重構(gòu)代碼,得需要去寫一段注釋時,你首先應(yīng)該嘗試去重構(gòu)代碼,這將使任何注釋都變得是多余的。)這將使任何注釋都變得是多余的。)代碼味道w 1.1.4 過
38、多的注釋(Comments)重構(gòu)手段重構(gòu)手段 需要注釋來解釋一塊代碼做了什么:需要注釋來解釋一塊代碼做了什么:Extract Method(提煉函數(shù))(提煉函數(shù)) 函數(shù)已經(jīng)提煉出來,但還是需要注釋來解釋其行為:函數(shù)已經(jīng)提煉出來,但還是需要注釋來解釋其行為:Rename Method(函數(shù)改名)(函數(shù)改名) 需要注釋來說明某些系統(tǒng)的需求規(guī)格:需要注釋來說明某些系統(tǒng)的需求規(guī)格:Introduce Assertion(引入斷言)(引入斷言)代碼味道w 1.1.4 過多的注釋(Comments)實例實例public class Matcher public Matcher() public boole
39、an match(int expected, int actual, int clipLimit, int delta) / Clip too-large values for (int i = 0; i clipLimit) actuali = clipLimit; / Check for length differences if (actual.length != expected.length) return false; / Check that each entry within expected +/- delta for (int i = 0; i delta) return
40、false; return true; 代碼味道w 1.2.1 夸夸其談的未來性(Speculative Generality)描述描述 If a machinery was being used, it would be worth it. But if it is not, it is not. The machinery just gets in the way, so get rid of it.(如果一個裝置(如果一個裝置【一個設(shè)計或一個設(shè)計或?qū)崿F(xiàn)方案實現(xiàn)方案】會被用到,那就值得去做;如果用不到,就會被用到,那就值得去做;如果用不到,就不值得。用不到的裝置會成為攔路石,因此需要將它搬
41、不值得。用不到的裝置會成為攔路石,因此需要將它搬移。)移。)代碼味道w 1.2.1 夸夸其談的未來性(Speculative Generality)重構(gòu)手段重構(gòu)手段 某個抽象類沒有太大作用:某個抽象類沒有太大作用:Collapse Hierarchy(折疊繼承體(折疊繼承體系)系) 不必要的委托:不必要的委托:Inline Class(將類內(nèi)聯(lián)化)(將類內(nèi)聯(lián)化) 函數(shù)的某些參數(shù)未被使用:函數(shù)的某些參數(shù)未被使用:Remove Parameter(移除參數(shù))(移除參數(shù)) 函數(shù)名稱帶有多余的抽象涵義:函數(shù)名稱帶有多余的抽象涵義:Rename Method(函數(shù)改名)(函數(shù)改名) 對于無用的函數(shù):對于
42、無用的函數(shù):Inline Method(內(nèi)聯(lián)函數(shù))、(內(nèi)聯(lián)函數(shù))、Remove Method(移除函數(shù))(移除函數(shù))代碼味道w 1.2.1 夸夸其談的未來性(Speculative Generality)實例:如果函數(shù)或類的實例:如果函數(shù)或類的唯一用戶是測試用例唯一用戶是測試用例(Test Cases),這就飄出了壞味道,這就飄出了壞味道Speculative Generality。如果你發(fā)現(xiàn)這樣的函數(shù)或類,請把它們連同其測試用例如果你發(fā)現(xiàn)這樣的函數(shù)或類,請把它們連同其測試用例一并刪掉。但如果它們的用途是幫助測試用例檢測正當(dāng)一并刪掉。但如果它們的用途是幫助測試用例檢測正當(dāng)功能,當(dāng)然必須刀下留人
43、。功能,當(dāng)然必須刀下留人。代碼味道w 1.3.1 重復(fù)代碼(Duplicated Code)描述描述 Same code structure happens in more than one place.(在一個以上的地方發(fā)現(xiàn)相似的代碼結(jié)構(gòu)。)(在一個以上的地方發(fā)現(xiàn)相似的代碼結(jié)構(gòu)。)類型類型類型一:類型一:除空格、布局和注釋不同之外,其余部分都相同的代碼片段除空格、布局和注釋不同之外,其余部分都相同的代碼片段類型二:類型二:除標(biāo)識符、字面量、類型、空格、布局和注釋外,語法結(jié)構(gòu)相同的代除標(biāo)識符、字面量、類型、空格、布局和注釋外,語法結(jié)構(gòu)相同的代碼片段碼片段類型三:類型三:除標(biāo)識符、字面量、類型、
44、空格、布局和注釋外,進(jìn)一步對重復(fù)代碼除標(biāo)識符、字面量、類型、空格、布局和注釋外,進(jìn)一步對重復(fù)代碼段進(jìn)行改動,例如修改、增加或者刪除語句段進(jìn)行改動,例如修改、增加或者刪除語句類型四:類型四:兩個或多個代碼片段執(zhí)行相同的計算(功能),但是語法結(jié)構(gòu)的實現(xiàn)兩個或多個代碼片段執(zhí)行相同的計算(功能),但是語法結(jié)構(gòu)的實現(xiàn)方式不同方式不同代碼味道w 1.3.1 重復(fù)代碼(Duplicated Code)重構(gòu)手段重構(gòu)手段 同一個類的一個同一個類的一個/兩個方法含有相同的代碼:兩個方法含有相同的代碼: Extract Method(提煉函數(shù))(提煉函數(shù)) 兩個互為兄弟的子類含有相同的代碼:兩個互為兄弟的子類含有相
45、同的代碼:Extract Method(提煉函數(shù))、(提煉函數(shù))、Pull Up Method(函數(shù)上(函數(shù)上移)、移)、Form Template Method(塑造模板函數(shù))(塑造模板函數(shù)) 兩個毫不相關(guān)的類含有相同的代碼兩個毫不相關(guān)的類含有相同的代碼 :Extract Class(提煉類)(提煉類)代碼味道w 1.3.1 重復(fù)代碼(Duplicated Code)w 實例實例代碼味道w 1.3.2 異曲同工的類(Alternative Classes with Different Interfaces)描述描述Classes are doing similar things but wi
46、th different signatures. (不同的類做相同的事情,卻(不同的類做相同的事情,卻擁有不同的簽名,主要是指方法簽名不同。)擁有不同的簽名,主要是指方法簽名不同。)代碼味道w 1.3.2 異曲同工的類(Alternative Classes with Different Interfaces)重構(gòu)手段重構(gòu)手段 兩 個 函 數(shù) 做 同 一 件 事 , 卻 有 著 不 同 的 簽 名 :兩 個 函 數(shù) 做 同 一 件 事 , 卻 有 著 不 同 的 簽 名 :Rename Method(函數(shù)改名)(函數(shù)改名) 將某些行為移入類,直到兩者的協(xié)議一致為止:將某些行為移入類,直到兩者的
47、協(xié)議一致為止:Move Method(搬移函數(shù))(搬移函數(shù)) 必須重復(fù)而冗贅地移入代碼才能實現(xiàn)上述重構(gòu):必須重復(fù)而冗贅地移入代碼才能實現(xiàn)上述重構(gòu):Extract Superclass(提煉超類)(提煉超類)代碼味道w 1.3.2 異曲同工的類(Alternative Classes with Different Interfaces)實例實例代碼味道w 1.4.1 Switch驚悚現(xiàn)身(Switch Statement)描述描述Switch statements often lead to duplication. Most times you see a switch statement w
48、hich you should consider as polymorphism.(Switch語句通常會導(dǎo)致代碼重復(fù)。大多數(shù)時候,一看到語句通常會導(dǎo)致代碼重復(fù)。大多數(shù)時候,一看到Switch語句你應(yīng)該考慮使用多態(tài)來替換。)語句你應(yīng)該考慮使用多態(tài)來替換。)代碼味道w 1.4.1 Switch驚悚現(xiàn)身(Switch Statement)重構(gòu)手段重構(gòu)手段 與類型碼相關(guān)的函數(shù)或類:與類型碼相關(guān)的函數(shù)或類:Extract Method(提煉函數(shù))、(提煉函數(shù))、Move Method(搬移函數(shù))、(搬移函數(shù))、Replace Conditional with Polymorphism(以多態(tài)取代條件表
49、達(dá)式)、(以多態(tài)取代條件表達(dá)式)、Replace Type Code with Subclass(以子類取代類型碼)、(以子類取代類型碼)、Replace Type Code with State/Strategy(以(以State/Strategy取代類型碼)取代類型碼) 只在單一函數(shù)中有一些選擇事件,且不想改動它們:只在單一函數(shù)中有一些選擇事件,且不想改動它們:Replace Parameter with Explicit Methods(以明確函數(shù)取代參數(shù))(以明確函數(shù)取代參數(shù)) 選擇條件之一是選擇條件之一是null:Introduce Null Object(引入(引入Null對象)對
50、象)代碼味道w 1.4.1 Switch驚悚現(xiàn)身(Switch Statement)實例實例/電影票類class MovieTicket private double price; /電影票價格 private String type; /電影票類型 /計算打折之后的票價 public double calculate() /學(xué)生票折后票價計算 if(this.type.equalsIgnoreCase(student) System.out.println(學(xué)生票:); return this.price * 0.8; /兒童票折后票價計算 else if(this.type.equalsI
51、gnoreCase(children) & this.price = 20 ) System.out.println(兒童票:); return this.price - 10; /VIP票折后票價計算 else if(this.type.equalsIgnoreCase(vip) System.out.println(VIP票:); System.out.println(增加積分!); return this.price * 0.5; else return this.price; /如果不滿足任何打折要求,則返回原始票價 代碼味道代碼味道w 2.1.1 基本類型偏執(zhí)(Primiti
52、ve Obsession)描述描述Primitive types are overused in software. Small classes should be used in place of primitive types in some situations.(在軟件中,基本類型(在軟件中,基本類型被過度使用。在某些場合下,應(yīng)該使用一些小的類被過度使用。在某些場合下,應(yīng)該使用一些小的類來代替這些基本類型。)來代替這些基本類型。)代碼味道w 2.1.1 基本類型偏執(zhí)(Primitive Obsession) 重構(gòu)手段重構(gòu)手段將原本單獨存在的數(shù)據(jù)值替換成對象:將原本單獨存在的數(shù)據(jù)值替換成
53、對象:Replace Data Value with Object(以對象取代數(shù)據(jù)值)(以對象取代數(shù)據(jù)值)如果想要替換的數(shù)據(jù)值是類型碼,而它并不影響行為:如果想要替換的數(shù)據(jù)值是類型碼,而它并不影響行為:Replace Type Code with Class(以類取代類型碼)(以類取代類型碼)如果有與類型碼相關(guān)的條件表達(dá)式:如果有與類型碼相關(guān)的條件表達(dá)式: Replace Type Code with Subclass(以子類取代類型碼)、(以子類取代類型碼)、 Replace Type Code with State/Strategy(以(以State/Strategy取代類型碼)取代類型碼
54、)如果有一組應(yīng)該總是被放在一起的字段:如果有一組應(yīng)該總是被放在一起的字段: Extract Class(提煉類)提煉類)如果在參數(shù)列中看到基本類型的數(shù)據(jù):如果在參數(shù)列中看到基本類型的數(shù)據(jù): Introduce Parameter Object(引入?yún)?shù)對象)(引入?yún)?shù)對象)發(fā)現(xiàn)自己正從數(shù)組中挑選數(shù)據(jù):發(fā)現(xiàn)自己正從數(shù)組中挑選數(shù)據(jù): Replace Array with Object(以對象取(以對象取代數(shù)組)代數(shù)組)代碼味道w 2.1.1 基本類型偏執(zhí)(Primitive Obsession)實例實例public class Person private String name; private
55、 int birthdayDay; private int brithdayMonth; private int brithdayYear; private String addressNationality; private String addressProvince; private String addressCity; private String addressStreet; 代碼味道w 2.1.2 純稚的數(shù)據(jù)類(Data Class)描述描述 These are classes that have fields, getting and setting methods for t
56、he fields, and nothing else. Such classes are dumb data holders and are almost certainly being manipulated in far too much detail by other classes.(這(這些類擁有一些字段些類擁有一些字段【成員變量成員變量】,并提供了對應(yīng)的,并提供了對應(yīng)的Getter和和Setter方法,除此以外一無所有。這些類只是一些不會說話的方法,除此以外一無所有。這些類只是一些不會說話的數(shù)據(jù)容器,數(shù)據(jù)容器, 而且它們必定會被其他類過分瑣細(xì)地操作。)而且它們必定會被其他類過分瑣
57、細(xì)地操作。)代碼味道w 2.1.2 純稚的數(shù)據(jù)類(Data Class)重構(gòu)手段重構(gòu)手段對于對于public字段:字段: Encapsulate Field(封裝字段)(封裝字段)如果一個類內(nèi)含容器類的字段,如果沒有得到恰當(dāng)?shù)姆庋b:如果一個類內(nèi)含容器類的字段,如果沒有得到恰當(dāng)?shù)姆庋b: Encapsulate Collection(封裝集合)(封裝集合)對于那些不該被其他類修改的字段:對于那些不該被其他類修改的字段:Remove Setting Method(移除(移除設(shè)值函數(shù))設(shè)值函數(shù))找出找出Getter/Setter函數(shù)被其他類運用的地點:函數(shù)被其他類運用的地點:Move Method(搬
58、移函(搬移函數(shù))數(shù))如果無法搬移整個函數(shù):如果無法搬移整個函數(shù):Extract Method(提煉函數(shù))(提煉函數(shù))將將Getter/Setter函數(shù)隱藏起來:函數(shù)隱藏起來:Hide Method(隱藏函數(shù))(隱藏函數(shù))代碼味道w 2.1.2 純稚的數(shù)據(jù)類(Data Class)實例實例package net.sf.robocode.serialization;/* * author Pavel Savara (original) */public class SerializableOptions public boolean skipExploded;public boolean skip
59、Names;public boolean skipVersion;public boolean skipDebug;public boolean skipTotal;public boolean trimPrecision;public boolean shortAttributes;public SerializableOptions(SerializableOptions src) skipExploded = src.skipExploded;skipNames = src.skipNames;skipVersion = src.skipVersion;skipDebug = src.s
60、kipDebug;skipTotal = src.skipTotal;trimPrecision = src.trimPrecision;shortAttributes = src.shortAttributes;public SerializableOptions(boolean skipAllDetails) if (skipAllDetails) skipExploded = true;skipNames = true;skipVersion = true;skipDebug = true;skipTotal = true;trimPrecision = true;shortAttributes
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 影像三基考試試題及答案
- 溫州高級電工考試試題及答案
- 醫(yī)師定期考試試題及答案
- 廚神大賽筆試題及答案
- 財務(wù)管理混合模式的試題及答案
- 道具伴侶測試題及答案
- 大考心理測試題及答案
- 初中靜物考試題及答案
- 成人脾氣測試題及答案
- 初級會計實務(wù)習(xí)題及答案參考
- 華中師范大學(xué)第一附中2025屆高考沖刺押題(最后一卷)數(shù)學(xué)試卷含解析
- 《電力機車構(gòu)造(第2版)》課件 任務(wù)三 HXD1型電力機車車體設(shè)備布置認(rèn)知
- (完整版)北郵英語統(tǒng)考題庫
- 殯儀服務(wù)員職業(yè)培訓(xùn)試題和答案
- 房屋買賣合同范本模版模板
- 第五課 在和睦家庭中成長 說課稿-2024-2025學(xué)年高中政治統(tǒng)編版選擇性必修二法律與生活
- 農(nóng)業(yè)昆蟲學(xué)-形考測試一-國開(ZJ)-參考資料
- 房地產(chǎn) -中建商務(wù)管理精細(xì)化管理實施細(xì)則
- 初級消防設(shè)施操作員實操題庫 (一)
- JJF 2166-2024電子固體密度天平校準(zhǔn)規(guī)范
- 六年級青島版數(shù)學(xué)下學(xué)期應(yīng)用題專項水平練習(xí)題
評論
0/150
提交評論