返回總目錄 本小節目錄 Extract Class(提煉類) Inline Class(將類內聯化) 3Extract Class(提煉類) 概要 某個類做了應該由兩個類做的事。 建立一個新類,將相關的欄位和函數從舊類搬移到新類。 動機 如果一個類中有大量的函數和數據,這個類往往太大而且不易理解。這 ...
本小節目錄
3Extract Class(提煉類)
概要
某個類做了應該由兩個類做的事。
建立一個新類,將相關的欄位和函數從舊類搬移到新類。
動機
如果一個類中有大量的函數和數據,這個類往往太大而且不易理解。這時候就需要考慮哪些部分可以分離出去,並將它們分離到一個單獨的類中。
如果發現子類化隻影響類的部分特性,或如果某些特性需要以一種方式來子類化,某些特性則需要以另一種方式子類化,這也意味著需要分解原來的類。
範例
先看一個簡單的Person類。
class Person { public string Name { get; set; } public string OfficeAreaCode { get; set; } public string OfficeNumber { get; set; } public string GetTelephoneNumber() { return $"({OfficeAreaCode})-{OfficeNumber}"; } }
在這裡,我們可以將與電話號碼有關的行為分離到一個獨立的類中。
首先,定義一個TelePhoneNumber類表示“電話號碼”:
class TelePhoneNumber{}
然後,在Person類中建立從Person到TelePhoneNumber的連接:
private TelePhoneNumber _phoneNumber = new TelePhoneNumber();
現在運用Move Field移動屬性,並運用Move Method將相關函數移動到TelePhoneNumber類中。
class Person { private TelePhoneNumber _phoneNumber = new TelePhoneNumber(); public string Name { get; set; } public string GetTelephoneNumber() { return _phoneNumber.GetTelephoneNumber(); } }
class TelePhoneNumber { public string OfficeAreaCode { get; set; } public string OfficeNumber { get; set; } public string GetTelephoneNumber() { return $"({OfficeAreaCode})-{OfficeNumber}"; } }
小結
類的單一原則表示:一個類應該是一個清楚的抽象,處理一些明確的責任。如果一個類做了兩個類的事,那它就該被提煉了。
4Inline Class(將類內聯化)
概要
某個類沒有做太多事情。
將這個類的所有特性搬移到另一個類中,然後移除原類。
動機
Inline Class和Extract Class正好相反。如果一個類不再承擔足夠責任、不再有單獨存在的理由,那麼就將其塞進另一個類中。
範例
第3節中我們提煉出一個TelePhoneNumber類,現在我們將其塞回Person中。
class Person { private TelePhoneNumber _phoneNumber = new TelePhoneNumber(); public string Name { get; set; } public string GetTelephoneNumber() { return _phoneNumber.GetTelephoneNumber(); } } class TelePhoneNumber { public string OfficeAreaCode { get; set; } public string OfficeNumber { get; set; } public string GetTelephoneNumber() { return $"({OfficeAreaCode})-{OfficeNumber}"; } }
首先,在Person中聲明TelePhoneNumber的所有public的函數。
class Person { private TelePhoneNumber _phoneNumber = new TelePhoneNumber(); public string Name { get; set; } public string OfficeAreaCode { get; set; } public string OfficeNumber { get; set; } public string GetTelephoneNumber() { return _phoneNumber.GetTelephoneNumber(); } public TelePhoneNumber GetOfficeTelePhoneNumber() { return _phoneNumber; } }
現在,我們要做的就是:找出所有使用TelePhoneNumber的地方,讓它們使用Person的介面。於是,下列代碼:
Person martin=new Person(); martin.GetOfficeTelePhoneNumber().OfficeAreaCode = "781";
就變成了:
Person martin=new Person(); martin.OfficeAreaCode = "781";
最後,反覆使用Move Method和Move Field,直到TelePhoneNumber類不復存在。
小結
如果一個類無所事事,那麼這就是一種壞味道——Lazy Class。遇到這種類,我們應該毫不猶豫的為它舉行“葬禮”,將它塞進其他類中。
To Be Continued……