




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、9.1 分解條件式 復(fù)雜的條件語(yǔ)句 從if、then、else三個(gè)段落中分別提煉出獨(dú)立函數(shù)。if (date.before(SUMMER_START) | date.after(SUMMER_END) charge = quantity * _winterRate + _winterServiceCharge;else chareg = quantity * _summerRate;if (notSummer(data) charge = winterCharge(quantity);else charge = summerCharge(quantity);假設(shè)要計(jì)算購(gòu)買(mǎi)某樣商品的總價(jià)(總價(jià)=
2、數(shù)量單價(jià),而這個(gè)商品在冬季和夏季的單價(jià)是不同的:把每個(gè)分支的判斷條件都提煉到一個(gè)獨(dú)立函數(shù)中,如下所示:if (date.before(SUMMER_START) | date.after(SUMMER_END) charge = quantity * _winterRate + _winterServiceCharge;else chareg = quantity * _summerRate;if (notSummer(date) charge = winterCharge(quantity);else chareg = summerCharge(quantity);private boole
3、an notSummer(Date date) return date.before(SUMMER_START)|date.after(SUMMER_END);private double summerCharge(int quantity) return quantity * _summerRate;private double winterCharge(int quantity) return quantity * _winterRate + _winterServiceCharge;9.2 合并條件式 一系列條件測(cè)試,都得到相同結(jié)果 將這些測(cè)試合并為一個(gè)條件式,并將這個(gè)條件式提煉成為一個(gè)
4、獨(dú)立函數(shù)。double disablityAmount() if (_seniority 12 ) return 0;if (_isPartTime) return 0;double disabilityAmount() if (ifNotBligableForDisablility() return 0;確定這些條件語(yǔ)句都沒(méi)有連帶影響。使用適當(dāng)?shù)倪壿嫴僮鞣瑢⒁幌盗邢嚓P(guān)條件式合并為一個(gè)。編譯,測(cè)試。對(duì)合并后的條件式提煉函數(shù)。連續(xù)的的條件檢查,等價(jià)于一個(gè)以邏輯OR連接起來(lái)的語(yǔ)句:double disablityAmount() if (_seniority 12 ) return 0;if (
5、_isPartTime) return 0;double disablityAmount() if (_seniority 12 )| (_isPartTime) return 0;然后,在新條件式中提煉出一個(gè)獨(dú)立函數(shù),以函數(shù)名稱(chēng)表達(dá)該語(yǔ)句所檢查的條件double disabilityAmount() if (ifNotBligableForDisablility() return 0;Boolen ifNotBligableForDisablility() return (_seniority 12 )| (_isPartTime);9.3 合并重復(fù)的條件片段 在條件式的每個(gè)分支上有相同的一
6、段代碼。 將這段代碼搬移到條件式之外。找出執(zhí)行方式不隨條件變化而變化的代碼:如果這些代碼位于條件式起始處,就將它移到條件式之前如果這些代碼位于條件式尾端,就將它移到條件式之后。如果這些代碼位于條件式中段,需要觀察共同代碼之前或之后的代碼是否改變其他代碼。如果有所改變,應(yīng)該首先將共同代碼向前或向后移動(dòng),移至條件式的起始處或尾端,再以前面所說(shuō)的辦法來(lái)處理。如果代碼不止一條語(yǔ)句,將共同代碼提煉到獨(dú)立函數(shù)中,再以上述方法處理。 由于條件式的兩個(gè)分支都執(zhí)行了send()函數(shù),所以將該部分代碼移到條件式的外圍:if (isSpecialDeal() total = price * 0.95; send()
7、;else total = price * 0.98; send();if (isSpecialDeal() total = price * 0.95;else total = price * 0.98; send();9.4 移除控制標(biāo)記 在布爾表達(dá)式中,某個(gè)變量待遇控制標(biāo)記的作用 以break語(yǔ)句或return語(yǔ)句取代控制標(biāo)記方法:找出跳出這段邏輯的控制標(biāo)記值。用break或continue代替不符合條件式的值賦予標(biāo)記變量的語(yǔ)句。每次并換后,編譯并測(cè)試。例:以break取代控制標(biāo)記下列函數(shù)用來(lái)檢杳多個(gè)人名之中是否包含兩個(gè)可疑人物的名字void checkSecurity (String p
8、eople) boolean found = false; for (!found) if (peoplei.equals(don) sendAlert(); found = ture; if (peoplei.equals(john) sendAlert(); found = ture; 很容易找出控制標(biāo)記,當(dāng)變量found被賦予true時(shí),搜索就結(jié)束。為此逐一引入break語(yǔ)句:void checkSecurity (String people) boolean found = false; for (!found) if (peoplei.equals(don) sendAlert();
9、 break; if (peoplei.equals(john) sendAlert(); break; 然后把對(duì)控制標(biāo)記的所有引用都去掉void checkSecurity (String people) for (int i=0; ipeople.length; i+) if (peoplei.equals(don) sendAlert(); break; if (peoplei.equals(john) sendAlert(); found = ture; 例:以return取代控制標(biāo)記本項(xiàng)重構(gòu)的另一種方法是使用return語(yǔ)句。把前面的例子稍加修改,以控制標(biāo)記記錄搜索結(jié)果:變量foun
10、d既是控制標(biāo)記,也是運(yùn)算結(jié)果。先把計(jì)算found變量的代碼提煉到一個(gè)獨(dú)立函數(shù)中:void checkSecurity (String people) String found = ; for (int i=0; ipeople.length; i+) if (found.equals( ) if( people i .equals(don) sendAlert(); found = don; if (people i .equals(john) sendAlert(); found = john; someLaterCode(found);void checkSecurity (String
11、people) String found = foundMiscreant(people); someLaterCode(found);String foundMiscreant(String people) String foud = ; for(int i=0; ipeople.length; i+) if(found.equals() if(people i .equals(don) sendAlert(); found = don; if(people i .equals(john) sendAlert(); found = john; return found;然后以return語(yǔ)句
12、取代控制標(biāo)記String foundMiscreant(String people) String foud = ; for(int i=0; ipeople.length; i+) if(found.equals() if(people i .equals(don) sendAlert(); return don; if(people i .equals(john) sendAlert(); return john; return found;最后完全去掉控制標(biāo)記String foundMiscreant(String people) for(int i=0; i 0.0) if (_int
13、Rate 0.0 & _duration 0.0) result = (_income / _duration) * ADJ_FACTOR; return result;需逐一替換。在插入衛(wèi)語(yǔ)句前,將相應(yīng)的條件逆反過(guò)來(lái)。public double getAdjustedCapital() double result = 0.0; if (_capital 0.0 & _duration 0.0) result = (_income / _duration) * ADJ_FACTOR; return result;下一個(gè)條件稍復(fù)雜,分兩步進(jìn)行。首先加入“l(fā)ogical NOT”操
14、作public double getAdjustedCapital() double result = 0.0; if (_capital 0.0 & _duration 0.0) return result; result = (_income / _duration) * ADJ_FACTOR; return result;繼續(xù)簡(jiǎn)化如下:public double getAdjustedCapital() double result = 0.0; if (_capital 0.0) return result; if( _intRate = 0.0 | _duration = 0.
15、0) return result; result = (_income / _duration) * ADJ_FACTOR; return result;在衛(wèi)語(yǔ)句內(nèi)返回一個(gè)明確值,這樣能清晰地看到衛(wèi)語(yǔ)句返回的失敗結(jié)果public double getAdjustedCapital() double result = 0.0; if (_capital 0.0) return 0.0; if( _intRate = 0.0 | _duration = 0.0) return 0.0; result = (_income / _duration) * ADJ_FACTOR; return resu
16、lt;最后移除臨時(shí)變量public double getAdjustedCapital() double result = 0.0; if (_capital 0.0) return 0.0; if( _intRate = 0.0 | _duration = 0.0) return 0.0; return (_income / _duration) * ADJ_FACTOR;9.6 以多態(tài)取代條件式 條件式根據(jù)對(duì)象型別的不同而選擇不同的行為 將這個(gè)條件式的每個(gè)分支放進(jìn)一個(gè)子類(lèi)的覆寫(xiě)函數(shù)中,然后將原始函數(shù)聲明為抽象函數(shù)如果要處理的條件式是個(gè)更大函數(shù)中的一部分,將它提煉到獨(dú)立函數(shù)。使用移動(dòng)函數(shù)方法
17、將條件式放在繼承結(jié)構(gòu)的頂端任選一個(gè)子類(lèi)在其中建立一個(gè)函數(shù),覆寫(xiě)子類(lèi)中容納條件式的那個(gè)函數(shù)。將與該子類(lèi)相關(guān)的條件式分支復(fù)制到新建函數(shù)中,并對(duì)它進(jìn)行適當(dāng)調(diào)整。編譯,測(cè)試。在子類(lèi)中刪掉條件式內(nèi)被復(fù)制的分支針對(duì)條件式的每個(gè)分支,重復(fù)上述過(guò)程,直到所有分支都被移到子類(lèi)中的函數(shù)為止。將子類(lèi)中容納條件式的函數(shù)聲明為抽象函數(shù)。方法:class Employee. int payAmount ( ) swith (getType( ) ) case Employee.ENGINEER: return _monthlySalary; case Employee.SALESMAN: return _monthlyS
18、alary + _conmission; case Employee. return _monthlySalary + _bornus; default: throw new RuntimeException(incorrect employee); Switch語(yǔ)句已經(jīng)被提煉出來(lái),需將其移到EmployeeType 類(lèi)中 int getType() return _type.getTypeCode(); private EmployeeType _type;abstract class EmployeeType. abstract int getTypeCode( );class Engin
19、eer extends EmployeeType. int getTypeCode( ) return EmployeeType.ENGINEER; 將Employee對(duì)象作為參數(shù)傳遞給payAmount()修改Employee中payAmount()函數(shù),令它委托EmployeeType:class EmployeeType. int payAmount (Employee emp) swith (getTypeCode( ) ) case ENGINEER: return emp.getMonthlySalary(); case SALESMAN: return emp.getMonthl
20、ySalary() + emp.getConmission(); case MANAGER: return emp.getMonthlySalary() + emp.getBornus; default: throw new RuntimeException(incorrect employee); class Employee. int payAmount ( ) return _type.payAmount(this); 下面開(kāi)始處理switch語(yǔ)句。首先將switch語(yǔ)句中的”Engineer“分支復(fù)制到Engineer類(lèi):這個(gè)新函數(shù)覆寫(xiě)了父類(lèi)中switch語(yǔ)句內(nèi)處理”Engineer的
21、分支。重復(fù)上述過(guò)程,直到所有分支都被去除為止。然后,將父類(lèi)的payAmount()聲明為抽象函數(shù)class Employee. int payAmount (Employee emp ) return emp.getMonthlySalary(); class Salesman. int payAmount (Employee emp ) return emp.getMonthlySalary() + emp.getComminssion(); class Manager. int payAmount (Employee emp ) return emp.getMonthlySalary()
22、+ emp.getBounus(); class EmployeeType. abstract int payAmount(Employee emp);9.7 引入Null對(duì)象 某值為無(wú)效值null object 將null value替換為null object為源類(lèi)建立一個(gè)子類(lèi),使其行為像所在源類(lèi)的null版本。在源類(lèi)和null類(lèi)加上isNull()函數(shù),前者的isNull應(yīng)該返回false,后者應(yīng)該返回true。編譯。找出所有要求源對(duì)象卻獲得null的地方。修改它們改而獲得null object。找出所有將源對(duì)象與null做比較的地方。修改它們調(diào)用isNull()函數(shù)。編譯,測(cè)試。找出這
23、樣的程序點(diǎn):如果對(duì)象不是null,做A動(dòng)作,否則做B動(dòng)作。對(duì)于每一個(gè)上述地點(diǎn),在null class中覆寫(xiě)A動(dòng)作,使其行為和B動(dòng)作相同。使用上述的被覆寫(xiě)動(dòng)作(A),然后刪除對(duì)象是否等于null的條件測(cè)試。編譯并測(cè)試一家公用事業(yè)公司的系統(tǒng)以site表示地點(diǎn)(場(chǎng)所)、庭院宅第( house)和集合公寓( apartment)都使用該公司的服務(wù)。任何時(shí)候每個(gè)地點(diǎn)都擁有(或說(shuō)都對(duì)應(yīng)于)一個(gè)顧客,顧客信息以Custmer表示:Customer的其中三個(gè)特性class Site. Customer getCustomer() return _customer; Customer _customer;cla
24、ss Customer. public String getName() . public BillingPlan getPlan() . public PaymentHistory getHistory() .系統(tǒng)以PaymentHistory表示顧客的付款記錄上面的各種取值函數(shù)允許客戶(hù)取得各種數(shù)據(jù)。但有時(shí)候一個(gè)地點(diǎn)的顧客搬走了,新顧客還沒(méi)搬進(jìn)來(lái),此時(shí)這個(gè)地點(diǎn)就沒(méi)有顧客。所以必須保證Customer的所有用戶(hù)都能夠處理“Customer對(duì)象等于nu”ll的情況。public class PaymentHistory. int getWeeksDelingquenInLastYear()Cus
25、tomer customer = site.getCustomer();BillingPlan plan;if (customer = null) plan = BillingPlan.basic();else plan customer.getPLan();.String customerName;if (customer = null) customerName = occupant;else customerName = customer.getName();.int weekDellinquent = 0;if (customer = null)weekDellinquent = 0;
26、else weekDellinquent = customer.getHistory().getWeekDellinquentInLastYear(); 這個(gè)系統(tǒng)中可能使用許多Site和customer,它們都必須檢查Customer對(duì)象是否等于null,這樣的檢查完全是重復(fù)的。 應(yīng)使用null object。 首先建立一個(gè)NullCustomer,并修改Customer,使其支持對(duì)象是否為Null的檢查class NullCustomer extends Customer public boolean isNull() return true; class Customer. public
27、boolean isNull() return false; protected Customer() 修改所有索求Customer對(duì)象的地方,使它們不返回null,而是返回一個(gè)NullCustomer對(duì)象class Site. Customer getCustomer() return (_customer = null? Customer.newNull():_customer; Customer customer = site.getCustomer();BillingPlan plan;if (customer.isNull( ) ) plan = BillingPlan.basic(
28、);else plan customer.getPLan();.String customerName;if (customer.isNull() ) customerName = occupant ;else customerName = customer.getName();.int weekDellinquent = 0;if (customer.isNull() )weekDellinquent = 0;else weekDellinquent = customer.getHistory().getWeekDellinquentInLastYear();另外修改所有使用Customer
29、對(duì)象的地方,讓它們isNull()函數(shù)進(jìn)行檢查,不再使用“ = null ”檢查方式。把相關(guān)行為移到NullCustomer 類(lèi)中并去除條件式。首先從“取得顧客名稱(chēng)”開(kāi)始,其原代碼如下:首先為NullCutomer加入函數(shù),通過(guò)該函數(shù)取得顧客名稱(chēng)然后去掉條件碼:以同樣方法處理其他函數(shù),使他們對(duì)相應(yīng)查詢(xún)作出合適的相應(yīng)。String customerName;if (customer.isNull() ) customer = occupant;else customer = customer.getName();class NullCustomer. public String getName() return occupent; String customerName = customer.getName();還
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 智慧辦公樓宇的安防挑戰(zhàn)與對(duì)策
- 少兒美術(shù)培訓(xùn)招貼畫(huà)創(chuàng)意設(shè)計(jì)指南
- 智慧城市發(fā)展背景下網(wǎng)絡(luò)安全與數(shù)據(jù)保護(hù)的創(chuàng)新策略
- 學(xué)生大腦的神經(jīng)可塑性研究
- 口腔細(xì)節(jié)管理培訓(xùn)課件
- 抖音商戶(hù)市場(chǎng)專(zhuān)員競(jìng)品分析周期制度
- 全球物聯(lián)網(wǎng)傳感器行業(yè)技術(shù)創(chuàng)新與市場(chǎng)應(yīng)用前景報(bào)告
- 公交優(yōu)先發(fā)展戰(zhàn)略下2025年城市交通擁堵治理的公共交通服務(wù)滿(mǎn)意度提升報(bào)告
- 公眾參與視角下2025年環(huán)境評(píng)價(jià)機(jī)制優(yōu)化與生態(tài)文明建設(shè)路徑研究
- 2025屆湖北省荊州市松滋市數(shù)學(xué)七上期末統(tǒng)考模擬試題含解析
- 2025屆上海市閔行區(qū)七下數(shù)學(xué)期末學(xué)業(yè)水平測(cè)試模擬試題含解析
- GB/T 18487.4-2025電動(dòng)汽車(chē)傳導(dǎo)充放電系統(tǒng)第4部分:車(chē)輛對(duì)外放電要求
- 離婚不離家協(xié)議書(shū)
- 社區(qū)干事考試試題及答案
- 2025年廣西南寧賓陽(yáng)縣昆侖投資集團(tuán)有限公司招聘筆試參考題庫(kù)含答案解析
- 醫(yī)院入職培訓(xùn):醫(yī)德醫(yī)風(fēng)
- 2025年軍人離婚協(xié)議書(shū)范本
- 娛樂(lè)行業(yè):舞蹈演員個(gè)人簡(jiǎn)介簡(jiǎn)歷
- 工程造價(jià)復(fù)審報(bào)告書(shū)范文
- SAP S4HANA 用戶(hù)操作手冊(cè)-成本控制CO操作手冊(cè)-002-訂單成本核算
- 幼兒園2025-2026學(xué)年度第一學(xué)期園本培訓(xùn)計(jì)劃
評(píng)論
0/150
提交評(píng)論