基本類型偏執(zhí)(Primitive Obsession)
成都創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)貴州,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18980820575
- 使用基本類型而不是小對(duì)象來(lái)實(shí)現(xiàn)簡(jiǎn)單任務(wù)(例如貨幣、范圍、電話號(hào)碼字符串等)。
- 使用常量編碼信息(例如一個(gè)用于引用管理員權(quán)限的常量
USER_ADMIN_ROLE = 1
)。- 使用字符串常量作為字段名在數(shù)組中使用。
類似其他大部分壞味道,基本類型偏執(zhí)誕生于類初建的時(shí)候。一開始,可能只是不多的字段,隨著表示的特性越來(lái)越多,基本數(shù)據(jù)類型字段也越來(lái)越多。
基本類型常常被用于表示模型的類型。你有一組數(shù)字或字符串用來(lái)表示某個(gè)實(shí)體。
還有一個(gè)場(chǎng)景:在模擬場(chǎng)景,大量的字符串常量被用于數(shù)組的索引。
大多數(shù)編程語(yǔ)言都支持基本數(shù)據(jù)類型和結(jié)構(gòu)類型(類、結(jié)構(gòu)體等)。結(jié)構(gòu)類型允許程序員將基本數(shù)據(jù)類型組織起來(lái),以代表某一事物的模型。
基本數(shù)據(jù)類型可以看成是機(jī)構(gòu)類型的積木塊。當(dāng)基本數(shù)據(jù)類型數(shù)量成規(guī)模后,將它們有組織地結(jié)合起來(lái),可以更方便的管理這些數(shù)據(jù)。
以類取代類型碼(Replace Type Code with Class)
。
引入?yún)?shù)對(duì)象(Introduce Parameter Object)
或
保持對(duì)象完整(Preserve Whole Object)
。
以類取代類型碼(Replace Type Code with Class)
將它替換掉。如果你有與類型碼相關(guān)的條件表達(dá)式,可運(yùn)用
以子類取代類型碼(Replace Type Code with Subclass)
或
以狀態(tài)/策略模式取代類型碼(Replace Type Code with State/Strategy)
加以處理。
以對(duì)象取代數(shù)組(Replace Array with Object)
。
問題
類之中有一個(gè)數(shù)值類型碼,但它并不影響類的行為。
解決
以一個(gè)新的類替換該數(shù)值類型碼。
問題
某些參數(shù)總是很自然地同時(shí)出現(xiàn)。
解決
以一個(gè)對(duì)象來(lái)取代這些參數(shù)。
問題
你從某個(gè)對(duì)象中取出若干值,將它們作為某一次函數(shù)調(diào)用時(shí)的參數(shù)。
int low = daysTempRange.getLow(); int high = daysTempRange.getHigh(); boolean withinPlan = plan.withinRange(low, high);
解決
改為傳遞整個(gè)對(duì)象。
boolean withinPlan = plan.withinRange(daysTempRange);
問題
你有一個(gè)不可變的類型碼,它會(huì)影響類的行為。
解決
以子類取代這個(gè)類型碼。
問題
你有一個(gè)類型碼,它會(huì)影響類的行為,但你無(wú)法通過繼承消除它。
解決
以狀態(tài)對(duì)象取代類型碼。
問題
你有一個(gè)數(shù)組,其中的元素各自代表不同的東西。
String[] row = new String[3]; row[0] = "Liverpool"; row[1] = "15";
解決
以對(duì)象替換數(shù)組。對(duì)于數(shù)組中的每個(gè)元素,以一個(gè)字段來(lái)表示。
Performance row = new Performance(); row.setName("Liverpool"); row.setWins("15");
數(shù)據(jù)泥團(tuán)(Data Clumps)
有時(shí),代碼的不同部分包含相同的變量組(例如用于連接到數(shù)據(jù)庫(kù)的參數(shù))。這些綁在一起出現(xiàn)的數(shù)據(jù)應(yīng)該擁有自己的對(duì)象。
通常,數(shù)據(jù)泥團(tuán)的出現(xiàn)時(shí)因?yàn)樵愀獾木幊探Y(jié)構(gòu)或“復(fù)制-粘貼式編程”。
有一個(gè)判斷是否是數(shù)據(jù)泥團(tuán)的好辦法:刪掉眾多數(shù)據(jù)中的一項(xiàng)。這么做,其他數(shù)據(jù)有沒有因而失去意義?如果它們不再有意義,這就是個(gè)明確的信號(hào):你應(yīng)該為它們產(chǎn)生一個(gè)新的對(duì)象。
提煉類(Extract Class)
將它們提煉到一個(gè)獨(dú)立對(duì)象中。
引入?yún)?shù)對(duì)象(Introduce Parameter Object)
將它們組織成一個(gè)類。
保持對(duì)象完整(Preserve Whole Object)
將整個(gè)數(shù)據(jù)對(duì)象傳入到函數(shù)中。
問題
某個(gè)類做了不止一件事。
解決
建立一個(gè)新類,將相關(guān)的字段和函數(shù)從舊類搬移到新類。
問題
某些參數(shù)總是很自然地同時(shí)出現(xiàn)。
解決
以一個(gè)對(duì)象來(lái)取代這些參數(shù)。
問題
你從某個(gè)對(duì)象中取出若干值,將它們作為某一次函數(shù)調(diào)用時(shí)的參數(shù)。
int low = daysTempRange.getLow(); int high = daysTempRange.getHigh(); boolean withinPlan = plan.withinRange(low, high);
解決
改為傳遞整個(gè)對(duì)象。
boolean withinPlan = plan.withinRange(daysTempRange);
過大的類(Large Class)
一個(gè)類含有過多字段、函數(shù)、代碼行。
類通常一開始很小,但是隨著程序的增長(zhǎng)而逐漸膨脹。
類似于過長(zhǎng)函數(shù),程序員通常覺得在一個(gè)現(xiàn)存類中添加新特性比創(chuàng)建一個(gè)新的類要容易。
設(shè)計(jì)模式中有一條重要原則:職責(zé)單一原則。一個(gè)類應(yīng)該只賦予它一個(gè)職責(zé)。如果它所承擔(dān)的職責(zé)太多,就該考慮為它減減負(fù)。
提煉類(Extract Class)
。
提煉子類(Extract Subclass)
。
提煉接口(Extract Interface)
。
復(fù)制被監(jiān)視數(shù)據(jù)(Duplicate Observed Data)
可以告訴你怎么做。
問題
某個(gè)類做了不止一件事。
解決
建立一個(gè)新類,將相關(guān)的字段和函數(shù)從舊類搬移到新類。
問題
一個(gè)類中有些特性僅用于特定場(chǎng)景。
解決
創(chuàng)建一個(gè)子類,并將用于特殊場(chǎng)景的特性置入其中。
問題
多個(gè)客戶端使用一個(gè)類部分相同的函數(shù)。另一個(gè)場(chǎng)景是兩個(gè)類中的部分函數(shù)相同。
解決
移動(dòng)相同的部分函數(shù)到接口中。
問題
如果存儲(chǔ)在類中的數(shù)據(jù)是負(fù)責(zé) GUI 的。
解決
一個(gè)比較好的方法是將負(fù)責(zé) GUI 的數(shù)據(jù)放入一個(gè)獨(dú)立的類,以確保 GUI 數(shù)據(jù)與域類之間的連接和同步。
過長(zhǎng)函數(shù)(Long Method)
一個(gè)函數(shù)含有太多行代碼。一般來(lái)說(shuō),任何函數(shù)超過 10 行時(shí),你就可以考慮是不是過長(zhǎng)了。 函數(shù)中的代碼行數(shù)原則上不要超過 100 行。
通常情況下,創(chuàng)建一個(gè)新函數(shù)的難度要大于添加功能到一個(gè)已存在的函數(shù)。大部分人都覺得:“我就添加這么兩行代碼,為此新建一個(gè)函數(shù)實(shí)在是小題大做了。”于是,張三加兩行,李四加兩行,王五加兩行。。。函數(shù)日益龐大,最終爛的像一鍋漿糊,再也沒人能完全看懂了。于是大家就更不敢輕易動(dòng)這個(gè)函數(shù)了,只能惡性循環(huán)的往其中添加代碼。所以,如果你看到一個(gè)超過 200 行的函數(shù),通常都是多個(gè)程序員東拼西湊出來(lái)的。
一個(gè)很好的技巧是: 尋找注釋 。添加注釋,一般有這么幾個(gè)原因:代碼邏輯較為晦澀或復(fù)雜;這段代碼功能相對(duì)獨(dú)立;特殊處理。 如果代碼前方有一行注釋,就是在提醒你:可以將這段代碼替換成一個(gè)函數(shù),而且可以在注釋的基礎(chǔ)上給這個(gè)函數(shù)命名。如果函數(shù)有一個(gè)描述恰當(dāng)?shù)拿郑筒恍枰タ磧?nèi)部代碼究竟是如何實(shí)現(xiàn)的。就算只有一行代碼,如果它需要以注釋來(lái)說(shuō)明,那也值得將它提煉到獨(dú)立函數(shù)中。
提煉函數(shù)(Extract Method)
。
以查詢?nèi)〈R時(shí)變量(Replace Temp with Query)
,
引入?yún)?shù)對(duì)象(Introduce Parameter Object)
或
保持對(duì)象完整(Preserve Whole Object)
。
以函數(shù)對(duì)象取代函數(shù)(Replace Method with Method Object)
嘗試移動(dòng)整個(gè)函數(shù)到一個(gè)獨(dú)立的對(duì)象中。
分解條件表達(dá)式(Decompose Conditional)
。至于循環(huán),應(yīng)該使用
提煉函數(shù)(Extract Method)
將循環(huán)和其內(nèi)的代碼提煉到獨(dú)立函數(shù)中。
是否像許多人說(shuō)的那樣,增加函數(shù)的數(shù)量會(huì)影響性能?在幾乎絕大多數(shù)情況下,這種影響是可以忽略不計(jì),所以不用擔(dān)心。 此外,現(xiàn)在有了清晰和易讀的代碼,在需要的時(shí)候,你將更容易找到真正有效的函數(shù)來(lái)重組代碼和提高性能。
問題
你有一段代碼可以組織在一起。
void printOwing() { printBanner(); //print details System.out.println("name: " + name); System.out.println("amount: " + getOutstanding()); }
解決
移動(dòng)這段代碼到一個(gè)新的函數(shù)中,使用函數(shù)的調(diào)用來(lái)替代老代碼。
void printOwing() { printBanner(); printDetails(getOutstanding()); } void printDetails(double outstanding) { System.out.println("name: " + name); System.out.println("amount: " + outstanding); }
問題
將表達(dá)式的結(jié)果放在局部變量中,然后在代碼中使用。
double calculateTotal() { double basePrice = quantity * itemPrice; if (basePrice > 1000) { return basePrice * 0.95; } else { return basePrice * 0.98; } }
解決
將整個(gè)表達(dá)式移動(dòng)到一個(gè)獨(dú)立的函數(shù)中并返回結(jié)果。使用查詢函數(shù)來(lái)替代使用變量。如果需要,可以在其他函數(shù)中合并新函數(shù)。
double calculateTotal() { double basePrice = quantity * itemPrice; if (basePrice > 1000) { return basePrice * 0.95; } else { return basePrice * 0.98; } }
問題
某些參數(shù)總是很自然地同時(shí)出現(xiàn)。
解決
以一個(gè)對(duì)象來(lái)取代這些參數(shù)。
問題
你從某個(gè)對(duì)象中取出若干值,將它們作為某一次函數(shù)調(diào)用時(shí)的參數(shù)。
int low = daysTempRange.getLow(); int high = daysTempRange.getHigh(); boolean withinPlan = plan.withinRange(low, high);
解決
改為傳遞整個(gè)對(duì)象。
boolean withinPlan = plan.withinRange(daysTempRange);
問題
你有一個(gè)過長(zhǎng)函數(shù),它的局部變量交織在一起,以致于你無(wú)法應(yīng)用提煉函數(shù)(Extract Method) 。
class Order { //... public double price() { double primaryBasePrice; double secondaryBasePrice; double tertiaryBasePrice; // long computation. //... } }
解決
將函數(shù)移到一個(gè)獨(dú)立的類中,使得局部變量成了這個(gè)類的字段。然后,你可以將函數(shù)分割成這個(gè)類中的多個(gè)函數(shù)。
class Order { //... public double price() { return new PriceCalculator(this).compute(); } } class PriceCalculator { private double primaryBasePrice; private double secondaryBasePrice; private double tertiaryBasePrice; public PriceCalculator(Order order) { // copy relevant information from order object. //... } public double compute() { // long computation. //... } }
問題
你有復(fù)雜的條件表達(dá)式。
if (date.before(SUMMER_START) || date.after(SUMMER_END)) { charge = quantity * winterRate + winterServiceCharge; } else { charge = quantity * summerRate; }
解決
根據(jù)條件分支將整個(gè)條件表達(dá)式分解成幾個(gè)函數(shù)。
if (notSummer(date)) { charge = winterCharge(quantity); } else { charge = summerCharge(quantity); }
過長(zhǎng)參數(shù)列(Long Parameter List)
一個(gè)函數(shù)有超過 3、4 個(gè)入?yún)ⅰ?/p>
過長(zhǎng)參數(shù)列可能是將多個(gè)算法并到一個(gè)函數(shù)中時(shí)發(fā)生的。函數(shù)中的入?yún)⒖梢杂脕?lái)控制最終選用哪個(gè)算法去執(zhí)行。
過長(zhǎng)參數(shù)列也可能是解耦類之間依賴關(guān)系時(shí)的副產(chǎn)品。例如,用于創(chuàng)建函數(shù)中所需的特定對(duì)象的代碼已從函數(shù)移動(dòng)到調(diào)用函數(shù)的代碼處,但創(chuàng)建的對(duì)象是作為參數(shù)傳遞到函數(shù)中。因此,原始類不再知道對(duì)象之間的關(guān)系,并且依賴性也已經(jīng)減少。但是如果創(chuàng)建的這些對(duì)象,每一個(gè)都將需要它自己的參數(shù),這意味著過長(zhǎng)參數(shù)列。
太長(zhǎng)的參數(shù)列難以理解,太多參數(shù)會(huì)造成前后不一致、不易使用,而且一旦需要更多數(shù)據(jù),就不得不修改它。
以函數(shù)取代參數(shù)(Replace Parameter with Methods)
。在這里,,“已有的對(duì)象”可能是函數(shù)所屬類里的一個(gè)字段,也可能是另一個(gè)參數(shù)。
保持對(duì)象完整(Preserve Whole Object)
將來(lái)自同一對(duì)象的一堆數(shù)據(jù)收集起來(lái),并以該對(duì)象替換它們。
引入?yún)?shù)對(duì)象(Introduce Parameter Object)
為它們制造出一個(gè)“參數(shù)對(duì)象”。
問題
對(duì)象調(diào)用某個(gè)函數(shù),并將所得結(jié)果作為參數(shù),傳遞給另一個(gè)函數(shù)。而接受該參數(shù)的函數(shù)本身也能夠調(diào)用前一個(gè)函數(shù)。
int basePrice = quantity * itemPrice; double seasonDiscount = this.getSeasonalDiscount(); double fees = this.getFees(); double finalPrice = discountedPrice(basePrice, seasonDiscount, fees);
解決
讓參數(shù)接受者去除該項(xiàng)參數(shù),并直接調(diào)用前一個(gè)函數(shù)。
int basePrice = quantity * itemPrice; double finalPrice = discountedPrice(basePrice);
問題
你從某個(gè)對(duì)象中取出若干值,將它們作為某一次函數(shù)調(diào)用時(shí)的參數(shù)。
int low = daysTempRange.getLow(); int high = daysTempRange.getHigh(); boolean withinPlan = plan.withinRange(low, high);
解決
改為傳遞整個(gè)對(duì)象。
boolean withinPlan = plan.withinRange(daysTempRange);
問題
某些參數(shù)總是很自然地同時(shí)出現(xiàn)。
解決
以一個(gè)對(duì)象來(lái)取代這些參數(shù)。
當(dāng)前名稱:怎么讓代碼不再臃腫,寫的像詩(shī)一樣優(yōu)雅-創(chuàng)新互聯(lián)
鏈接URL:http://www.rwnh.cn/article38/pccpp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、關(guān)鍵詞優(yōu)化、自適應(yīng)網(wǎng)站、微信公眾號(hào)、域名注冊(cè)、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容