日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

C#:如何将坏的代码重新编译为好的代码

發(fā)布時(shí)間:2023/12/4 C# 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#:如何将坏的代码重新编译为好的代码 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

自己的前言說(shuō)明:

?本文原作者:Radoslaw Sadowski,原文鏈接為:C# BAD PRACTICES: Learn how to make a good code by bad example。

本系列還有其他文章,后續(xù)將慢慢翻譯。

?

引言:

我的名字叫Radoslaw Sadowski,我現(xiàn)在是一個(gè)微軟技術(shù)開(kāi)發(fā)人員。我從開(kāi)始工作時(shí)就一直接觸的微軟技術(shù).

在工作一年后,我看到的質(zhì)量很差的代碼的數(shù)量基本上都可以寫(xiě)成一整本書(shū)了。

這些經(jīng)歷讓我變成了一個(gè)想要清潔代碼的強(qiáng)迫癥患者。

寫(xiě)這篇文章的目的是為了通過(guò)展示質(zhì)量很差的類(lèi)的例子來(lái)說(shuō)明如何書(shū)寫(xiě)出干凈的、可延伸的和可維護(hù)的代碼。我會(huì)通過(guò)好的書(shū)寫(xiě)方式和設(shè)計(jì)模式來(lái)解釋壞的代碼帶來(lái)的問(wèn)題,以及替換他的好的解決方法。

第一部分是針對(duì)那些擁有C#基礎(chǔ)知識(shí)的開(kāi)發(fā)人員——我會(huì)展示一些常見(jiàn)的錯(cuò)誤,然后再展示一些讓代碼變得可讀性的方法與技巧。高級(jí)部分主要針對(duì)那些至少擁有設(shè)計(jì)模式概念的開(kāi)發(fā)人員——我將會(huì)展示完全干凈的、單元可測(cè)試的代碼。

為了能夠理解這篇文章你需要至少掌握以下兩個(gè)部分的基本知識(shí):

  • C#語(yǔ)言

  • 依賴(lài)注入、工廠(chǎng)設(shè)計(jì)模式、策略設(shè)計(jì)模式

本文中所涉及的例子都將會(huì)是現(xiàn)實(shí)中實(shí)實(shí)在在的具體的特性,而不是用裝飾模式來(lái)做披薩或者用策略模式來(lái)做計(jì)算器這樣的示例。

(ps解釋:看過(guò)設(shè)計(jì)模式相關(guān)的書(shū)籍的人應(yīng)該會(huì)知道很多這方面的書(shū)籍都是用這種例子,只是為了幫助讀者理解設(shè)計(jì)模式)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? ? ? ? ??

因?yàn)槲野l(fā)現(xiàn)這種類(lèi)型的產(chǎn)品不好用來(lái)解釋,相反這些理論性的例子卻是非常適合用來(lái)在本文中做解釋的。

我們常常會(huì)聽(tīng)到說(shuō)不要用這個(gè),要用那個(gè),但是卻不知道這種替換的理由。今天我將會(huì)努力解釋和證明那些好的書(shū)寫(xiě)習(xí)慣以及設(shè)計(jì)模式是真的是在拯救我們的開(kāi)發(fā)生活!

?提示:

  • ?在本文中我不會(huì)花時(shí)間來(lái)講解C#的特性和涉及模式之類(lèi)(我也解釋不完),網(wǎng)上有很多關(guān)于這方面的好的理論的例子。我將集中講述如何在我們?nèi)粘9ぷ髦惺褂眠@些東西。

  • 例子是一種比較容易的突出我們要說(shuō)明的問(wèn)題的方法,但是僅限于描述的問(wèn)題——因?yàn)槲野l(fā)現(xiàn)當(dāng)我在學(xué)習(xí)哪些包含著主要代碼的例子時(shí),我發(fā)現(xiàn)在理解文章的總體思想方面會(huì)有困難。

  • ?我不是說(shuō)我文中說(shuō)的方法是惟一的解決方式,我只是能保證這些方法將會(huì)是讓你的代碼變得更高質(zhì)量的途徑。

  • 我并不關(guān)心下面這些代碼的什么錯(cuò)誤處理,日志記錄等等。我要表述的只是用來(lái)解決日常編碼一些問(wèn)題的方法。

那就開(kāi)始吧….

那些糟糕透了的類(lèi)...

下面的例子是我們現(xiàn)實(shí)中的類(lèi):

上面這個(gè)例子真的是一種非常差的書(shū)寫(xiě)方式。你能知道這個(gè)類(lèi)是用來(lái)干嘛的么?這個(gè)東西是用來(lái)做一些奇怪的運(yùn)算的么?我們文章就從他開(kāi)始入手來(lái)講解吧

現(xiàn)在我來(lái)告訴你,剛剛那個(gè)類(lèi)是用來(lái)當(dāng)顧客在網(wǎng)上買(mǎi)東西的時(shí)候?yàn)樗麄冇?jì)算對(duì)應(yīng)折扣的折扣計(jì)算和管理的類(lèi)。

-難以置信吧!

-可是這是真的!

這種寫(xiě)法真的是將難以閱讀、難以維護(hù)和難以擴(kuò)展這三種集合在一起了,而且擁有著太差的書(shū)寫(xiě)習(xí)慣和錯(cuò)誤的模式。

除此之外還有其他什么問(wèn)題么?

1.命名方式-從源代碼中我們可以連蒙帶猜估計(jì)出來(lái)這個(gè)計(jì)算方法和輸出結(jié)果是什么。而且我們想要從這個(gè)類(lèi)中提取計(jì)算算法將會(huì)是一件非常困難的事情。

這樣帶來(lái)的危害是:

最嚴(yán)重的問(wèn)題是:浪費(fèi)時(shí)間,

?

如果我們需要滿(mǎn)足客戶(hù)的商業(yè)咨詢(xún),要像他們展示算法細(xì)節(jié),或者我們需要修改這段代碼,這將花費(fèi)我們很長(zhǎng)的時(shí)間去理解我們的計(jì)算方法的邏輯。即使我們不記錄他或重構(gòu)代碼,下次我們/其他開(kāi)發(fā)人員再看這段代碼的時(shí)候,還是需要花費(fèi)同等的時(shí)間來(lái)研究這些代碼是干嘛的。而且在修改的同時(shí)還容易出錯(cuò),導(dǎo)致原來(lái)的計(jì)算全部出錯(cuò)。

?2.魔法數(shù)字

?

在這個(gè)例子中type是變量,你能猜到它代表著客戶(hù)賬戶(hù)的等級(jí)么?If-else if語(yǔ)句是用來(lái)實(shí)現(xiàn)如何選擇計(jì)算出產(chǎn)品價(jià)格折扣的方法。

現(xiàn)在我們不知道什么樣的賬戶(hù)是1,2,3或4。現(xiàn)在想象一下,當(dāng)你不得不為了那些有價(jià)值的VIP客戶(hù)改變他們的折扣計(jì)算方式的時(shí)候,你試著從那些代碼中找出修改的方法---這個(gè)過(guò)程可能會(huì)花費(fèi)你很長(zhǎng)的時(shí)間不說(shuō),還很有可能犯錯(cuò)以至于修改那些基礎(chǔ)的一般的客戶(hù)的賬戶(hù),畢竟像2或者3這些詞語(yǔ)毫無(wú)描述性的。但是在我們犯錯(cuò)以后,那些一般的客戶(hù)卻很高興,因?yàn)樗麄兊玫搅薞IP客戶(hù)的折扣。:)

3.沒(méi)有明顯的bug

因?yàn)槲覀兊拇a質(zhì)量很差,而且可讀性非常差,所以我們可能輕易就忽略掉很多非常重要的事情。想象一下,現(xiàn)在突然在系統(tǒng)中增加一種新的客戶(hù)類(lèi)型-金卡用戶(hù),而在我們的系統(tǒng)中任何一種新的賬戶(hù)類(lèi)型最后獲得的價(jià)格將是0元。為什么呢?因?yàn)樵谖覀兊?strong>if-else if語(yǔ)句中沒(méi)有任何狀態(tài)是滿(mǎn)足新的狀態(tài)的,所以只要是未處理過(guò)的賬戶(hù)類(lèi)型,最后返回值都將變成0。一旦我們的老板發(fā)現(xiàn)這件事,他將會(huì)大發(fā)雷霆-畢竟他已經(jīng)免費(fèi)賣(mài)給這樣用戶(hù)很多很多東西了!

4.沒(méi)有可讀性

我們必須承認(rèn)上面這段代碼的可讀性是真的糟糕。

她讓我們花費(fèi)了太多的時(shí)間去理解這段代碼,同時(shí)代碼隱藏錯(cuò)誤的幾率太大了,而這就是沒(méi)有可讀性的最重要的定義。

?5.魔法數(shù)字(再次)

你從代碼中能知道類(lèi)似0.1,0.7,0.5這些數(shù)字的意思么?好的,我承認(rèn)我不知道。只有我們自己編寫(xiě)這些代碼我們才知道這是什么意思,別人是無(wú)法理解的。

你試試想想如果讓你修改下面這句代碼,你會(huì)怎么樣:

result = (amount - (0.5m * amount)) - disc * (amount - (0.5m * amount));

因?yàn)檫@個(gè)方法完全不可讀,所以你修改的過(guò)程中只能?chē)L試著把第一個(gè)0.5改成0.4而保持第二個(gè)0.5不懂。這可能會(huì)是一個(gè)bug,但是卻是最好的最合適的修改方式。因?yàn)檫@個(gè)0.5什么都沒(méi)有告訴我們。

同樣的事也存在將years變量轉(zhuǎn)換到disc變量的轉(zhuǎn)換過(guò)程中

decimal disc = (years > 5) ? (decimal)5/100 : (decimal)years/100;

這是用來(lái)計(jì)算折扣率的,會(huì)通過(guò)賬戶(hù)在我們系統(tǒng)的時(shí)間的百分比來(lái)獲取。好的,那么現(xiàn)在問(wèn)題來(lái)了,如果時(shí)間剛剛好就是5呢?

6.簡(jiǎn)潔-不要反復(fù)做無(wú)用功

雖然第一眼看的時(shí)候不容易看出來(lái),但是仔細(xì)研究一下就會(huì)發(fā)現(xiàn):我們的代碼里有很多重復(fù)的地方。例如:disc?* (amount - (0.1m * amount));

而與之有同樣效果的還有(只是變了一個(gè)參數(shù)而已):disc?* (amount - (0.5m * amount))

在這兩個(gè)算術(shù)中,唯一的區(qū)別就只是一個(gè)靜態(tài)參數(shù),而我們完全可以用一個(gè)可變的參數(shù)來(lái)替代。

如果我們不試著在寫(xiě)代碼的時(shí)候從一直ctri+c,ctrl+v中擺脫出來(lái),那我們將遇到的問(wèn)題就是我們只能修改代碼中的部分功能,因?yàn)槲覀儾恢烙卸嗌俚胤叫枰薷摹I厦娴倪壿嬍怯?jì)算出在我們系統(tǒng)中每個(gè)客戶(hù)對(duì)應(yīng)年限獲得的折扣,所以如果我們只是貿(mào)然修改兩到三處,很容易造成其他地方的前后不一致。

7.每個(gè)類(lèi)有著太多的復(fù)雜的責(zé)任區(qū)域

我們寫(xiě)的類(lèi)至少背負(fù)了三個(gè)責(zé)任:

  • 選擇計(jì)算的運(yùn)算法則

  • 為每個(gè)不同狀態(tài)的賬戶(hù)計(jì)算折扣率

  • 根據(jù)每個(gè)客人的年限計(jì)算出對(duì)應(yīng)的折扣率

  • 這個(gè)違背了單一責(zé)任原則。那么這會(huì)帶來(lái)什么危害呢?如果我們想要改變上訴3個(gè)特性中的兩個(gè),那就意味著可能會(huì)碰觸到一些其他的我們并不想修改的特性。所以在修改的時(shí)候我們不得不重新測(cè)試所有的類(lèi),那么這就造成了很重的時(shí)間的浪費(fèi)。

    那就開(kāi)始重構(gòu)吧…

    在接下來(lái)的9個(gè)步驟中我將向你展示我們?nèi)绾伪苊馍显V問(wèn)題來(lái)構(gòu)建一個(gè)干凈的易維護(hù),同時(shí)又方便單元測(cè)試的看起來(lái)一目了然的代碼。

    ?

    I:命名,命名,命名

    恕我直言,這是代碼中最重要的一步。我們只是修改方法/參數(shù)/變量這些的名字,而現(xiàn)在我們可以直觀的了解到下面這個(gè)類(lèi)代表什么意思。

    雖然如此,我們還是不理解1,2,3,4代表著什么,那就繼續(xù)往下吧!

    II:魔法數(shù)

    C#中避免出現(xiàn)不理解的魔法數(shù)的方法是通過(guò)枚舉來(lái)替代。我通過(guò)枚舉方法來(lái)替代在if-else if?語(yǔ)句中出現(xiàn)的代替賬戶(hù)狀態(tài)的魔法數(shù)。

    現(xiàn)在在看我們重構(gòu)了的類(lèi),我們可以很容易的說(shuō)出那個(gè)計(jì)算法則是用來(lái)根據(jù)不用狀態(tài)來(lái)計(jì)算折扣率的。將賬戶(hù)狀態(tài)弄混的幾率就大幅度減少了。

    III:更多的可讀性

    在這一步中我們將通過(guò)將if-else if?語(yǔ)句改為switch-case?語(yǔ)句,來(lái)增加文章的可讀性。

    同時(shí),我也將一個(gè)很長(zhǎng)的計(jì)算方法拆分為兩句話(huà)來(lái)寫(xiě)。現(xiàn)在我們將“ 通過(guò)賬戶(hù)狀態(tài)來(lái)計(jì)算折扣率”與“通過(guò)賬戶(hù)年限來(lái)計(jì)算折扣率”這兩者分開(kāi)來(lái)計(jì)算。

    例如:priceAfterDiscount = (price - (0.5m * price)) - (discountForLoyaltyInPercentage * (price - (0.5m * price)));

    我們將它重構(gòu)為:priceAfterDiscount = (price - (0.5m * price));
    priceAfterDiscount = priceAfterDiscount - (discountForLoyaltyInPercentage * priceAfterDiscount);

    這就是修改后的代碼:

    IV:沒(méi)有明顯的bug

    我們終于找到我們隱藏的bug了!

    因?yàn)槲覄倓偺岬降奈覀兊姆椒ㄖ袑?duì)于不適合的賬戶(hù)狀態(tài)會(huì)在造成對(duì)于所有商品最后都返回0。雖然很不幸,但卻是真的。

    那我們?cè)撊绾涡迯?fù)這個(gè)問(wèn)題呢?那就只有通過(guò)沒(méi)有錯(cuò)誤提示了。

    你是不是會(huì)想,這個(gè)會(huì)不會(huì)是開(kāi)發(fā)的例外,應(yīng)該不會(huì)被提交到錯(cuò)誤提示中去?不,他會(huì)的!

    當(dāng)我們的方法通過(guò)獲取賬戶(hù)狀態(tài)作為參數(shù)的時(shí)候,我們并不想程序讓我們不可預(yù)知的方向發(fā)展,造成不可預(yù)計(jì)的失誤。

    ?這種情況是絕對(duì)不允許出現(xiàn)的,所以我們必須通過(guò)拋出異常來(lái)防止這種情況。

    下面的代碼就是通過(guò)拋出異常后修改的以防止出現(xiàn)不滿(mǎn)足條件的情況-修改方式是將拋出異常防止?switch-case語(yǔ)句中的default?句中。

    V:分析計(jì)算方法

    在我們的例子中我們有兩個(gè)定義給客戶(hù)的折扣率的標(biāo)準(zhǔn):

  • 賬戶(hù)狀態(tài);

  • 賬戶(hù)在我們系統(tǒng)中存在的年限

  • 對(duì)于年限的計(jì)算折扣率的方法,所有的計(jì)算方法都有點(diǎn)類(lèi)似:

    (discountForLoyaltyInPercentage * priceAfterDiscount)

    當(dāng)然,也還是存在例外的:0.7m * price

    所以我們把這個(gè)改成這樣:price - (0.3m * price)

    現(xiàn)在我們將整理所有通過(guò)賬戶(hù)狀態(tài)的計(jì)算方法改為同一種格式:price - ((static_discount_in_percentages/100) * price)

    VI:通過(guò)其他方式再擺脫魔法數(shù)

    接下來(lái)讓我們的目光放在通過(guò)賬戶(hù)狀態(tài)計(jì)算折扣率的計(jì)算方法中的靜態(tài)變量:(static_discount_in_percentages/100)

    然后帶入下面數(shù)字距離試試:0.1m,0.3m,0.5m

    這些數(shù)字其實(shí)也是一種類(lèi)型的魔法數(shù)-他們也沒(méi)有直接告訴我們他們代表著什么。

    我們也有同樣的情況,比如將“有賬戶(hù)的時(shí)間”折價(jià)為“忠誠(chéng)折扣”。

    decimal discountForLoyaltyInPercentage = (timeOfHavingAccountInYears > 5) ? (decimal)5/100 : (decimal)timeOfHavingAccountInYears/100;

    數(shù)字5讓我們的代碼變得神秘了起來(lái)。

    我們必須做些什么讓這個(gè)變得更具表現(xiàn)性。

    我會(huì)用另外一種方法來(lái)避免魔法數(shù)的表述的出現(xiàn)-也就是C#中的常量(關(guān)鍵詞是const),我強(qiáng)烈建議在我們的應(yīng)用程序中專(zhuān)門(mén)定義一個(gè)靜態(tài)類(lèi)來(lái)存儲(chǔ)這些常量。

    在我們的例子中,我是創(chuàng)建了下面的類(lèi):

    經(jīng)過(guò)一定的修改,我們的DiscountManager類(lèi)就變成了這樣了:

    我希望你也認(rèn)同我這個(gè)方法會(huì)更加使代碼自身變得更具有說(shuō)明性:)

    VII:不要再重復(fù)啦!

    ?

    我們可以通過(guò)分拆算法的方式來(lái)移動(dòng)我們的計(jì)算方法,而不是僅僅簡(jiǎn)單的復(fù)制代碼。

    我們會(huì)通過(guò)擴(kuò)展方法。

    首先我們會(huì)創(chuàng)建兩個(gè)擴(kuò)展方法。

    正如方法的名字一般,我不再需要單獨(dú)解釋一次他們的功能是什么。現(xiàn)在就開(kāi)始在我們的例子中使用這些代碼吧:

    擴(kuò)展方法讓代碼看起來(lái)更加友善了,但是這個(gè)代碼還是靜態(tài)的類(lèi),所以會(huì)讓你單元測(cè)試的時(shí)候遇到困難,甚至不可能。那么出于擺脫這個(gè)問(wèn)題的打算我們?cè)谧詈笠徊絹?lái)解決這個(gè)問(wèn)題。我將展示這些是如何簡(jiǎn)化我們的工作生活的。但是對(duì)于我個(gè)人而言,我喜歡,但是并不算是熱衷粉。

    不管怎樣,你現(xiàn)在同意我們的代碼看起來(lái)友善多了這一點(diǎn)么?

    那我們就繼續(xù)下去吧!

    VIII:移除那些多余的代碼

    在寫(xiě)代碼的時(shí)候原則上是我們的代碼越是精簡(jiǎn)越好。精簡(jiǎn)的代碼的意味著,越少的錯(cuò)誤的可能性,在閱讀理解代碼邏輯的時(shí)候花費(fèi)的時(shí)間越少。

    所以現(xiàn)在開(kāi)始精簡(jiǎn)我們的代碼吧。

    我們可以輕易發(fā)現(xiàn)我們?nèi)N客戶(hù)賬戶(hù)下有著相同的方法:

    .ApplyDiscountForTimeOfHavingAccount(timeOfHavingAccountInYears);

    我們可不可以只寫(xiě)一次呢?我們之前將未注冊(cè)的用戶(hù)放在了拋出異常中,因?yàn)槲覀兊恼劭勐手粫?huì)計(jì)算注冊(cè)用戶(hù)的年限,并沒(méi)有給未注冊(cè)用戶(hù)留有功能設(shè)定。所以,我們應(yīng)該給未注冊(cè)用戶(hù)設(shè)定的時(shí)間為多少呢? -0年

    那么對(duì)應(yīng)的折扣率也將變成0了,這樣我們就可以安全的將折扣率交付給未注冊(cè)用戶(hù)使用了,那就開(kāi)始吧!

    我們還可以將這一行移除到switch-case語(yǔ)句外面。好處就是:更少的代碼量!

    IX:提高-最后的得到干凈整潔的代碼

    好了,現(xiàn)在我們可以像閱讀一本書(shū)一樣方便來(lái)審視我們的代碼了,但是這就夠了么?我們可以將代碼變得超級(jí)精簡(jiǎn)的!

    好的,那就開(kāi)始做一些改變來(lái)實(shí)現(xiàn)這個(gè)目標(biāo)吧。我們可以使用依賴(lài)注入和使用策略模式這兩種方式。

    這就是我們今天最后整理出來(lái)的代碼了:

    首先我們擺脫了擴(kuò)展方法(也就是靜態(tài)類(lèi)),之所以要擺脫這種是因?yàn)閿U(kuò)展方法與折扣計(jì)算方法之間存在了緊耦合的關(guān)系。如果我們想要單元測(cè)試我們的方法ApplyDiscount的時(shí)候?qū)⒆兊貌惶菀?#xff0c;因?yàn)槲覀儽仨毥y(tǒng)一測(cè)試與之緊密關(guān)聯(lián)的類(lèi)PriceExtensions

    為了避免這個(gè),我創(chuàng)建了DefaultLoyaltyDiscountCalculator?類(lèi),這里面包含了ApplyDiscountForTimeOfHavingAccount擴(kuò)展方法,同事我通過(guò)抽象接口ILoyaltyDiscountCalculator隱藏了她的具體實(shí)現(xiàn)。現(xiàn)在,當(dāng)我想測(cè)試我們的類(lèi)DiscountManager的時(shí)候,我就可以通過(guò)?ILoyaltyDiscountCalculator模擬注入虛構(gòu)對(duì)象到DiscountManager類(lèi)中通過(guò)構(gòu)造函數(shù)顯示測(cè)試功能。這里我們運(yùn)用的就叫依賴(lài)注入模式。

    在做這個(gè)的同時(shí),我們也將計(jì)算折扣率這個(gè)功能安全的移交到另一個(gè)不同的類(lèi)中,如果我們想要修改這一段的邏輯,那我們就只需要修改DefaultLoyaltyDiscountCalculator?類(lèi)就好了,而不需要改動(dòng)其他的地方,這樣減少了在改動(dòng)他的時(shí)候產(chǎn)生破壞其他地方的風(fēng)險(xiǎn),同時(shí)也不需要再增加單獨(dú)測(cè)試的時(shí)間了。

    下面是我們?cè)?strong>DiscountManager類(lèi)中使用分開(kāi)的邏輯類(lèi):

    priceAfterDiscount = _loyaltyDiscountCalculator.ApplyDiscount(priceAfterDiscount, timeOfHavingAccountInYears);

    為了針對(duì)賬戶(hù)狀態(tài)的邏輯來(lái)計(jì)算折扣率,我創(chuàng)建了一些比較復(fù)雜的東西。我們?cè)?strong>DiscountManager類(lèi)中有兩個(gè)責(zé)任需要分解出去。

  • 根據(jù)賬戶(hù)狀態(tài)如何選擇對(duì)應(yīng)的計(jì)算方法。

  • 特殊計(jì)算方法的細(xì)節(jié)

  • 為了將第一個(gè)責(zé)任移交出去,我創(chuàng)建了工廠(chǎng)類(lèi)(DefaultAccountDiscountCalculatorFactory),為了實(shí)現(xiàn)工廠(chǎng)模式,然后再把這個(gè)隱藏到抽象IAccountDiscountCalculatorFactory里面去。

    我們的工廠(chǎng)會(huì)決定選擇哪種計(jì)算方法。最后我們通過(guò)依賴(lài)注冊(cè)模式構(gòu)造函數(shù)將工廠(chǎng)模式注射到DiscountManager類(lèi)中

    下面就是運(yùn)用了工廠(chǎng)的DiscountManager類(lèi):

    priceAfterDiscount = _factory.GetAccountDiscountCalculator(accountStatus).ApplyDiscount(price);

    ?以上會(huì)針對(duì)不同的賬戶(hù)狀態(tài)返回何時(shí)的策略,然后調(diào)用ApplyDiscount?方法。

    第一個(gè)責(zé)任已經(jīng)被交接出去了,接下來(lái)就是第二個(gè)了。

    ?接下來(lái)我們就開(kāi)始討論策略了…..

    因?yàn)椴煌馁~戶(hù)狀態(tài)會(huì)有不用的折扣計(jì)算方法,所以我們需要不同的實(shí)現(xiàn)策略。座椅非常適用于策略模式。

    在我們的例子中,我們有三種策略:

    NotRegisteredDiscountCalculator
    SimpleCustomerDiscountCalculator
    MostValuableCustomerDiscountCalculator

    他們包含了具體的折扣計(jì)算方法的實(shí)現(xiàn)并被藏在了抽象IAccountDiscountCalculator里。

    這就允許我們的類(lèi)DiscountManager使用合適的策略,而不需要知道具體的實(shí)現(xiàn)。我們的類(lèi)只需要知道與ApplyDiscount方法相關(guān)的IAccountDiscountCalculator?接口返回的對(duì)象的類(lèi)型。

    NotRegisteredDiscountCalculator, SimpleCustomerDiscountCalculator, MostValuableCustomerDiscountCalculator這些類(lèi)包含了具體的通過(guò)賬戶(hù)狀態(tài)選擇適合計(jì)算的計(jì)算方法的實(shí)現(xiàn)。因?yàn)槲覀兊倪@三個(gè)策略看起來(lái)相似,我們唯一能做的基本上就只有針對(duì)這三種計(jì)算策略創(chuàng)建一個(gè)方法然后每個(gè)策略類(lèi)通過(guò)一個(gè)不用的參數(shù)來(lái)調(diào)用她。因?yàn)檫@會(huì)讓我們的代碼變得越來(lái)越多,所以我現(xiàn)在決定不這么做了。

    好了,到目前為止我們的代碼變得可讀了,而且每個(gè)類(lèi)都只有一個(gè)責(zé)任了-這樣修改他的時(shí)候會(huì)單獨(dú)一一對(duì)應(yīng)了:

  • DiscountManager-管理代碼流

  • DefaultLoyaltyDiscountCalculator-可靠的計(jì)算折扣率的方法

  • DefaultAccountDiscountCalculatorFactory-決定根據(jù)賬戶(hù)狀態(tài)選擇哪個(gè)策略來(lái)計(jì)算

  • NotRegisteredDiscountCalculator,?SimpleCustomerDiscountCalculator,?MostValuableCustomerDiscountCalculator?– 根據(jù)賬戶(hù)狀態(tài)計(jì)算折扣率

  • 現(xiàn)在開(kāi)始比較現(xiàn)在與之前的方法:

    這是我們的新的重構(gòu)的代碼:

    總結(jié)

    在本文中,代碼被極其簡(jiǎn)化了,使得所有的技術(shù)和模式的解釋更容易了。它展示了如何解決常見(jiàn)的編程問(wèn)題,以及使用良好的實(shí)踐和設(shè)計(jì)模式以適當(dāng)、干凈的方式解決這些問(wèn)題的好處。

    在我的工作經(jīng)歷中,我多次在這篇文章中強(qiáng)調(diào)了不良的做法。它們顯然存在于許多應(yīng)用場(chǎng)合,而不是在一個(gè)類(lèi)中,如在我的例子中那樣,這使得發(fā)現(xiàn)它們更加困難,因?yàn)樗鼈冸[藏在適當(dāng)?shù)拇a之間。寫(xiě)這種代碼的人總是爭(zhēng)辯說(shuō),他們遵循的是簡(jiǎn)單愚蠢的規(guī)則。不幸的是,幾乎所有的系統(tǒng)都在成長(zhǎng),變得非常復(fù)雜。然后,這個(gè)簡(jiǎn)單的、不可擴(kuò)展的代碼中的每一個(gè)修改都是非常重要的,并且?guī)?lái)了巨大的風(fēng)險(xiǎn)。

    請(qǐng)記住,您的代碼將長(zhǎng)期存在于生產(chǎn)環(huán)境中,并將在每個(gè)業(yè)務(wù)需求更改上進(jìn)行修改。因此編寫(xiě)過(guò)于簡(jiǎn)單、不可擴(kuò)展的代碼很快就會(huì)產(chǎn)生嚴(yán)重的后果。最后一點(diǎn)是對(duì)開(kāi)發(fā)人員有利,尤其是那些在你自己之后維護(hù)你的代碼。

    如果你有一些問(wèn)題根據(jù)文章不要猶豫聯(lián)系我!

    原文地址https://www.cnblogs.com/Aries-rong/p/9289725.html

    .NET社區(qū)新聞,深度好文,歡迎訪(fǎng)問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com

    總結(jié)

    以上是生活随笔為你收集整理的C#:如何将坏的代码重新编译为好的代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 视频二区中文字幕 | 夜夜夜网站 | 黄色片免费 | 99热这里都是精品 | 中文字幕亚洲在线 | 在线观看h视频 | 亚洲情人网 | 黑人vs日本人ⅹxxxhd | 成人激情视频在线观看 | 黑人操亚洲女 | 天天爽天天插 | 久久久久久久久综合 | 亚洲高清视频免费观看 | 天天综合天天综合 | 亚洲综合视频在线 | 黄色片免费网站 | 美女狠狠干 | 尤物精品在线观看 | 国产农村妇女精品一二区 | 国产奶水涨喷在线播放 | 美女张开腿让男人桶爽 | 尤物av在线 | 在线观看成人av | 深夜福利网站在线观看 | fexx性欧美| 五十路av| 久久性色| 国产91在线亚洲 | 91黄色视屏 | 欧美精品久久天天躁 | 无码人妻丰满熟妇奶水区码 | 一级绝黄 | www.欧美激情| 熟妇人妻一区二区三区四区 | 欧美在线视频你懂的 | 一级做a爱片 | 久久久全国免费视频 | 女人天堂av | 久久视频在线 | 中文字幕乱码一区二区三区 | 深爱激情五月婷婷 | 久久久久久久综合色一本 | 天天综合网久久综合网 | 亚洲综合p | 日本japanese极品少妇 | 秋霞福利 | 午夜精品久久久久久久第一页按摩 | 一级淫片免费看 | 欧美一a一片一级一片 | 亚洲小说在线 | 精品亚洲乱码一区二区 | 国产成人精品一区二区三区无码熬 | 综合五月婷婷 | 亚洲欧美一级 | 欧美激情一区二区 | 日本大片黄 | 国产精品19p | 日本美女毛片 | 不卡黄色 | 日本在线资源 | 日日日干| 久久久久成人精品免费播放动漫 | 日韩精品一级 | 超碰男人天堂 | 日韩高清专区 | 久热精品视频在线播放 | 一二三区免费 | jizz18欧美18 | 欧美天天性影院 | 欧洲一级黄色片 | 插插插色综合 | 激情网站在线 | 青青草免费在线观看视频 | 永久免费视频网站直接看 | 三级成人网 | 国产视频精品久久 | 亚洲精品一区二区三区婷婷月 | 日本丰满少妇 | 欧美极品一区二区 | 日本免费电影一区二区三区 | 国产一级性生活片 | 日韩高清国产一区在线 | 4hu最新网址 | 人人草人人草 | 日韩精品免费一区二区夜夜嗨 | 欧美久久久一区二区三区 | 乱lun合集小可的奶水 | 国产成人精品国内自产拍免费看 | 久草视频精品 | 日日爽视频 | 国产精品福利在线播放 | 素人女裸体 | 国产欧美激情 | 亚洲av无码久久精品狠狠爱浪潮 | 午夜福利电影 | 精品人妻在线一区二区三区 | 午夜av在线| 蜜臀精品 | 国产欧美日韩综合 |