面向?qū)ο蠓治稣n件_第1頁
面向?qū)ο蠓治稣n件_第2頁
面向?qū)ο蠓治稣n件_第3頁
面向?qū)ο蠓治稣n件_第4頁
面向?qū)ο蠓治稣n件_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、一個(gè)設(shè)計(jì)的啟發(fā): Mark4 專用咖啡機(jī)第1頁,共32頁。1 描述: Mark4專用咖啡機(jī)最多一次可煮好12杯咖啡。使用者向燒水壺(boiler)內(nèi)加入最多12杯冷水, 按下加熱(Brew)鍵,水被加熱至沸騰,蒸氣壓力迫使水漫 過咖啡粉末,咖啡通過濾網(wǎng)的過濾,流入咖啡壺中,并保 持一定溫度。壺中有咖啡時(shí),保溫托盤處于工作狀態(tài),若 將壺從保溫托盤上拿開,水流將立刻停止,這樣煮沸的咖 啡不會(huì)溢出到保溫托盤上。 使用者先將咖啡粉放入濾網(wǎng)(filter)內(nèi), 濾網(wǎng)放入濾網(wǎng)支架(filter holder)中, 將濾網(wǎng)支架滑入托盤中, 咖啡壺(pot)放在保溫托盤(warmer plate上。第2頁,共

2、32頁。2需要監(jiān)控的硬件 用于燒水壺的加熱部件,可以開啟和關(guān)閉保溫托盤的加熱部件,可以開啟和關(guān)閉保溫托盤的傳感器,有三個(gè)狀態(tài): warmerEmpty(溫?zé)嵫b置空閑) potEmpty(壺空), potNotEmpty (壺不空) 燒水壺中的傳感器,有二個(gè)狀態(tài): boilerEmpty, boilerNotEmpty加熱鍵指示加熱過程,加熱過程結(jié)束,咖啡 煮好,指示燈亮壓力閥門,有開啟和關(guān)閉狀態(tài)。當(dāng)開啟時(shí),燒水 壺中的壓力降低,使經(jīng)過過濾網(wǎng)的水流立刻停止。 第3頁,共32頁。3 硬件由硬件工程師提供API實(shí)現(xiàn)。軟件如何設(shè)計(jì)?ButtonLightCoffeeMakerBoilerWarmePl

3、ateBoilerSensorSensorPlate SensorHeaterBoilerHeaterPlate Heater燒水壺?zé)袅量Х葔乇赝斜P傳感器加熱器圖 1 過于具體的咖啡機(jī)這個(gè)設(shè)計(jì)如何?第4頁,共32頁。4解決思路#1 向Light(燈亮)類添加方法,看看怎么樣? Light只有on(),off()兩個(gè)方法Light.javapublic class Light public void on() CoffeeMakerAPI.api. setIndicatorState(CoffeeMakerAPI.INDICATOR_ON); /設(shè)置指示器狀態(tài) public void off(

4、) CoffeeMakerAPI.api. setIndicatorState(CoffeeMakerAPI.INDICATOR_OFF); 這段代碼有什么問題?沒有變量,奇怪,因?yàn)閷?duì)象通常擁有狀態(tài),且還操縱這些狀態(tài)兩個(gè)方法只是簡(jiǎn)單調(diào)用的一個(gè)轉(zhuǎn)發(fā)者,沒作任何事情,多余稱為泡泡類(Vapor Class)Button,Boiler,WarmerPlate也是如此第5頁,共32頁。5解決思路#2 考慮抽象 圖中有兩個(gè)基類 Sensor,Heatersensor.javapublic interface Sensor public int sense();Heater.javapublic inte

5、rface Heater public void turnOn(); public void turnOff(); 程序的這兩個(gè)類有什么用? 一個(gè)類只包含抽象方法,但沒有使用者,返回值不確定,sense()方法返回什么? 在燒水壺的傳感器中返回值有兩種可能. 在保溫托盤的傳感器中返回值有三種可能. 無法在接口中表達(dá)傳感器的約定. Sensor,Heater沒什么用.第6頁,共32頁。6一個(gè)可行的解決方案 重新根據(jù)問題的本質(zhì)特性分解細(xì)節(jié) 忘掉:燒水壺、閥門、加熱托盤、傳感器等 專注本質(zhì)問題:怎樣沖咖啡? 向咖啡粉上倒熱水,然后將產(chǎn)生的液體收集到 某種容器內(nèi)??稍O(shè)定為兩個(gè)抽象類: HotWater

6、Source(燒水壺、閥門、傳感器)加熱水, 把熱水送到咖啡粉,最后滴到ContainmentVessel (保溫托盤、傳感器演了這個(gè)角色)容器中,且保溫。 第7頁,共32頁。7其描述:HotWaterSourceContainmentVesselCoffeeFlow 這個(gè)關(guān)系是根據(jù)物理特性設(shè)定的,而不是根據(jù)軟件操作的控制設(shè)定的。HotWaterSourceContainmentVesselstart圖 2 交叉線圖 3 開啟熱水水流 設(shè)計(jì)中的關(guān)聯(lián)是在對(duì)象間發(fā)送消息的通道, 和物理對(duì)象的流程無關(guān)。第8頁,共32頁。8 用戶與系統(tǒng)是怎樣交互的?用類UserInterface(按鈕、指示燈)來表示

7、。 這三個(gè)類實(shí)例之間是怎樣交互的?# 由哪個(gè)對(duì)象檢測(cè)用戶按下加熱“Brew”按鈕這一事件?UserInterface對(duì)象# 加熱按鈕被按下時(shí),這個(gè)對(duì)象應(yīng)該做什么?確認(rèn)燒水壺滿了,咖啡壺是空的,且放在保溫托盤上。UserInterface對(duì)象發(fā)送消息給: HotWaterSource ContainmentVessel,是否就緒。 第9頁,共32頁。9UserInterfaceHotWaterSourceContainmentVesselIsReadyIsReady圖 4 加熱按鈕被按下,檢查是否就緒 只要有一個(gè)查詢?yōu)閒alse,拒絕加熱咖啡,通知用戶,請(qǐng)求無效。 具體到咖啡機(jī)上,可用指示燈閃爍

8、來表示。UserInterfaceHotWaterSourceContainmentVessel2a:IsReady1a:IsReady圖 5 加熱按鈕被按下,完成3a:Start 兩個(gè)查詢的結(jié)果都為true,開始熱水的流動(dòng)。具體到咖啡機(jī)上,關(guān)閉閥門,打開燒水壺。第10頁,共32頁。10UserInterfaceHotWaterSourceContainmentVessel2a:IsReady1a:IsReady圖 6 暫停和恢復(fù)熱水的流動(dòng)3a:Start 煮咖啡時(shí),咖啡機(jī)的用戶可以把咖啡壺從加熱托盤上拿走。哪個(gè)對(duì)象檢查壺被拿走?停止咖啡的流動(dòng)。1b:Pause2b:Resume 是Conta

9、inmentVessel對(duì)象:咖啡壺被拿走,停止加熱;咖啡壺被放回原處,開始加熱第11頁,共32頁。11UserInterfaceHotWaterSourceContainmentVessel2a:IsReady1a:IsReady圖 7 檢查加熱的過程是否完成(done)3a:Start 咖啡煮好,就停止熱水的流動(dòng)。哪個(gè)對(duì)象知道煮咖啡的過程結(jié)束了?1b:Pause2b:Resume加熱完畢 User Interface 要知道,咖啡煮好, 亮燈。 2c:Done1c:Done2d:Done1d:Done HotWaterSource要知道加熱過程結(jié)束,停止熱水流動(dòng)。 對(duì)于咖啡機(jī),關(guān)閉燒水壺,

10、打開閥門。 ContainmentVessel也要知道加熱過程結(jié)束,檢查空咖 啡壺確實(shí)放回到保濕托盤上,并發(fā)出用戶倒完最后一杯咖 啡的信號(hào)。第12頁,共32頁。12UserInterfaceHotWaterSourceContainmentVessel2a:IsReady1a:IsReady圖 8 咖啡倒空3a:Start 加熱過程結(jié)束后,咖啡機(jī)熄滅指示燈,空咖啡壺放回到托盤上。誰來檢查這種情況?1b:Pause2b:Resume咖啡倒空2c:Done1c:Done2d:Done1d:Done ContainmentVesselu檢查,它還向UserInterface發(fā)送一個(gè)Complete(

11、完成)消息1e:Complete4a:Start第13頁,共32頁。13如何在這種結(jié)構(gòu)下實(shí)現(xiàn)Mark4咖啡機(jī)?是否可實(shí)現(xiàn)這三個(gè)類中的方法,去調(diào)用相應(yīng)的CoffeeMakerAPI? x是否將咖啡機(jī)的本質(zhì)同Mark4機(jī)綁定在一起就可以?是個(gè)糟糕的設(shè)計(jì)利用依賴倒置(DIP)進(jìn)行設(shè)計(jì)User Interface#startBrewingHotWaterSourceContainmentVessel圖 9 檢查加熱按鈕M4UserInterface+checkButton當(dāng)checkButton函數(shù)被調(diào)用,它就調(diào)用CoffeeMakerAPI.getBrewButtonStatus() 按鈕己經(jīng)被按下

12、,它就調(diào)用UserInterface中的保護(hù)方法startBrewing()為什么要?jiǎng)?chuàng)建保護(hù)方法startBrewing()?為什么不直接從M4UserInterface調(diào)用start()函數(shù)?對(duì)start(),isReady()檢測(cè)方法的調(diào)用都是UserInterface應(yīng)該處理的高級(jí)行為,不應(yīng)耦合到Mark4機(jī)中。第14頁,共32頁。14CoffeeMakerAPI.JAVApublic interface CoffeeMakerAPI public static CoffeeMakerAPI api = null;/由 main 設(shè)置實(shí)現(xiàn)以下的函數(shù): 返回加熱托盤傳感器的狀態(tài),該傳感器檢

13、查咖啡壺否 在托盤上,其中是否有咖啡. 返回?zé)畨亻_關(guān)的狀態(tài),檢查壺中的存水是水多于1/2杯檢查開關(guān)燒水壺中的加熱托盤檢查開關(guān)保溫托盤中的加熱托盤檢查開關(guān)指示燈開關(guān)壓力閥門,閥門關(guān),燒水壺蒸氣壓力迫使開水流過 過濾器第15頁,共32頁。15public int getBrewButtonStatus(); public static final int BREW_BUTTON_PUSHED = 0; public static final int BREW_BUTTON_NOT_PUSHED = 1 檢查加熱按鈕的狀態(tài) M4UserInterface.java public class M4U

14、serInterface extends UserInterface private void checkButton() int buttonStatus = CoffeeMakerAPI.api.getBrewButtonStatus(); if (buttonStatus = CoffeeMakerAPI.BREW_BUTTON_PUSHED) startBrewing(); 第16頁,共32頁。16 UserInterface.java public class UserInterface private HotWaterSource hws; private ContainmentV

15、essel cv; public void done() public void complete() protected void startBrewing() if (hws.isReady() & cv. isReady() hws.start(); cv.start(); 第17頁,共32頁。17圖 4-10 實(shí)現(xiàn)1sReady()函數(shù)User Interface#startBrewingHot Water Source+isReady()Containment Vessel +isReady()M4Containment Vessel +isReady()加熱水檢查停止/開始加熱M4

16、HotWater Source M4UserInterface+checkButton()實(shí)現(xiàn)準(zhǔn)備就緒IsReady()函數(shù)保溫器通過調(diào)用coffeeMakerAPI函數(shù)來實(shí)現(xiàn)第18頁,共32頁。18M4HotWaterSource.javapublic class M4HotWaterSource extends HotWaterSource public boolean isReady() int boiler Status = CoffeeMakerAPI.api.getBoilerStatus(); return boilerStatus = CoffeeMakerAPI.BOILER

17、_NOT_EMPTY; 第19頁,共32頁。19M4ContainmentVessel.javapublic class M4ContainmentVessel extends ContainmentVessel public boolean isReady() int plateStatus = CoffeeMakerAPI.api.getWarmerplateStatus(); return plateStatus = CoffeeMakerAPI. POT_EMPTY; 第20頁,共32頁。20 實(shí)現(xiàn) start()函數(shù)start()函數(shù)是類HotWaterSource的一個(gè)抽象 方法,

18、是由M4UserInterface調(diào)用關(guān)閉閥門和打開燒 水壺的CoffeeMakerAPI函數(shù)實(shí)現(xiàn)的。 第21頁,共32頁。21M4HotWaterSource.javapublic class M4HotWaterSource extends HotWaterSource CoffeeMakerAPI api public M4HotWaterSource(CoffeeMakerAPI api) this.api = api; public boolean isReady() inc boilerStatus = api.getBoilerStatus(); return boilerSta

19、tus = api. BOILER_NOT_EMPTY; public void start() api.setReliefValveState(api. VALVE_CLOSED); api.setBoilerState(api.BOILER_ON); 第22頁,共32頁。22ContainmentVessel的start()方法唯一操作是記住系統(tǒng)煮咖啡的狀態(tài)??梢员WC當(dāng)咖啡壺放到托盤上或?qū)⑺鼜耐斜P上拿走時(shí),系統(tǒng)能做出正確的反應(yīng)。M4ContainmentVessel.javapublic class M4ContainmentVessel extends ContainmentVessel

20、 private CoffeeMakerAPI api; private boolean isBrewing; public M4ContainmentVessel(CoffeeMakerAPI api) this.api = api; isBrewing = false; 第23頁,共32頁。23 public boolean isReady() int plateStatus = ai.getWarmerPlateStatus(); return plateStatus = api.POT_EMPTY; public void start() isBrewing = true; 第24頁,

21、共32頁。24 M4UserInterface.checkButton是如何被調(diào)用的?CoffeeMakerAPI.getBrewButtonStatus怎樣被調(diào) 用的?即任何檢測(cè)傳感器的方法是如何被調(diào)用的?使用多線程還是使用輪詢方法解決?一個(gè)比較理想的方法是假設(shè)這些消息可以異步發(fā) 送,與線程是相互獨(dú)立的,是后再?zèng)Q定使用多線程 還是使用輪詢。設(shè)控制流以異步方式進(jìn)入M4UserInterface對(duì)象, 這樣它就調(diào)用 CoffeeMakerAPI.getBrewButtonStatus()第25頁,共32頁。25假設(shè),最小的JVM,不支持線程,只能采用輪詢。Pollable.javapublic

22、interface Pollable public void poll(); 若M4UserInterface實(shí)現(xiàn)了這個(gè)接口,情況如何? 若main()程序陷入了一個(gè)死循環(huán),不停地調(diào)用此 方法,情況如何?控制流就會(huì)持續(xù)不斷地進(jìn)入M4UserInterface 接口,可以檢測(cè)“加熱”按鈕。第26頁,共32頁。26User Interface#startBrewingHot Water Source+isReady()Containment Vessel +isReady()M4Containment Vessel加熱水檢查停止/開始加熱M4HotWater Source M4UserInterf

23、ace+checkButton() 可以輪詢的咖啡機(jī)interface Pollable +poll()圖 4-11 可以輪詢 的咖啡機(jī)第27頁,共32頁。27CoffeeMaker.javapublic class CoffeeMaker public static void main(String args) CoffeeMakerAPI api = new M4CoffeeMakerAPIImplementation(); M4UserInterface ui = new M4UserInterface(api); M4HotWaterSource hws = new M4HotWaterSource(api); M4ContainmentVessel cv = new M4ContainmentVessel(api);第28頁,共32頁。28 ui.init(hws,cv); hws.init(ui,cv); cv.init(ui,hws); while(true) ui.poll(); hws.poll(); cv.poll(); 可以清楚M4UserInterface函數(shù)是如

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論