有關於Refactor(重構)與Source(源)的比較

來源:互聯網
上載者:User

上周發的blog上,談及Vs.net與Eclipse的比較,在“快速由欄位產生屬性”的問題與兄弟們發生了爭執,有兄弟認為在Vs.net2005重構中“Encapsulate Field...”,可以做到這一功能。我覺得這是一個概念上的錯誤,因為“封裝欄位“這個重構方法的本質並不是幹這事。

算了,我乾脆就談談“重構”吧

讓我從頭說起吧,當然俺的知識有限,肯定有說錯的地方。

如果說錯了,還請各位海涵。最重要的是指出俺的錯誤,不讓俺一直錯下去。

說到了“重構(refactor)”,也不得不說說源(Source),看看他們的比較。

一、Source

Source並不是一個標準的概念,目前來說只出現在Eclipse 中,他可以說是一堆方便寫代碼的功能的集合,來看看Eclipse中的Source菜單

(菜單內容就不仔細解釋了,看英文就懂了)

Source的功能大多數是為了方便寫代碼之用,即他是在產生代碼,也就是說,他的作用發生在“編寫代碼時”,他是“產生代碼結構,而非改變代碼結構

Source的功能很多,在實際操作中,可大大加快寫代碼的速度,大家可以自行看功能表項目理解(強烈建議自己動手一試),我這裡僅僅談談,上次發生爭論的“Generate Getters and Setters..”的功能。

這裡我圖例一次,操作,希望大家不要閑煩。

這個“Generate Getters and Setters..”就是我上次說的,“快速產生屬性..”。

我隨便寫一個類, 寫了三個欄位,讓他幫我同時產生這三個屬性:

/**

 * @author duliang

 * @version 1.0

 * <p> </p>

 */

public class TestField

{

 private String name = "";

 private String address = "";

 private boolean isNew = false;

 

}

操作如下:

OK,一切搞定,連注釋都有了,自動產生如下代碼:

/**

 * @author duliang

 * @version 1.0

 * <p> </p>

 */

public class TestField

{

 private String name = "";

 private String address = "";

 private boolean isNew = false;

 

 

 /**

  * @return Returns the address.

  */

 public String getAddress()

 {

  return (address);

 }

 /**

  * @param address The address to set.

  */

 public void setAddress(String address)

 {

  this.address = address;

 }

 /**

  * @return Returns the isNew.

  */

 public boolean isNew()

 {

  return (isNew);

 }

 /**

  * @param isNew The isNew to set.

  */

 public void setNew(boolean isNew)

 {

  this.isNew = isNew;

 }

 /**

  * @return Returns the name.

  */

 public String getName()

 {

  return (name);

 }

 /**

  * @param name The name to set.

  */

 public void setName(String name)

 {

  this.name = name;

 }

}

實際上我要說的就是這麼一個簡單的功能。

我圖例的原因,就是告訴大家,這些操作發生在“代碼編寫時”。哈哈,很羅嗦吧:)

二 Refactor

OK,再來說說重構,這也是主題。

重構是指:在不改變代碼功能的基礎上,改變代碼的結構。

舉幾個重構的簡單例子:

1. 重新命名某個類,某個欄位或者是本地變數,你則需要“rename“操作。

2. 某函數代碼太長,你就需要將一個函數分成多個小函數,則你需要“Extract Method(抽取方法)”

3. 你的類,需要增加基類(介面),以更好的符合裡氏代換、依賴轉置原則,則你需要 “Extract Interface”

4. 某個方法要移至基類或子類,你則需要使用“Pull UP” 或 “Pull Down”

5.  。。。。。

重構是一種思想,當然你可以用手動改代碼直接實現,但是你面對大項目時,你就會發現手動重構是多麼痛苦,比如你在項目中,修改一個被其它人廣泛使用的類名(方法名),如果你手動修改,必須得一個個的手動尋找、修改,你認為不痛苦嗎?

如果只需要點幾下滑鼠,就能搞定這一切,那多爽?

這就是開發工具提供重構的意義。

下面來看看Eclipse中提供的重構功能:


Vs.net 2005提供的有:

顯然,Eclipse提供的要多得多。

當然就算是eclipse,提供的重構功能也並不是全部,慢慢加強吧。

OK,現在我們都知道“重構”是什麼了,我們再來看看有兄弟指出的“Encapsulate Field...”方法到底是幹什麼。

從上兩圖中可以看出,這功能在Eclipse與Vs2005中都提供,可以說這方法是比較重要,比較常見的。

當然,首先我得承認,使用“Encapsulate Field...”確實能使用單個欄位產生屬性  ,似乎是實現了我們上次爭論的功能。但是它既然稱為重構的一種方法,則他的本質作用便不是這個,。

重構是幹什嗎?他是要改變代碼的結構,以讓代碼更便閱讀,代碼結構更合理。

因此“Encapsulate Field...”的作用是“封裝欄位的可見度”,發產生“代碼編寫後

初級程式員,經常幹這種事情,就是為了訪問方便,把一些欄位設成public 或者說是protected、internal這些可能被外部直接修改的類型,擁有這種修飾符欄位的類,是不安全的,因為有些欄位我們經常是不允許外部更改的。

類設計的基本原則就是盡量減少提供修改類內部結構的方法。這樣隨意讓別人就有權力更改內部欄位,顯然是不合理的。

因此這個時候就需要使用“Encapsulate Field...”這個重構方法,將代碼重構,使這些欄位通過get,set來訪問,以控制欄位的可見度,保證類的安全。

“Generate Getters and Setters..”與“Encapsulate Field...”還有個很大的區別,也可以說是Source與Refactor的區別:

“Generate Getters and Setters..”只是會改變當前的類的代碼,而“Encapsulate Field...”則應改變與之相關的其它類的代碼。

舉個簡單的例子,有A,B,C三個類,其它A類中有一個public欄位field,B實現了 對這個欄位的引用,C則設定這個欄位。

重構前的代碼:

public class A

{

 public String field = "HI, I am feidao";

}

public class B

{

 public B()

 {

  A a = new A();

  String str = a.field;

 }

}

public class C

{

 public C()

 {

  A a = new A();

  a.field = "";

 }

}

對A類的field欄位進行“Encapsulate Field...”重構,重構後增加了get,set方法(在.Net中就是屬性),且欄位的public修飾符,改為private。重構後代碼為:

public class A

{

 private String field = "HI, I am feidao";

 /**

  * @param field The field to set.

  */

 public void setField(String field)

 {

  this.field = field;

 }

 /**

  * @return Returns the field.

  */

 public String getField()

 {

  return field;

 }

}

重構後,B類的引用代碼,則需要改為getField(),才能保證原有功能,當然這一切,開發工具,幫你自動幫你做了。

public class B

{

 public B()

 {

  A a = new A();

  String str = a.getField();

 }

}

同理C類,改為setField(),以改變此欄位的值:

public class C

{

 public C()

 {

  A a = new A();

  a.setField("");

 }

}

大家注意紅色字型,相信很直觀的了瞭解“Encapsulate Field...”真正作用。

重構是非常有用的東西(其實Source也是),相信2005出來後,會增加.Net兄弟們對重構的認識。

重構的內容很多,理解運用好重構,可以讓大家寫出一手漂亮的代碼。

有一本經典好書,就叫《重構》,英文原版忘記叫什麼名字了,中文版是由候大師翻譯的,裡面的內容都是Java寫的,但是 Java與C#文法差別不大,.Net的兄弟們不會存在看不懂的問題,當然極度反感Java的兄弟除外。

VB我就不太會,用VB.Net的兄弟們就不要挑我的刺了。

btw,運用,學好重構,首先還是得以設計模式為基礎,否則你都不知道重構的目標。

Source與重構: 前者是產生代碼結構,後者是改變代碼結構;一個方便快速寫代碼,另一個使代碼更加強壯,聞不到“壞味道”。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.