




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7讲.模式与对象设计2019-8-172内容责任分配设计模式GRASP模式案例谢谢观赏2019-8-1731.1引言我们已经创建了领域模型确定有什么样的方法,属于谁,对象之间如何交互,这是开发面向对象系统的核心但是如何做?谢谢观赏2019-8-174GRASP模式是帮助我们理解详细的原则和所需要的思考方法的学习工具这些模式与如何将责任分配给类相关谢谢观赏2019-8-1751.2责任和方法
责任:分类器的契约和责任对象具有责任意味着:自己做某些事情,例如创建一个对象或者进行一个计算控制或者协调其它对象的活动“一个sale对象负责创建SalesLineItems(adoing)”要想知道一个对象的责任,需要:知道私有的封装的数据知道相关的对象知道可以派生或者计算的对象“一个sale对象需要负责knowingitstotal”谢谢观赏2019-8-176责任不等同于方法,但是方法是用来完成责任的Sale
类可以定义一个或多个方法来计算总价被命名为
getTotal的方法或者发送getSubTotal
消息给每一个SalesLineItem
对象,来获取每一个类别的价格谢谢观赏2019-8-1771.3责任和交互图责任可以通过编程实现或者可以用过创建交互图来进行分配:SalemakePayment(cashTendered):Paymentcreate(cashTendered)impliesSaleobjectshavearesponsibilitytocreatePayments谢谢观赏2.模式2019-8-1792.1学习的模式在我们人类社会中,许多方面的成功经验都可以归结为模式事实上,教育的重要目标就是把学习的模式从一代传向下一代下面,我们将探索如何依据模式来学习下棋学习开发高质量的软件与学习下棋非常类似虽然失败的后果通常没有那么戏剧性谢谢观赏2019-8-17102.2成为下棋大师首先学习规则和物理需求例如,棋子的名字,合法的移动,棋盘的构成,等等然后,学习原则例如,每一个棋子的大小,如何将,如何吃子等等但是,要成为高手,还必须从其它人的棋谱中学习这些棋谱包含了许多必须理解,记忆和不断运用的模式这种棋谱也是非常多的谢谢观赏2019-8-17112.3成为一个软件设计大师首先学习规则例如,算法,数据结构和软件语言然后学习原则例如,结构化编码,模块化编码,面向对象编码,遗传编码等等但是,
为了真正掌握软件设计,还必须学习其它大师的设计–这些设计包含了必须理解,记忆和重复运用的模式这种模式也是非常多的谢谢观赏2019-8-17122.4例子模式名字:信息专家(InformationExpert)解决方案:将责任分配给拥有信息完成责任的类解决的问题:将责任分配给对象的基本原则是什么?最简单的,模式是一个命名的问题/解决对,它可以用在新的场景中,并包含了如何利用它解决新问题和对它在不同情况下的权衡讨论谢谢观赏2019-8-17132.5优点模式对专家的知识和设计中的优缺点进行了显示获取,并尽力使这种专家知识被广泛应用模式可以改进开发者之间的沟通–模式名字构成一个词汇集模式有助于面向对象技术的推广谢谢观赏2019-8-17142.6注意点不要把所有的东西都作为一个模式–开发战略性的领域模式,并重用现存的战术型模式模式作者,应用开发者和领域专家之间的密切合作在文档中清楚表明何时可以应用,何时不可以应用谢谢观赏3.GRASP分配责任的通用原则模式PatternsofGeneralPrinciplesinAssigningResponsibilities2019-8-17163.1为什么&是什么为什么在对象设计中,对责任的合理分配非常重要对责任进行分配一般是在画交互图,在编码时创建模式是一个命名的问题/求解对,它包含了好的建议和原则,这些与责任的分配相关是什么通用的责任分配软件模式(GeneralResponsibilityAssignmentSoftwarePatterns)谢谢观赏2019-8-17173.2五个重要模式信息专家(InformationExpert)创建者(Creator)高度内聚(HighCohesion)低耦合(LowCoupling)控制器(Controller)谢谢观赏3.3.1模式1:信息专家2019-8-1719解决方案将责任分配给信息专家,所谓的信息专家是拥有完成责任的信息的类谢谢观赏2019-8-1720问题设计模型可能定义成百上千个软件对象,一个应用中也可能需要将成百上千项责任进行分配目的:易于理解,维护,扩展和重用谢谢观赏2019-8-1721例子NextGENPOS应用,某些类需要知道销售总额谁负责知道销售总额?拥有需要的信息的对象类确定总额需要回答的问题我们已经有领域模型了,但是我们依然没有设计模型谢谢观赏2019-8-1722如果已经有设计模型,并且包含了相关的类,首先关注它们否则,在领域模型中,分析如何依据领域模型中的表示来创建相应的设计类谢谢观赏2019-8-1723部分领域模型谢谢观赏2019-8-1724谢谢观赏2019-8-1725SaledatetimegetTotal()SalesLineItemquantitygetSubtotal()Newmethod1*:st:=getSubtotal():Salet:=getTotal()*:SalesLineItem:SalesLineItem谢谢观赏2019-8-1726SaledatetimegetTotal()SalesLineItemquantitygetSubtotal()ProductSpecificationdescriptionpriceitemIDgetPrice()Newmethod:ProductSpecification1.1:p:=getPrice()1*:st:=getSubtotal():Salet:=getTotal()*:SalesLineItem:SalesLineItem谢谢观赏2019-8-1727这些责任在画交互图时被考虑和确定设计类责任SaleKnowssaletotalSalesLineItemKnowslineitemsubtotalProductSpecificationKnowsproductprice
谢谢观赏2019-8-1728讨论由于它们知道信息,所以对象必须做事情当信息分布在不同的对象中,他们需要相互间通过消息进行交互以分担工作在真实的世界中,对象可能没有生命的,但是在软件中,对象是“活着的”或者“有生命的”,因为它们将承担责任谢谢观赏2019-8-1729禁忌没有万能药专家模式可能在某些情况中造成耦合和内聚例如,将Sale保存在数据库我们需要将与数据库处理相关的逻辑作为Sale的责任吗?如果这样的话,我们将违反基本的结构原则:依据分离的主要的系统关注点进行设计将应用逻辑放在一个地方,将数据库逻辑放在另外一个地方(持久化服务子系统)谢谢观赏2019-8-1730优点实现了信息封装,因为对象使用它们自己的信息完成任务行为分布在拥有所需要的信息的类上谢谢观赏3.3.2模式2:创建者(Creator)2019-8-1732解决方案将创建类A的实例的责任分配给类B,如果一个或多个下面的条件为真:B聚合了(aggregates)A对象B包含了(contains)A对象B记录了(records)A对象的实例B密切使用(closelyuses)A对象B拥有传递给创建A所需要的初始化数据(因此B是创建A的专家)B是A对象的创建者谢谢观赏2019-8-1733问题谁来负责创建某些类的新实例?在面向对象系统中对象的创建是一个最普通的活动我们需要一个分配创建责任的通用原则谢谢观赏2019-8-1734例子在POS应用,谁需要负责创建
SalesLineItem
实例呢?谢谢观赏2019-8-1735sale包含了许多SalesLineItem
对象:Register:SalemakeLineItem(quantity):SalesLineItemcreate(quantity)谢谢观赏2019-8-1736讨论某些时候创建者是通过查找具有在创建时传递的初始化数据的类而发现的例如,假设Payment
的一个实例需要被初始化,在创建时,需要携带
Sale
总额信息.由于Sale
知道总价,Sale
是Payment的备选创建者对象谢谢观赏2019-8-1737禁忌许多时候,创建过程有很强的复杂性,例如由于性能原因需要回收实例,依据外部属性值有条件的创建一族相近似的类的一个实例建议采用Factory类
谢谢观赏2019-8-1738优点低耦合因为通过该模式存在的关联得到了满足谢谢观赏3.3.3低耦合2019-8-1740解决方案分配责任使得耦合度比较低谢谢观赏2019-8-1741问题耦合是对一个元素与其他元素的连接,拥有知识,依赖等关系的强烈程度的度量高耦合造成:相关的类的修改造成本地修改难以理解难以重用谢谢观赏2019-8-1742例子我们需要创建一个Payment
实例并将其与Sale关联.谢谢观赏2019-8-1743方案1(Fromthecreatorpattern):Registerp:Payment:SalemakePayment()1:create()2:addPayment(p)谢谢观赏2019-8-1744方案2谢谢观赏2019-8-1745讨论低耦合是一个在设计中时时需要记住的原则;它也是需要一直考虑的目标。这是设计者用来评估设计决策时运用的一个评价准则.但是我们知道O-O软件是一个协同系统.这意味着对象之间从某种程度上都是耦合的.因此,这是一个我们尽力去满足的原则,而不必一定遵循.谢谢观赏2019-8-1746禁忌对稳定的元素和普遍的元素的高耦合一般不是一个问题例如,一个JavaJ2EE应用对Java库(java.util,等等)的耦合没有问题,因为它们是稳定的,并被普遍使用谢谢观赏2019-8-1747优点其他组件中的变更不会造成影响由于分离,便于理解方便重用谢谢观赏3.3.4高内聚2019-8-1749解决方案责任分配以保证高内聚谢谢观赏2019-8-1750问题内聚是对一个元素的责任之间的关系是否密切相关和集中的度量低内聚的类包含了很多无关的事情,或者承担了太多的工作。它们有下面这些的问题:难以理解难以重用难以维护脆弱;常常受修改影响谢谢观赏2019-8-1751例子我们需要创建(cash)Payment
的实例并将它与Sale关联解决方案1谢谢观赏2019-8-1752解决方案2谢谢观赏2019-8-1753讨论这是一个需要放在心中的模式,就如同低耦合模式一样高度内聚的类一般具有较少的方法,具有高度相关的功能,而且不完成太多的工作谢谢观赏2019-8-1754模块化设计一些老的原则依旧很重要耦合内聚模块设计“模块化是系统的一个属性,该系统被分解成一组内聚和松耦合的模块”谢谢观赏2019-8-1755内聚和耦合-:软件工程的“阴”和“阳”谢谢观赏2019-8-1756不要教条低耦合在某些情况下是可以接受的将SQL语句放入每一个类遵循了内聚模式.但是将SQL语句分离出来并归并在一个类中更合理,因为它需要特殊的技术在分布应用中,为了改进性能,我们可以设置一个远程操作
setData
而不是分别设置
setName,setSalary
和
setHireDate.谢谢观赏3.3.5控制器(Controller)2019-8-1758解决方案将接收和处理系统事件消息的责任分配给代表下列方面的类:代表整个系统,设备或子系统代表一个与系统事件相对应的用例场景谢谢观赏2019-8-1759问题谁应该为处理输入系统事件负责?一个控制器是一个没有用户界面的对象,负责接收和处理系统事件。控制器定义了系统操作的方法谢谢观赏2019-8-1760例子在NextGen应用中,有下列几个系统操作谢谢观赏2019-8-1761actionPerformed(actionEvent):???:Cashier:SaleJFramepressesbuttonenterItem(itemID,qty)InterfaceLayerDomainLayersystemeventmessage哪一个类对象需要负责接收系统事件消息?有时被称为控制器或者协调器。它一般不工作而是将消息在分配给其他对象。控制器是一种从接口层到领域层的“方面”谢谢观赏2019-8-1762谢谢观赏2019-8-1763讨论可以使用同一个控制类来处理一个用例中的所有系统事件以维护控制器中有关用例状态的信息
一般,控制器将需要完成的工作分配给其他对象;它负责协调或者控制活动,自己不做太多工作。谢谢观赏2019-8-1764方面控制器(FacadeController)它代表了整个系统,设备或一个子系统它提供了从UI层往其他层的服务调用的主要入口
对整个物理单元的抽象,例如Register,TelecommSwitch,Phone
或
Robot代表了整个软件系统的类,例如POSSystem设计者选择用来表示整个系统,子系统的其他概念,例如如果是一个游戏软件,选择ChessGame谢谢观赏2019-8-1765用例控制器对每一个用例设置一个单独的控制器这是支持系统的人工结构例如,在NextGen应用中,例如ProcessSale等用例可以与ProcessSaleHandler类关联什么时候我们选择用例控制器?当有太多的系统事件并设计不同的过程,用例控制器是一个好的选择。它将处理它们的任务分配给那些可管理的单独的类,也提供了一个获知和推理目前进行中的场景的当前状态的基础。谢谢观赏2019-8-1766Register...endSale()enterItem()makeNewSale()makePayment()makeNewReturn()enterReturnItem()...SystemendSale()enterItem()makeNewSale()makePayment()makeNewReturn()enterReturnItem()...systemoperationsdiscoveredduringsystembehavioranalysisallocationofsystemoperationsduringdesign,usingonefacadecontrollerProcessSaleHandler...endSale()enterItem()makeNewSale()makePayment()SystemendSale()enterItem()makeNewSale()makePayment()enterReturnItem()makeNewReturn()...allocationofsystemoperationsduringdesign,usingseveralusecasecontrollersHandleReturnsHandler...enterReturnItem()makeNewReturn()...谢谢观赏2019-8-1767在统一过程中:边界对象(BoundaryObjects)
是接口的抽象实体对象(EntityObjects)
是独立于应用(经常是持久性)领域软件对象控制对象(ControlObjects)
是控制器模式中描述的用例处理器谢谢观赏2019-8-1768优点提高了重用的可能性,提供了可插拔的接口-它保证了接口层不处理应用逻辑对用例的状态进行推理保证系统操作以合法的顺序发生谢谢观赏2019-8-1769问题和解决方案“浮肿的”控制器(BloatedControllers)如果设计得不合理,控制类内聚性不强-不聚焦并处理了太多领域的责任症兆一个控制类接收所有的系统事件控制类自己处理了完成系统事件所需要的太多任务控制器有太多的属性并维持了系统或领域的信息谢谢观赏2019-8-1770接口层并不处理系统事件谢谢观赏2019-8-1771Cashier:SaleJFrameactionPerformed(actionEvent):Sale1:makeLineItem(itemID,qty)InterfaceLayerDomainLayer对于接口层的对象而言,例如Window参与决定如何处理领域过程业务逻辑是嵌入在表现层中的,而该层并不十分有用SaleJFrame不能发送该消息pressesbutton谢谢观赏4.使用GRASP模式实现Use-Case2019-8-17734.1目标设计用例的实现运用GRASP模式给类分配责任使用UML交互图标记来表示对象设计责任的分配和协作的设计是非常重要的,并且是设计,画图或者编程中具有创新性的步骤我们将试图说明软件设计是工程而不是艺术谢谢观赏2019-8-17744.2用例实现用例实现
描述了一个特定的用例在设计模型中是如何通过协作的对象来实现的.UML交互图是一种表示用例实现的通用的语言谢谢观赏2019-8-1775谢谢观赏2019-8-1776协同图(CollaborationDiagrams)
可以用于显示用例实现:RegisterenterItem():RegisterendSale():RegistermakePayment()1:???()1:???()1:???():RegistermakeNewSale()1:???()谢谢观赏2019-8-1777顺序图谢谢观赏2019-8-1778or谢谢观赏2019-8-1779契约和用例实现有可能直接从用例的文字中设计用例实现
对某些系统操作而言,契约可以用于增加描述细节契约CO2:enterItemOperation:enterItem(ItemID:ItemID,quantity:integer)CrossReferences:UseCases:ProcessSalePreconditions:ThereisasaleunderwayPostconditions:-ASalesLineIteminstancesliwascreated(instancecreation)-谢谢观赏2019-8-17801:makeLineItem(...)enterItem(id,qty)1.1:create(...):Register:Sale:SalesLineItemSatisfythestatechangeofSalesLineIteminstancecreation谢谢观赏2019-8-1781领域模型和用例实现选择合适的责任分配依赖于领域模型但是用例实现可能引起领域模型的修改谢谢观赏2019-8-1782概念vs.设计类领域模型可以用以启发我们在设计模型中定义软件类并据此命名谢谢观赏2019-8-1783PaymentamountSaledatetimePays-forPaymentamount:MoneygetBalance():MoneySaledate:DatestartTime:TimegetTotal():Money...Pays-forUPDomainModelStakeholder'sviewofthenoteworthyconceptsinthedomain.UPDesignModelTheobjectdeveloperhastakeninspirationfromthereal-worlddomainincreatingsoftwareclasses.Therefore,therepresentationalgapbetweenhowstakeholdersconceivethedomain,anditsrepresentationinsoftware,hasbeenlowered.1111inspiresobjectsandnamesinconceptualclassesdesignclasses谢谢观赏4.3NextGen迭代的Use-Case实现2019-8-17854.3.1对象设计:makeNewSalemakeNewSale
系统操作发生于当收银员在顾客到达后有东西要买,开始一笔新的买卖时ContractCO1:makeNewSaleOperation:makeNewSale()CrossReferences:UseCases:ProcessSalePreconditions:nonePostconditions:-ASaleinstanceswascreated(instancecreation)-swasassociatedwiththeRegister(associationformed)-Attributesofswereinitialized谢谢观赏2019-8-1786选择一个控制类依据控制者模式,下面是一些选择项:代表整个“系统”,设备或子系统Register,POSSystem代表一个用例场景中系统事件的接收者或者处理者ProcessSaleHandlerProcessSaleSessionFaçadeControllerUseCaseController在设计模型中,该Register
是一个软件对象。它不是一个真实的物理的收银台,而是一种软件抽象,选择这个名字可以减少领域和软件概念之间的表示鸿沟.谢谢观赏2019-8-1787在这个案例中,由于只有少数系统操作,Register
足够了谢谢观赏2019-8-1788创建新Sale软件对象Sale
必须被创建:Creator模式谁来创建它呢?Register:创建它,然后与之关联当Sale
创建后,它必须创建一个空的集合,以记录所有的将来要被添加的
SalesLineItem
实例谢谢观赏2019-8-1789:RegistermakeNewSale():Salecreate()RegistercreatesaSalebyCreatorcreate():SalesLineItembyCreator,Salecreatesanemptymultiobject(suchasaList)whichwilleventuallyholdSalesLineIteminstancesCAUTION:ThisisnotaSalesLineIteminstance.Thisisacollectionobject(suchasaList)thatcanholdSalesLineitemobjects.byCreatorandControllerthisactivationisimpliedtobewithintheconstructoroftheSaleinstance谢谢观赏2019-8-17904.3.2对象设计:enterItementerItem
系统操作发生于当收银员输入一个购买商品的itemID
和(可选)数量.ContractCO2:enterItemOperation:enterItem(itemID:ItemID,quantity:integer)CrossReferences:UseCases:ProcessSalePreconditions:Thereisanunderwaysale.Postconditions:-ASalesLineIteminstancesliwascreated(instancecreation)-sliwasassociatedwiththecurrentSale(associationformed)-sli.quantitybecamequantity(attributemodification)-sliwasassociatedwithaProductSpecification,basedonitemIDmatch(associationformed)谢谢观赏2019-8-1791选择控制类系统操作消息enterItem的责任的处理如同makeNewSale一样,采用Controller
模式继续使用Register
作为控制器谢谢观赏2019-8-1792显示商品描述和价格使用的设计原则被称为模型-视图分离原则(Model-ViewSeparation),即显示任务不应该是非GUI对象的责任尽管用例说明了在操作后描述和价格将被显示,但是设计中在此时将忽略此情况谢谢观赏2019-8-1793创建一个新的SalesLineItementerItem
契约的后置条件:显示创建,初始化和与SalesLineItem的关联
在领域模型中,Sale包含了SaleLineItem对象.因而,软件Sale
也类似地包含软件
SalesLineItem.通过Creator模式,软件Sale
是创建SalesLineItem的备选对象.谢谢观赏2019-8-1794通过将新的实例存放在商品条目集合中,Sale
可以与新创建的SalesLineItem
关联.后置条件表明,当创建SalesLineItem
时,需要一个
数量值,所以,Register
需要将此值传递给Sale,Sale必须将此值作为create
消息的一个参数.谢谢观赏2019-8-1795寻找ProductSpecificationSalesLineItem
要与匹配进入的itemID
的ProductSpecification
建立关联这意味着基于一个itemID
匹配,必须返回一个
ProductSpecification谁必须负责“基于一个itemID
匹配,必须返回一个
ProductSpecification
”?Creation模式?Controller模式?谢谢观赏2019-8-1796专家模式依据领域模型,ProductCatalog
逻辑上包含所有的ProductSpecifications我们可以设计一个ProductCatalog
对象负责该责任谁应该发送getSpecification消息给ProductCatalog
来请求ProductSpecification呢可以假设在启动用例的初始化过程中,创建长生命周期的Register
和ProductCatalog
实例,并且Register
对象与ProductCatalog对象之间存在永久关联,这样,可以让Register
给ProductCatalog
发送getProductDescription消息.可见性:一个对象“看见”或引用另一个对象的能力谢谢观赏2019-8-1797从数据库中检索ProductSpecification不可能把所有
ProductSpecification全部放在内存中但是可以把它们放在关系数据库或者对象数据库中,然后按需检索为了简单起见,从数据库中检索的问题稍后讨论谢谢观赏2019-8-17982:makeLineItem(spec,qty)enterItem(id,qty)1:spec:=getSpecification(id)2.1:create(spec,qty)1.1:spec:=find(id):Register:Sale:ProductCatalogsl:SalesLineItemSalesLineItem:SalesLineItem:ProductSpecification2.2:add(sl)byExpertbyControllerThisfindmessageistotheMapobject(themultiobject),nottoaProductSpecification.CAUTION:Thisisamultiobjectcollection(suchasaMap),notaProductSpecification.ItmaycontainmanyProductSpecifications.CAUTION:Thisisamultiobjectcollection(suchasaList),notaSalesLineItem.ItmaycontainmanySalesLineItems.byCreatoraddthenewlycreatedSalesLineIteminstancetothemultiobject(e.g.,List)谢谢观赏2019-8-17994.3.3.对象设计:endSale当收银员按下表示商品条目输入完毕的按钮后,将会产生endSale
系统操作ContractCO3:endSaleOperation:endSale()CrossReferences:UseCases:ProcessSalePreconditions:Thereisanunderwaysale.Postconditions:-Sale.isCompletebecametrue(attributemodification)谢谢观赏2019-8-17100选择控制类继续使用Register
作为控制器谢谢观赏2019-8-17101设置Sale.isComplete属性除非是控制器或者创建问题,否则信息专家模式应该是我们首先考虑的模式谁应该负责将Sale的属性
isComplete
设置为true呢?根据信息专家模式,应该是由Sale
本身完成.:RegisterendSale()s:Sale1:becomeComplete()byExpertbyController谢谢观赏2019-8-17102UML表示约束,注释和算法的方法有些时候在UML中,我们希望用文字来描述方法中的算法,或者指定某些约束约束:semanticallymeaningfullyinformationattachedtoamodelelementNote:isacommentthathasnosemanticimpact:RegisterendSale()s:Sale1:becomeComplete(){publicvoidbecomeComplete(){isComplete=true;}}{s.isComplete=true}aconstraintimplementationinanoteboxobservetheouterbracesaroundthemethodsignifyingaconstraintwithinanoteboxaconstraintthatdoesn'tdefinethealgorithm,butspecifieswhatmustholdastrue//anotecreatedbyCraig谢谢观赏2019-8-17103计算销售总额依据模型-视图分离的设计原则,我们现在不应该关注如何显示销售总额,而是必须保证如何知道销售总额除非是控制器或者创建问题,否则信息专家模式应该是我们首先要考虑应用的模式考虑处理销售的如下片断主成功场景:1.Customerarrives…2.Cashiertellssystemtocreateanewsale3.Cashierentersitemidentifier4.Systemrecordssalelineitemand…Cashierrepeatssteps3-4untilindicatesdone5.Systempresentstotalwithtaxescalculated谢谢观赏2019-8-17104销售总额所需要的信息信息专家ProductSpecification.priceProductSpecificationSalesLineItem.quantitySalesLineItemAlltheSalesLineItemsinthecurrentSaleSale谢谢观赏2019-8-17105TheSale-getTotalDesign:Saletot:=getTotal()1*:st:=getSubtotal():ProductSpecification1.1:pr:=getPrice():SalesLineItem*byExpertbyExpertrecallthisspecialnotationtoindicateiterationovertheelementsofacollection并不是每一个交互图都由系统操作消息开始,可以由设计者希望表示其交互的任何消息开始谢谢观赏2019-8-17106:Saletot:=getTotal()1*:st:=getSubtotal():ProductSpecification1.1:pr:=getPrice():SalesLineItem*{st=aSLI.quantity*aSLI.prodSpec.price}//observetheseudocodestylehere{publicvoidgetTotal(){inttot=0;foreachSalesLineItem,slitot=tot+sli.getSubtotal();returntot}}Notethesemi-formalstyleoftheconstraint."aSLI"isnotformallydefined,butmostdeveloperswillreasonablyunderstandthistomeananinstanceofSalesLineItem.LikewisewiththeexpressionaSLI.prodSpec.price.Thepointisthattheconstraintlanguagecanbeinformal,tosupportquickandeasywriting,ifdesired.谢谢观赏2019-8-171074.3.4对象设计:makePayment当收银员输入所支付的现金数额后,将发生makePayment
系统操作ContractCO4:makePaymentOperation:makePayment(amount:Money)CrossReferences:UseCases:ProcessSalePreconditions:Thereisanunderwaysale.Postconditions:-APaymentinstancepwascreated(instancecreation)-p.amountTenderedbecameamount(attributemodification)-pwasassociatedwithcurrentSale(associationformed)-ThecurrentSalewasassociatedwiththeStore(associationformed);(toaddittothehistoricallogofcompletedsale)谢谢观赏2019-8-17108创建Payment创建了Payment
的实例p(创建实例)这是一个创建职责.两个候选者:RegisterInrealdomainaregisterrecordsaccountinformationTheRegisteristhecontrollerwhichreceivesthesystemoperationmakePaymentmessageSalesale对象频繁使用Payment?谢谢观赏2019-8-17109当存在多个可选设计时,应更深入地观察可选设计所存在的内聚和耦合,以及未来可能存在的进化压力。选择具有良好内聚,耦合和在未来变化时能保持稳定的设计1:makePayment(cashTendered)1.1:create(cashTendered):Register:Sale:PaymentmakePayment(cashTendered)byControllerbyCreatorandLowCoupling谢谢观赏2019-8-17110记录Sale的日志Store...addSale(s:Sale)...SalesLedger...addSale(s:Sale)...StoreisresponsibleforknowingandaddingcompletedSales.AcceptableinearlydevelopmentcyclesiftheStorehasfewresponsibilities.SalesLedgerisresponsibleforknowingandaddingcompletedSales.SuitablewhenthedesigngrowsandtheStorebecomesuncohesive.Sale......Sale......Logs-completed5Logs-completed5**11谢谢观赏2019-8-171111:makePayment(cashTendered)1.1:create(cashTendered):Registers:Sale:PaymentmakePayment(cashTendered):Store2:addSale(s)completedSales:SalecompletedSales:Sale2.1:add(s)byExpertnotethattheSaleinstanceisnamed's'sothatitcanbereferencedasaparameterinmessages2and2.1谢谢观赏2019-8-17112计算余额谁负责计算余额?PaymentSale两个选择Payment:它需要具有
Sale的可见性,以便向Sale
请求销售总额。它将增加整体设计的耦合度.Sale:它需要具有Payment的可见性,由于它是创建者,因此并不增加总的耦合谢谢观赏2019-8-17113:Salepmt:Payment1:amt:=getAmount()bal:=getBalance()2:t:=getTotal(){bal=pmt.amount-self.total}Notetheuseof"self"intheconstraint.TheformalOCLusesthespecialvariable"self"for"this"(inJavaandC++)."self"inthisconstraintimpliestheinstanceoftheSale.AlthoughofficialOCLisnotbeingused,thisstyleisborrowingfromit.Aconstraintcanbeinanyformalorinformallanguage.谢谢观赏2019-8-171144.3.5对象设计:startUp系统需要StartUp,它包含了某些初始化系统操作.尽管这些startUp系统操作是最早要执行的操作,但是在实际设计中要将该操作交互图的开发推迟到其他所有系统操作的设计工作之后,这一实践保证能够发现所有相关初始化活动所需要的信息最后完成初始化的设计谢谢观赏2019-8-17115如何完成应用的启动应用如何启动和初始化与编程语言和操作系统有关常见的设计约定是创建一个初始领域对象
initialdomainobject.PublicclassMain{Publicstaticvoidmain(String[]args)//storeistheinitialdomainobject//ThestorecreatessomeotherdomainobjectsStorestore=newStore();Registerregister=store.getRegister();ProcessSaleJFrameframe=newProcessSaleJFrame(register); }}Howtocreatetheinitialdomainobjectisdependentontheobjecttechnologychosen.谢谢观赏2019-8-17116对startUp系统操作的解释在交互图中,发送一个create()
消息以创建初始化领域对象如果初始化对象负责过程控制,在第二个交互图中,发送一个
run
消息给初始化对象.谢谢观赏2019-8-17117POS应用startUp
系统操作发生于当经理按下POS系统的按钮后软件开始装载.假定初始化领域对象不负责控制过程,控制权将依旧在UI层.对startUP的交互图可能只是被解释为一个create()
消息.谢谢观赏2019-8-17118选择初始化领域对象初始化领域对象的类是什么?选择位于或接近于领域对象包含或聚合层次中的根类作为初始领域对象。该类可能是外观控制器,例如Register,也可能是容纳所有或大部分其它对象的某些对象,例如Store.谢谢观赏2019-8-17119PersistentObjects:Produ
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 档案管理的品质保证体系试题及答案
- 植物病虫害生物防治措施试题及答案
- 学习与应用花艺师考试试题及答案
- 月嫂证考试题及答案
- 福建事业单位考试网络学习平台操作试题及答案
- 合肥二模考试题及答案
- 大学生行为引导能力的考题分析试题及答案
- 农业经理人考试的伦理与责任试题及答案
- 高校辅导员角色与职责的试题试题及答案
- 农业经理人考试中的未来工作展望试题及答案
- 育婴行业前景及就业前景
- 2024年美容师考试理论回顾试题及答案
- Unit5Whatwereyoudoingwhentherainstormcame?SectionB1a-1d课件人教版八年级英语下册
- 2025年中铁快运股份有限公司招聘(98人)笔试参考题库附带答案详解
- 老旧城市燃气管道更新改造工程设计方案
- 中医经典临证思维与实践知到课后答案智慧树章节测试答案2025年春浙江中医药大学
- 动火和受限空间作业监护人考试题有答案
- 老年肺炎临床诊断与治疗专家共识解读(2025年)解读课件
- (正式版)HGT 6313-2024 化工园区智慧化评价导则
- 康复医学科髋关节Harris-、膝关节HSS评分表
- VALOR基本操作步骤
评论
0/150
提交评论