面向?qū)ο蠓治龊驮O(shè)計(jì)講座9.細(xì)化迭代2更多模式_第1頁
面向?qū)ο蠓治龊驮O(shè)計(jì)講座9.細(xì)化迭代2更多模式_第2頁
面向?qū)ο蠓治龊驮O(shè)計(jì)講座9.細(xì)化迭代2更多模式_第3頁
面向?qū)ο蠓治龊驮O(shè)計(jì)講座9.細(xì)化迭代2更多模式_第4頁
面向?qū)ο蠓治龊驮O(shè)計(jì)講座9.細(xì)化迭代2更多模式_第5頁
已閱讀5頁,還剩92頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第9講細(xì)化迭代2:更多模式內(nèi)容迭代2GRASP模式GoF模式11/25/202321.迭代2的需求和重點(diǎn)1.1迭代2的重點(diǎn)基本對象設(shè)計(jì)使用模式來創(chuàng)建穩(wěn)健的設(shè)計(jì)應(yīng)用UML使模型可視化11/25/2023411/25/202351.2從迭代1到迭代2在迭代1所有軟件都已經(jīng)被充分地測試客戶定期地參與對已完成部分的評估已經(jīng)對系統(tǒng)(這里的系統(tǒng)也包括所有子系統(tǒng))進(jìn)行了完整的集成和固化,使其成為基線化的內(nèi)部版本11/25/202361.3迭代2需求NextGenPOS支持第三方外部服務(wù)的變化,例如,能夠與不同的稅金計(jì)算器相連接復(fù)雜的定價(jià)規(guī)則,可更換的業(yè)務(wù)規(guī)則需要進(jìn)行設(shè)計(jì),使得在銷售總額變化時(shí)刷新GUI窗口11/25/20237由于這些需求,我們要在迭代2中對處理銷售用例進(jìn)行修訂,但是實(shí)現(xiàn)了更多場景對面向分析的對象的修改在此輪迭代中也是需要的Use-CasesSSDsDomainModel11/25/202382.GRASP:MorePatternsForAssigningResponsibilities我們學(xué)習(xí)了什么?信息專家創(chuàng)建者高內(nèi)聚低耦合控制器11/25/202310我們還需要學(xué)習(xí)?多態(tài)(Polymorphism)間接性(Indirection)純虛構(gòu)(PureFabrication)防止變異(ProtectedVariation)11/25/2023112.1多態(tài)問題如何處理基于類型的選擇?“If-then-else”;“select-case”如何創(chuàng)建可插拔的軟件構(gòu)件?11/25/202313解決方案當(dāng)相關(guān)選擇或行為隨類型(類)有所不同時(shí),使用多態(tài)為變化的行為類型分配職責(zé)11/25/202314例子支持多種外部的第三方稅金計(jì)算器它們具有不同技術(shù)實(shí)現(xiàn)的不同的TCPsocketSOAPinterfaceJavaRMIinterface11/25/202315TaxMasterAdaptergetTaxes(Sale):ListofTaxLineItemsGoodAsGoldTaxProAdaptergetTaxes(Sale):ListofTaxLineItems<<interface>>ITaxCalculatorAdaptergetTaxes(Sale):ListofTaxLineItemsByPolymorphism,multipletaxcalculatoradaptershavetheirownsimilar,butvaryingbehaviorforadaptingtodifferentexternaltaxcalculators.<???>Adapter......11/25/202316UMLNotationGoodAsGoldTaxProAdaptergetTaxes(Sale):ListofTaxLineItems<<interface>>ITaxCalculatorAdaptergetTaxes(Sale):ListofTaxLineItemsINTERFACENOTATIONINTERFACENOTATIONInterfaceimplementationisillustratedwithadashedlineandalargeunfilledarrowpointingtotheinterfacefromtheimplementingclass.the<<interface>>elementinguillemetsiscalledaUMLstereotypeReturnorparametertypesthatrepresentacollectioncanbespecifiedinanysyntax,butthisisthegenerallyacceptedcommonUMLstyle.11/25/202317禁忌不要為那些假想中的變化添加太多的多態(tài)11/25/202318優(yōu)點(diǎn)易于增加新變化所需的擴(kuò)展無需影響客戶便能夠引入新的實(shí)現(xiàn)11/25/2023192.2純虛構(gòu)(PureFabrication)問題面向?qū)ο笤O(shè)計(jì)依據(jù)真實(shí)世界中的概念來表示軟件類但是軟件并非真實(shí)的世界我們需要通過領(lǐng)域?qū)訉ο髞砜朔蛢?nèi)聚或者耦合低復(fù)用11/25/202321解決方案對人為制造的類分配一組高內(nèi)聚的職責(zé),該類并不代表問題領(lǐng)域的概念-虛構(gòu)的事物,用以支持高內(nèi)聚、低耦合和復(fù)用11/25/202322例子為了保存Sale

的實(shí)例到關(guān)系數(shù)據(jù)庫基于信息專家的考慮,存在理由將責(zé)任分配給Sale

類自己.但是考慮如下含義:需要大量的數(shù)據(jù)庫操作,這將使Sale

變得非內(nèi)聚Sale

類必須與關(guān)系數(shù)據(jù)庫接口耦合,這樣增加了耦合將對象保存到關(guān)系數(shù)據(jù)庫中是一個(gè)普遍的任務(wù)-它可以重用11/25/20232311/25/202324討論對象的設(shè)計(jì)可以廣泛的分成兩組表示解析(Representationaldecomposition)行為解析(Behavioraldecomposition)11/25/202325優(yōu)點(diǎn)支持高內(nèi)聚增加了潛在的復(fù)用性11/25/202326禁忌不要過度使用它將導(dǎo)致非O-O的系統(tǒng)11/25/2023273.間接性(Indirection)問題為了避免兩個(gè)或多個(gè)事物之間的直接耦合,應(yīng)該如何分配職責(zé)?如何使對象解耦,以支持低耦合并提高復(fù)用性?11/25/202329解決方案將職責(zé)分配給中介對象,使其作為其他構(gòu)件或服務(wù)之間的媒介,以避免它們之間的直接耦合11/25/202330例子TaxCalculatorAdapterPersistentStorages:Sale:TaxMasterAdaptertaxes:=getTaxes(s)t:=getTotal()theadapteractsasalevelofindirectiontoexternalsystems<<System>>:TaxMasterTCPsocketcommunicationxxx...11/25/202331優(yōu)點(diǎn)組件之間的低耦合11/25/2023322.4防止變異(ProtectedVariations)問題如何設(shè)計(jì)對象,子系統(tǒng)和系統(tǒng),使其內(nèi)部的變化或不穩(wěn)定性不會對其它元素造成不良影響11/25/202334解決方案識別預(yù)計(jì)變化或不穩(wěn)定之處,分配職責(zé)用以在這些變化之外創(chuàng)建穩(wěn)定接口11/25/202335例子外部稅金計(jì)算器問題11/25/202336討論P(yáng)V時(shí)非常重要和基本的軟件設(shè)計(jì)原則。許多軟件或架構(gòu)設(shè)計(jì)技巧都是防止變異的特例Dataencapsulation,interfaces,polymorphism,indirection…Data-drivendesignsSOA…11/25/202337禁忌如果需要靈活性和對變化的預(yù)防,那么就應(yīng)用

PV如果預(yù)測將來驗(yàn)證或者預(yù)測“復(fù)用”的可能性并不確定,則需要有克制和批評的態(tài)度11/25/202338初學(xué)者傾向于脆弱的設(shè)計(jì)而中等程度的開發(fā)者則傾向于過度想象的,靈活的,一般化的設(shè)計(jì)專家開發(fā)者理智地進(jìn)行選擇11/25/202339優(yōu)點(diǎn)易于增加新變化所需的擴(kuò)展可以引入新的實(shí)現(xiàn)而無需影響客戶低耦合能夠降低變化的成本或影響11/25/2023403.Gang-of-Four模式Gang-of-Four模式DesignPatterns,作為一本非常著名的書,是由四位作者寫的,因此

我們使用“Gang-of-Four”11/25/2023423.1適配器Adapter(GOF)問題如何解決不相容的接口問題,或者如何為具有不同接口的類似構(gòu)件提供穩(wěn)定的接口?11/25/202344解決方案通過中介適配器對象,將構(gòu)件的原來的接口轉(zhuǎn)換為其它接口多態(tài)模式就是該模式的例子11/25/202345TaxMasterAdaptergetTaxes(Sale):ListofTaxLineItemsGoodAsGoldTaxProAdaptergetTaxes(Sale):ListofTaxLineItems<<interface>>ITaxCalculatorAdaptergetTaxes(Sale):ListofTaxLineItemsAdaptersuseinterfacesandpolymorphismtoaddalevelofindirectiontovaryingAPIsinothercomponents.SAPAccountingAdapterpostReceivable(CreditPayment)postSale(Sale)...GreatNorthernAccountingAdapterpostReceivable(CreditPayment)postSale(Sale)...<<interface>>IAccountingAdapterpostReceivable(CreditPayment)postSale(Sale)...<<interface>>IInventoryAdapter...<<interface>>ICreditAuthorizationServiceAdapterrequestApproval(CreditPayment,TerminalID,MerchantID)...11/25/202346:Register:SAPAccountingAdapterpostSale(sale)makePayment()theAdapteradaptstointerfacesinothercomponents<<system>>:SAPSOAPoverHTTPxxx...IAccountingAdapterUMLnotationtoindicatesomethingimplementsaparticularinterface11/25/202347Adapter

模式的應(yīng)用是對GRASP構(gòu)造塊的特殊化

(polymorphism,indirectionandprotectedvariations)可以找到數(shù)百種模式的說明理解本質(zhì)能夠使我們摒棄太多細(xì)節(jié)11/25/202348兩個(gè)問題命名習(xí)慣:將模式名字放在類型中設(shè)計(jì)中發(fā)現(xiàn)的“分析”:領(lǐng)域模型11/25/2023493.2工廠Factory(GoF)問題在適配器模式中,對外部服務(wù)有不同的接口,那么是誰創(chuàng)建了這些適配器,并且如何決定創(chuàng)建哪種類的適配器當(dāng)有特殊考慮(例如存在復(fù)雜創(chuàng)建邏輯,為了改良內(nèi)聚而分離創(chuàng)建職責(zé)等)時(shí),應(yīng)該由誰來負(fù)責(zé)創(chuàng)建對象?11/25/202351解決方案創(chuàng)建稱為工廠的純虛構(gòu)對象來處理這些創(chuàng)建職責(zé)11/25/202352ServicesFactoryaccountingAdapter:IAccountingAdapterinventoryAdapter:IInventoryAdaptertaxCalculatorAdapter:ITaxCalculatorAdaptergetAccountingAdapter():IAccountingAdaptergetInventoryAdapter():IInventoryAdaptergetTaxCalculatorAdapter():ITaxCalculatorAdapter...notethatthefactorymethodsreturnobjectstypedtoaninterfaceratherthanaclass,sothatthefactorycanreturnanyimplementationoftheinterface{

if(taxCalculatorAdapter==null){//areflectiveordata-drivenapproachtofindingtherightclass:readitfroman//externalproperty

StringclassName=System.getProperty("");

taxCalculatorAdapter=(ITaxCalculatorAdapter)Class.forName(className).newInstance();}

returntaxCalculatorAdapter;}ItmaylessentheneedforinteractiondiagramData-drivendesign11/25/202353優(yōu)點(diǎn)分離復(fù)雜的創(chuàng)建職責(zé),并將其分配給內(nèi)聚的幫助者對象隱藏潛在的復(fù)雜創(chuàng)建邏輯允許引入提高性能的內(nèi)存管理策略,例如對象緩存或再生11/25/2023543.3單實(shí)例類Singleton問題誰來創(chuàng)建工廠自身?如何訪問工廠?將實(shí)例作為一個(gè)參數(shù)進(jìn)行傳遞對那些需要可見性的對象在初始化時(shí)賦予一個(gè)持久引用單實(shí)例模式:只允許類的一個(gè)實(shí)例:這是一個(gè)單實(shí)例。對象需要一個(gè)全局和唯一的訪問點(diǎn).11/25/202356解決方案對類定義靜態(tài)方法用以返回單實(shí)例11/25/2023571ServicesFactoryinstance:ServicesFactoryaccountingAdapter:IAccountingAdapterinventoryAdapter:IInventoryAdaptertaxCalculatorAdapter:ITaxCalculatorAdaptergetInstance():ServicesFactorygetAccountingAdapter():IAccountingAdaptergetInventoryAdapter():IInventoryAdaptergetTaxCalculatorAdapter():ITaxCalculatorAdapter...singletonstaticattributesingletonstaticmethod{//staticmethodpublicstaticsynchronizedServicesFactory

getInstance(){if(instance==null)

instance:=newServicesFactory()returninstance}}UMLnotation:inaclassbox,anunderlined

attributeormethodindicatesastatic(classlevel)member,ratherthananinstancememberUMLnotation:this'1'canoptionallybeusedtoindicatethatonlyoneinstancewillbecreated(asingleton)LazyinitializationCreationworkisavoided,iftheinstanceisneveractuallyaccessedThegetInstancelazyinitializationsometimescontainscomplexandconditionalcreationlogic11/25/202358開發(fā)人員通過類的靜態(tài)方法getInstance

得到其唯一實(shí)例的全局可見性publicclassRegister{publicvoidinitialize(){…dosomework…//accessingthesingletonFactoryviathegetInstancecall

accountingAdapter=ServiceFactory.getInstance().getAccountingAdapter();…dosomework…}//othermtehods..}11/25/202359UMLnotation:Register<<Singleton>>:ServicesFactoryaa:=getAccountingAdapter()initialize()...aUMLstereotypecanindicatethatvisibilitytothisinstancewasachievedviatheSingletonpattern11/25/202360具有不同接口的外部服務(wù)問題的結(jié)論使用適配器,工廠和單實(shí)例類模式的結(jié)合,為具有不同接口的外部稅金計(jì)算器,財(cái)務(wù)系統(tǒng)等提供防止變異:RegisteraccountingAdapter:SAPAccountingAdapterpostSale(sale)makePayment()<<System>>:SAPSOAPoverHTTPxxxIAccountingAdapter:Register<<singleton>>:ServicesFactoryaccountingAdapter:=

getAccountingAdapter():Storecreate()create()[instance==null]create():SAPAccountingAdapterIAccountingAdapter:Paymentcreate(cashTendered)11/25/2023613.4策略(Strategy)問題提供更為復(fù)雜的定價(jià)邏輯,例如商店在某天的折扣,老年人折扣等如何設(shè)計(jì)變化但相關(guān)的算法或政策?如何設(shè)計(jì)才能使這些算法或政策具有可變更的能力11/25/202363解決方案在單獨(dú)的類中分別定義每種算法/政策/策略,并且使其具有共同接口11/25/202364例子PercentDiscountPricingStrategypercentage:floatgetTotal(s:Sale):MoneyAbsoluteDiscountOverThresholdPricingStrategydiscount:Moneythreshold:MoneygetTotal(s:Sale):Money<<interface>>ISalePricingStrategygetTotal(Sale):Money{

returns.getPreDiscountTotal()*percentage}???PricingStrategy......{pdt:=s.getPreDiscountTotal()if(pdt<threshold)

returnpdtelse

returnpdt-discount}11/25/202365:PercentDiscountPricingStrategyISalePricingStrategys:Sale*:st:=getSubtotal()t:=getTotal():SalesLineItem:SalesLineItemt:=getTotal(s)pdt:=getPreDiscountTotal(){t=pdt*percentage}notethattheSalesispassedtotheStrategysothatithasparametervisibilitytoitforfurthercollaboration11/25/202366語境對象需要其策略的屬性可見性PercentDiscountPricingStrategypercentage:floatgetTotal(Sale):MoneyAbsoluteDiscountOverThresholdPricingStrategydiscount:Moneythreshold:MoneygetTotal(Sale):Money<<interface>>ISalePricingStrategygetTotal(Sale):MoneySaledate...getTotal()...1*SaleneedsattributevisibilitytoitsStrategypricingStrategygetTotal(){...returnpricingStrategy.getTotal(this)}11/25/202367使用工廠創(chuàng)建策略1PricingStrategyFactoryinstance:PricingStrategyFactorygetInstance():PricingStrategyFactorygetSalePricingStrategy():ISalePricingStrategygetSeniorPricingStrategy():ISalePricingStrategy...{

StringclassName=System.getProperty("");

strategy=(ISalePricingStrategy)Class.forName(className).newInstance();returnstrategy;}Becauseofthefrequentlychangingpricingpolicyre-createoneeachtime11/25/202368:Sale<<singleton>>:PricingStrategyFactoryps:=getSalePricingStrategy():RegistermakeNewSale()create()create(percent)ps:PercentDiscountPricingStrategyISalePricingStrategy11/25/202369讀取和初始化百分比值如何確定百分比或絕對值折扣的數(shù)值?這些數(shù)據(jù)將保存于某種外部數(shù)據(jù)存儲中以便修改哪個(gè)對象讀取這些數(shù)據(jù),并確保將其分配給相應(yīng)的策略?StrategyFactory

從外部數(shù)據(jù)源中讀取數(shù)字的方法通過對其變化電賀金花店進(jìn)行分析后來確定11/25/2023703.5組合模式(CompositePattern)問題如何處理多個(gè)互相沖突的定價(jià)策略?老年人20%的折扣對于購物金額滿400元的優(yōu)先客戶給與折15%的折扣在星期一,購物金額滿500元的享受50元的折扣買一罐印度大吉嶺茶,則所有購買物品都享受15%的折扣11/25/202372解決沖突的策略對顧客最有利或者對商場最有利定價(jià)策略可能與產(chǎn)品類型相關(guān),也可能與客戶類型相關(guān),這意味著:StrategyFactory

必須知道客戶和產(chǎn)品的類型如何能夠像處理非組合(原子)對象一樣,(多態(tài)地)處理一組對象或具有組合結(jié)構(gòu)的對象呢?11/25/202373解決方案為復(fù)合和原子對象定義一個(gè)類,以使他們實(shí)現(xiàn)相同的接口11/25/202374PercentageDiscountPricingStrategypercentage:floatgetTotal(Sale):MoneyAbsoluteDiscountOverThresholdPricingStrategydiscount:Moneythreshold:MoneygetTotal(Sale):Money<<interface>>ISalePricingStrategygetTotal(Sale):Money{

returnsale.getPreDiscountTotal()*percentage}CompositePricingStrategyadd(ISalePricingStrategy)getTotal(Sale):Money{lowestTotal=INTEGER.MAXforeachISalePricingStrategy

stratinpricingStrategies{

total:=strat.getTotal(sale)

lowestTotal=min(total,lowestTotal)}returnlowestTotal}1..*CompositeBestForCustomerPricingStrategygetTotal(Sale):MoneyCompositeBestForStorePricingStrategygetTotal(Sale):MoneypricingStrategiesAllcompositesmaintainalistofcontainedstrategies.Therefore,defineacommonsuperclassCompositePricingStrategy

thatdefinesthislist(namedpricingStrategies).Saledate...getTotal()...1*pricingStrategy{...returnpricingStrategy.getTotal(this)}Theoutercompositeobjectcontainsalistofinnerobjectsandboththeouterandinnerobjectsimplementthesameinterface11/25/202375:CompositeBestForCustomerPricingStrategyISalePricingStrategys:Sale*:st:=getSubtotal()t:=getTotal():SalesLineItem:SalesLineItemt:=getTotal(s)theSaleobjecttreatsaCompositeStrategythatcontainsotherstrategiesjustlikeanyotherISalePricingStrategy*:x:=getTotal(s):SalesLineItem:ObjectISalePricingStrategyUMLnotation:thisisawaytoindicateobjectsthatimplementsomeinterface,whenwedon'twanttodeclarewhatthespecificimplementationclassesare{t=min(setofallx)}11/25/202376創(chuàng)建多個(gè)SalePricingStrategies什么時(shí)候創(chuàng)建這些策略呢?在情形中有三個(gè)地方可以將定價(jià)策略加入到符合對象中:目前商店定義的折扣,可以在銷售對象創(chuàng)建時(shí)添加顧客類型的折扣,可以在POS機(jī)獲取顧客類型時(shí)添加產(chǎn)品類型的折扣

(ifboughtDarjeelingtea,15%offtheoverallsale),可以在產(chǎn)品輸入到銷售中時(shí)添加11/25/202377:Sale<<singleton>>:PricingStrategyFactoryps:=getSalePricingStrategy():RegistermakeNewSale()create()create()ps:CompositeBestForCustomerPricingStrategyISalePricingStrategycreate(percent)s:PercentageDiscountPricingStrategyISalePricingStrategyadd(s)11/25/202378對于客戶類型折扣的第二種情形UseCaseUC1:ProcessSale…擴(kuò)展

(orAlternativeFlows):5b.Customersaystheyareeligibleforadiscount(e.g.,employee,preferredcustomer)1.Cashiersignalsdiscountrequest2.CashierentersCustomeridentification3.Systempresentsdiscounttotal,basedondiscountrules11/25/202379s:Sale:RegisterenterCustomerForDiscount(custID)byControllerbyExpertandIDstoObjects:Storec:=getCustomer(custID)enterCustomerForDiscount(c:Customer)continuedinanotherdiagrambyExpert11/25/202380s:Sale<<singleton>>:PricingStrategyFactoryaddCustomerPricingStrategy(s)ps:CompositeBestForCustomerPricingStrategyISalePricingStrategycreate(pct)s:PercentageDiscountPricingStrategyISalePricingStrategyadd(s)byExpertenterCustomerForDiscount(c:Customer)originatesinanotherdiagramc:=getCustomer()byFactoryandHighCohesionbyExpertps:=getPricingStrategy()pct:=getCustomerPercentage(c)byHighCohesionbyFactoryandCompositePassAggregateObjectasParameter11/25/202381兩個(gè)通用實(shí)踐IDs到對象Acommonpracticeinobjectdesign-totransformkeysandIDsforthingsintotrueobjectsTransformthecustomerIDintoaCustomerobject將聚集對象作為參數(shù)addCustomerPricingStrategy(s:Sale)messagewepassaSaletothefactory,andthenthefactoryturnsaroundandasksfortheCustomerandPricingStrategyfromtheSale11/25/2023823.6外觀(Fa?ade)問題可插拔的業(yè)務(wù)規(guī)則創(chuàng)建新銷售時(shí),可能要識別該銷售是否以禮券方式進(jìn)行支付。商店可能會規(guī)定如果使用禮券只可以購買一件商品。如果銷售使用禮券支付,在對該顧客找零時(shí),除了禮券之外所有其它支付類型的找零都應(yīng)該置為無效。例如,如果收銀員請求現(xiàn)金找零或更新顧客在其商店帳戶上的積分時(shí),這些請求都應(yīng)該判斷為無效….如何設(shè)計(jì)一個(gè)軟件對目前的軟件組件影響最小呢?11/25/202384解決方案定義對子系統(tǒng)的單一的接觸點(diǎn)-用一個(gè)外觀對象包裝子系統(tǒng)。外觀對象提供了一個(gè)唯一的統(tǒng)一接口,它負(fù)責(zé)與子系統(tǒng)的組件進(jìn)行協(xié)作11/25/202385子系統(tǒng)的外觀對象被稱為POSRuleEngineFacade.設(shè)計(jì)者決定在所有定義了可插拔規(guī)則的方法的開始之處調(diào)用這一外觀publicclassSale{publicvoidmakeLineItem(ProductSpecificationspec,intquantity){SalesLineItem

sli=newSalesLineItem(spec,quantity);//calltotheFa?adeif(POSRuleEngineFacade.getInstance().isInvalid(sli,this))return;linItems.add(sli);}//…}//endofclass11/25/202386Domain+Sale+Register...POSRuleEngine<<interface>>-IRule...-Rule1...-Rule2......packagenamemaybeshowninthetabvisibilityofthepackageelement(tooutsidethepackage)canbeshownbyprecedingtheelementnamewithavisibilitysymbol+POSRuleEngineFacadeinstance:RuleEngineFacadegetInstance():RuleEngineFacadeisInvalid(SalesLineItem,Sale)isInvalid(Payment,Sale)...*111/25/202387外觀一般通過單實(shí)例模式來訪問外觀

vs.適配器適配器對外部系統(tǒng)的訪問進(jìn)行了封裝,盡管它是一種外觀,它強(qiáng)調(diào)的是對各種接口的兼容性11/25/2023883.7觀察者/發(fā)布-訂閱/委派事件模型問題添加當(dāng)總價(jià)變化時(shí),GUI窗口能夠更新其顯示的能力Goal:Whenthetotalofthesalechanges,refreshthedisplaywiththenewvalueSaletotal...setTotal(newTotal)...Solution1:WhentheSalechangesthetotal,theSaleobjectsendsamessagetoawindow,askingittorefreshitsdisplayViolationofModel-ViewSeparationPrinciple11/25/202390解決方案定義一個(gè)“訂閱”or“聆聽者”接口.訂閱者實(shí)現(xiàn)該接口。發(fā)布者可以動(dòng)態(tài)的注冊對事件感興趣的訂閱者,并在事件發(fā)生時(shí),通知它們。11/25/202391<<interface>>PropertyListeneronPropertyEvent(source,name,value)SaleFrame1onPropertyEvent(source,name,value)initialize(Salesale)...javax.swing.JFrame...setTitle()setVisible()...{if(name.equals("sale.total"))

saleTextField.setText(value.toString());}SaleaddPropertyListener(PropertyListener

lis)publishPropertyEvent(name,value)setTotal(MoneynewTotal)...*propertyListeners{

total=newTotal;

publishPropertyEvent("sale.total",total);}{

propertyListeners.add(lis);}{

foreachPropertyListenerplinpropertyListeners

pl.onPropertyEvent(this,name,value);}{

sale.addPropertyListener(this)...}11/25/202392s:Salesf:SaleFrame1initialize(s:Sale)addPropertyListener(sf)PropertyListenerpropertylisteners:Objectadd(sf)PropertyListenerUMLnotation:Recallthatthereisnosuchthingasaninstanceofaninterface.Therefore,wecangeneralize(orbevague)andsimplyindicatetheinstancesastypeObject,whichisassumedtobethesuperclassofallclasses.Thisapproachcanbeusedevenifthelanguage(suchasC++)doesnotliterallydefinearootObjectsuperclass.11/25/202393s:SalesetTotal(total)*:onPropertyE

溫馨提示

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

評論

0/150

提交評論