第1章重构与代码味道_第1页
第1章重构与代码味道_第2页
第1章重构与代码味道_第3页
第1章重构与代码味道_第4页
第1章重构与代码味道_第5页
已阅读5页,还剩90页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第1章章重构与代码味道重构与代码味道刘刘 伟伟 (Sunny)weiliu_内容w 重构w 代码味道w 代码味道识别工具重构 软件开发方法学的泰山北斗,是最早研究软件开发模式和重构的人之一,软件开发方法学的泰山北斗,是最早研究软件开发模式和重构的人之一,是是敏捷开发的开创者之一敏捷开发的开创者之一,更是,更是极限编程极限编程(XP)和测试驱动开发和测试驱动开发(TDD)的的创始人创始人,同时还是,同时还是JUnit的作者,对当今世界的软件开发影响深远。的作者,对当今世界的软件开发影响深远。重构国际著名面向对象专家,敏捷开发方法的创始人之一,是国际著名面向对象专家,敏捷开发方法的创始人之一,是

2、面向对象分析面向对象分析设计、设计、UML、模式、软件开发方法学、模式、软件开发方法学、XP、重构、重构等领域的世界顶级专家,等领域的世界顶级专家,现为现为Thought Works公司的首席科学家。主要著作包括公司的首席科学家。主要著作包括分析模式分析模式、企业应用架构模式企业应用架构模式、UML精粹精粹和和重构重构等。等。重构w 何谓重构(Fowlers Definition)重构(名词):重构(名词):对软件内部结构的一种调整,目的是在对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。低其修改成

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.重构w 何谓重构(Fowlers Definition)重构(动词):重构(动词):使用一系列重构手法,在不改变软件可使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。观察行为的前提下,调整其结构。Refactor (verb): to restr

4、ucture software by applying a series of refactorings without changing its observable behavior.重构w 何谓重构(Fowlers Definition)重构w 何谓重构重构重构是是在不改变软件现有功能的基础上,通过调整程序在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使程序的设计和架构更趋代码改善软件的质量、性能,使程序的设计和架构更趋合理,进而提高软件的扩展性和维护性合理,进而提高软件的扩展性和维护性。 重构w 重构小实例(漫画)重构w 重构小实例(漫画)重构w 为何重构重构改进

5、软件设计重构改进软件设计(Refactoring Improves the Design of Software)重构使软件更容易理解重构使软件更容易理解 (Refactoring Makes Software Easier to Understand)重构帮助找到缺陷重构帮助找到缺陷 (Refactoring Helps You Find Bugs)重构提高编程速度重构提高编程速度 (Refactoring Helps You Program Faster)重构w 何时重构添加功能时重构添加功能时重构 (Refactor When You Add Function)修补错误时重构修补错误时重

6、构 (Refactor When You Need to Fix a Bug)复审代码时重构复审代码时重构(Refactor As You Do a Code Review)Three strikes and you refactor.代码味道w 代码味道代码味道:代码坏味道,代码味道:代码坏味道,Bad Smells in Code在在重构:改善既有代码的设计重构:改善既有代码的设计一书一书中,中,Kent Beck和和Martin Fowler一共一共定义了定义了22种种常用的代码味道常用的代码味道代码味道是指程序中存在的一些代码味道是指程序中存在的一些不良的不良的编程或设计方案编程或设计

7、方案代 码 味 道 可 以 作 为代 码 味 道 可 以 作 为 重 构 的 指 示 剂重 构 的 指 示 剂 (indicator)代码味道w 代码味道代码味道w 代码味道分类1. 类内味道类内味道1.1 Measured Smells(可度量的味道)(可度量的味道)1.2 Unneccessary Complexity(不必要的复杂性)(不必要的复杂性)1.3 Duplication(重复)(重复)1.4 Conditional Logic(条件逻辑)(条件逻辑)代码味道w 代码味道分类2. 类间味道类间味道2.1 Data(数据)(数据)2.2 Inheritance(继承)(继承)2.

8、3 Responsibility(职责)(职责)2.4 Accommodating Change(协调变化)(协调变化)2.5 Library Classes(库类)(库类)代码味道w 1. 类内味道1.1 可度量的味道可度量的味道1.1.1 Long Method(过长函数)(过长函数)1.1.2 Large Class(过大类)(过大类)1.1.3 Long Parameter List(过长参数列)(过长参数列)1.1.4 Comments(过多的注释)(过多的注释)1.2 不必要的复杂性不必要的复杂性1.2.1 Speculative Generality(夸夸其谈的未来(夸夸其谈的未

9、来性)性)代码味道w 1. 类内味道1.3 重复重复1.3.1 Duplicated Code(重复代码)(重复代码)1.3.2 Alternative Classes with Different Interfaces(异曲同工的类)(异曲同工的类)1.4 条件逻辑条件逻辑1.4.1 Switch Statements(Switch惊悚现身)惊悚现身)代码味道w 2. 类间味道2.1 数据数据2.1.1 Primitive Obsession(基本类型偏执)(基本类型偏执)2.1.2 Data Class(纯稚的数据类)(纯稚的数据类)2.1.3 Data Clumps(数据泥团)(数据泥团

10、)2.1.4 Temporary Field(令人迷惑的暂时值域)(令人迷惑的暂时值域)代码味道w 2. 类间味道2.2 继承继承2.2.1 Refused Bequest(被拒绝的遗赠)(被拒绝的遗赠)2.2.2 Inappropriate Intimacy(狎昵关系)(狎昵关系)2.2.3 Lazy Class(冗赘类)(冗赘类)2.3 职责职责2.3.1 Feature Envy(依恋情节)(依恋情节)2.3.2 Message Chains(过度耦合的消息链)(过度耦合的消息链)2.3.3 Middle Man(中间转手人)(中间转手人)代码味道w 2. 类间味道2.4 协调变化协调变

11、化2.4.1 Divergent Change(发散式变化)(发散式变化)2.4.2 Shotgun Surgery(霰弹式修改)(霰弹式修改)2.4.3 Parallel Inheritance Hierarchies(平行继(平行继承体系)承体系)2.5 库类库类2.5.1 Incomplete Library Class(不完善的程序(不完善的程序库类)库类)代码味道代码味道w 1.1.1 过长函数(Long Method)代码味道w 1.1.1 过长函数(Long Method)代码味道w 1.1.1 过长函数(Long Method)代码味道w 1.1.1 过长函数(Long Met

12、hod) 描述描述 A method is too long.(方法太长。)(方法太长。) 重构手段重构手段 把函数变小:把函数变小:Extract Method(提炼函数)(提炼函数) 函数内有大量的参数和临时变量:函数内有大量的参数和临时变量:Replace Temp with Query(以查(以查询取代临时变量)询取代临时变量) 参数太多:参数太多:Introduce Parameter Object(引入参数对象)、(引入参数对象)、Preserve Whole Object(保持对象完整)(保持对象完整) 太多临时变量和注释:太多临时变量和注释:Replace Method wit

13、h Method Object(以函(以函数对象取代函数)数对象取代函数) 条件表达式和循环:条件表达式和循环:Decompose Conditional(分解条件表达式)(分解条件表达式)代码味道w 1.1.1 过长函数(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.(一个类试图做太多的事情,通常(一个类试图做太多的事情,通常会出现太多的实例变量。)会出现太多的实例变量。) 重构手段

14、重构手段 太多实例变量或太多代码:太多实例变量或太多代码:Extract Class(提炼类)、(提炼类)、Extract Subclass(提炼子类)(提炼子类) 确定客户端如何使用:确定客户端如何使用:Extract Interface(提炼接口)(提炼接口) 把数据和行为移到一个独立的领域对象,但需要保留一些重复把数据和行为移到一个独立的领域对象,但需要保留一些重复数据:数据:Duplicate Observed Data(复制(复制“被监视数据被监视数据”)代码味道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 过长参数列(Long Parameter List)描述描述 A method needs passing too many parameters.(一(一个方法需要传递太多的参数。)个方法需要传递太多的参数。)重构手段重构手段 向已有对象发出一条请求就可以取代一个参数:向已有对象发出一条请求就可以取代一个参数:Replace Para

35、meter with Method(以函数取代参数)(以函数取代参数) 参数缺乏合理的对象归属:参数缺乏合理的对象归属:Introduce Parameter Object(引(引入参数对象)入参数对象) 将来自同一个对象的一堆参数收集起来:将来自同一个对象的一堆参数收集起来:Preserve Whole Object(保持对象完整)(保持对象完整)代码味道w 1.1.3 过长参数列(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.(在非必要的情况下不要写注释。当你觉(在非必要的情况下不要写注释。当你觉得需要去写一段注释时,你首先应该尝试去重构代码,得需要去写一段注释时,你首先应该尝试去重构代码,这将使任何注释都变得是多余的。)这将使任何注释都变得是多余的。)代码味道w 1.1.4 过

38、多的注释(Comments)重构手段重构手段 需要注释来解释一块代码做了什么:需要注释来解释一块代码做了什么:Extract Method(提炼函数)(提炼函数) 函数已经提炼出来,但还是需要注释来解释其行为:函数已经提炼出来,但还是需要注释来解释其行为:Rename Method(函数改名)(函数改名) 需要注释来说明某些系统的需求规格:需要注释来说明某些系统的需求规格: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.(如果一个装置(如果一个装置【一个设计或一个设计或实现方案实现方案】会被用到,那就值得去做;如果用不到,就会被用到,那就值得去做;如果用不到,就不值得。用不到的装置会成为拦路石,因此需要将它搬

41、不值得。用不到的装置会成为拦路石,因此需要将它搬移。)移。)代码味道w 1.2.1 夸夸其谈的未来性(Speculative Generality)重构手段重构手段 某个抽象类没有太大作用:某个抽象类没有太大作用:Collapse Hierarchy(折叠继承体(折叠继承体系)系) 不必要的委托:不必要的委托:Inline Class(将类内联化)(将类内联化) 函数的某些参数未被使用:函数的某些参数未被使用:Remove Parameter(移除参数)(移除参数) 函数名称带有多余的抽象涵义:函数名称带有多余的抽象涵义:Rename Method(函数改名)(函数改名) 对于无用的函数:对于

42、无用的函数:Inline Method(内联函数)、(内联函数)、Remove Method(移除函数)(移除函数)代码味道w 1.2.1 夸夸其谈的未来性(Speculative Generality)实例:如果函数或类的实例:如果函数或类的唯一用户是测试用例唯一用户是测试用例(Test Cases),这就飘出了坏味道,这就飘出了坏味道Speculative Generality。如果你发现这样的函数或类,请把它们连同其测试用例如果你发现这样的函数或类,请把它们连同其测试用例一并删掉。但如果它们的用途是帮助测试用例检测正当一并删掉。但如果它们的用途是帮助测试用例检测正当功能,当然必须刀下留人

43、。功能,当然必须刀下留人。代码味道w 1.3.1 重复代码(Duplicated Code)描述描述 Same code structure happens in more than one place.(在一个以上的地方发现相似的代码结构。)(在一个以上的地方发现相似的代码结构。)类型类型类型一:类型一:除空格、布局和注释不同之外,其余部分都相同的代码片段除空格、布局和注释不同之外,其余部分都相同的代码片段类型二:类型二:除标识符、字面量、类型、空格、布局和注释外,语法结构相同的代除标识符、字面量、类型、空格、布局和注释外,语法结构相同的代码片段码片段类型三:类型三:除标识符、字面量、类型、

44、空格、布局和注释外,进一步对重复代码除标识符、字面量、类型、空格、布局和注释外,进一步对重复代码段进行改动,例如修改、增加或者删除语句段进行改动,例如修改、增加或者删除语句类型四:类型四:两个或多个代码片段执行相同的计算(功能),但是语法结构的实现两个或多个代码片段执行相同的计算(功能),但是语法结构的实现方式不同方式不同代码味道w 1.3.1 重复代码(Duplicated Code)重构手段重构手段 同一个类的一个同一个类的一个/两个方法含有相同的代码:两个方法含有相同的代码: Extract Method(提炼函数)(提炼函数) 两个互为兄弟的子类含有相同的代码:两个互为兄弟的子类含有相

45、同的代码:Extract Method(提炼函数)、(提炼函数)、Pull Up Method(函数上(函数上移)、移)、Form Template Method(塑造模板函数)(塑造模板函数) 两个毫不相关的类含有相同的代码两个毫不相关的类含有相同的代码 :Extract Class(提炼类)(提炼类)代码味道w 1.3.1 重复代码(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)重构手段重构手段 两 个 函 数 做 同 一 件 事 , 却 有 着 不 同 的 签 名 :两 个 函 数 做 同 一 件 事 , 却 有 着 不 同 的 签 名 :Rename Method(函数改名)(函数改名) 将某些行为移入类,直到两者的协议一致为止:将某些行为移入类,直到两者的

47、协议一致为止:Move Method(搬移函数)(搬移函数) 必须重复而冗赘地移入代码才能实现上述重构:必须重复而冗赘地移入代码才能实现上述重构:Extract Superclass(提炼超类)(提炼超类)代码味道w 1.3.2 异曲同工的类(Alternative Classes with Different Interfaces)实例实例代码味道w 1.4.1 Switch惊悚现身(Switch Statement)描述描述Switch statements often lead to duplication. Most times you see a switch statement w

48、hich you should consider as polymorphism.(Switch语句通常会导致代码重复。大多数时候,一看到语句通常会导致代码重复。大多数时候,一看到Switch语句你应该考虑使用多态来替换。)语句你应该考虑使用多态来替换。)代码味道w 1.4.1 Switch惊悚现身(Switch Statement)重构手段重构手段 与类型码相关的函数或类:与类型码相关的函数或类:Extract Method(提炼函数)、(提炼函数)、Move Method(搬移函数)、(搬移函数)、Replace Conditional with Polymorphism(以多态取代条件表

49、达式)、(以多态取代条件表达式)、Replace Type Code with Subclass(以子类取代类型码)、(以子类取代类型码)、Replace Type Code with State/Strategy(以(以State/Strategy取代类型码)取代类型码) 只在单一函数中有一些选择事件,且不想改动它们:只在单一函数中有一些选择事件,且不想改动它们:Replace Parameter with Explicit Methods(以明确函数取代参数)(以明确函数取代参数) 选择条件之一是选择条件之一是null:Introduce Null Object(引入(引入Null对象)对

50、象)代码味道w 1.4.1 Switch惊悚现身(Switch Statement)实例实例/电影票类class MovieTicket private double price; /电影票价格 private String type; /电影票类型 /计算打折之后的票价 public double calculate() /学生票折后票价计算 if(this.type.equalsIgnoreCase(student) System.out.println(学生票:); 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 基本类型偏执(Primiti

52、ve Obsession)描述描述Primitive types are overused in software. Small classes should be used in place of primitive types in some situations.(在软件中,基本类型(在软件中,基本类型被过度使用。在某些场合下,应该使用一些小的类被过度使用。在某些场合下,应该使用一些小的类来代替这些基本类型。)来代替这些基本类型。)代码味道w 2.1.1 基本类型偏执(Primitive Obsession) 重构手段重构手段将原本单独存在的数据值替换成对象:将原本单独存在的数据值替换成

53、对象:Replace Data Value with Object(以对象取代数据值)(以对象取代数据值)如果想要替换的数据值是类型码,而它并不影响行为:如果想要替换的数据值是类型码,而它并不影响行为:Replace Type Code with Class(以类取代类型码)(以类取代类型码)如果有与类型码相关的条件表达式:如果有与类型码相关的条件表达式: Replace Type Code with Subclass(以子类取代类型码)、(以子类取代类型码)、 Replace Type Code with State/Strategy(以(以State/Strategy取代类型码)取代类型码

54、)如果有一组应该总是被放在一起的字段:如果有一组应该总是被放在一起的字段: Extract Class(提炼类)提炼类)如果在参数列中看到基本类型的数据:如果在参数列中看到基本类型的数据: Introduce Parameter Object(引入参数对象)(引入参数对象)发现自己正从数组中挑选数据:发现自己正从数组中挑选数据: Replace Array with Object(以对象取(以对象取代数组)代数组)代码味道w 2.1.1 基本类型偏执(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 纯稚的数据类(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.(这(这些类拥有一些字段些类拥有一些字段【成员变量成员变量】,并提供了对应的,并提供了对应的Getter和和Setter方法,除此以外一无所有。这些类只是一些不会说话的方法,除此以外一无所有。这些类只是一些不会说话的数据容器,数据容器, 而且它们必定会被其他类过分琐细地操作。)而且它们必定会被其他类过分琐

57、细地操作。)代码味道w 2.1.2 纯稚的数据类(Data Class)重构手段重构手段对于对于public字段:字段: Encapsulate Field(封装字段)(封装字段)如果一个类内含容器类的字段,如果没有得到恰当的封装:如果一个类内含容器类的字段,如果没有得到恰当的封装: Encapsulate Collection(封装集合)(封装集合)对于那些不该被其他类修改的字段:对于那些不该被其他类修改的字段:Remove Setting Method(移除(移除设值函数)设值函数)找出找出Getter/Setter函数被其他类运用的地点:函数被其他类运用的地点:Move Method(搬

58、移函(搬移函数)数)如果无法搬移整个函数:如果无法搬移整个函数:Extract Method(提炼函数)(提炼函数)将将Getter/Setter函数隐藏起来:函数隐藏起来:Hide Method(隐藏函数)(隐藏函数)代码味道w 2.1.2 纯稚的数据类(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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论