CH19对象的可见性可见性:一个对象可以看见另一个对象的能力一个对象通过看见或者拥有另一个对象的引用属性可见性一个对象是另一个对象的属性参数可见性一个对象是另一个对象中的一个方法的参数本地可见性一个对象是另一个对象中的一个方法中的一个变量(本地对象)全局可见性一个对象在全局可见的为什么要有对象的可见性下例中,Register为了使用ProductCatalog的spec:=getSpecification(itemID)必须保证在Register中对ProductCatalog是可见的属性可见性从A到B的属性可见性是指B是A的一个属性publicclassRegister{…privateProductCatalogcatalog;//catalog属性…}参数可见性从A到B的参数可见性是指B作为一个参数被传递给A中所定义的一个方法。这是一种相对临时的可见性,因为只有在方法的生命周期中B是可见的。但是这种可见性是非常常见的。参数可见性转换为属性可见性局部可见性从A到B的局部可见性是指B在A中的一个方法中被声明为局部对象。这也是一种相对临时的可见性。他只存在于方法的作用域内。publicclassA{…privateintF();…}intF(){Bb;b=newB();…deleteb;}全局可见性从A到B的全局可见性是指B对A全局可见。这也是一种相对持久的可见性。A和B同时存在。这种方法并不常用。它需要使用全局实例变量。可见性的UML表示CH20将设计映射成代码实现模型:源代码数据库定义JSP/ASP/HTML等页面定义交互图和设计类图中的代码信息类的定义:(设计类图)类名属性方法类的交互:(交互图)方法中与其他类的交互不断求精和不断的改善RequirementsAnalysisDesignImplementationandTestingIterativeCyclesofDevelopmentRequirementsAnalysisDesignImplementationandTestingRequirementsAnalysisDesignImplementationandTestingTime从设计到代码的映射类、简单属性、方法架构的映射引用属性SalesLineItemquantity:IntegergetSubtotal():MoneyProductSpecificationdescription:Textprice:MoneyitemID:ItemID...Described-bypublicclassSalesLineItem{privateintquantity;privateProductSpecificationproductSpec;publicSalesLineItem(ProductSpecificationspec,intqty){...}publicMoneygetSubtotal(){...}}*1简单属性引用属性SalesLineItemquantity:IntegergetSubtotal():MoneyProductSpecificationdescription:Textprice:MoneyitemID:ItemID...Described-bypublicclassSalesLineItem{...privateintquantity;privateProductSpecificationproductSpec;}productSpec属性名用的角色名字*1从设计到代码的映射容器类型的属性SalesLineItemquantity:IntegergetSubtotal()Contains1..*Saledate:DateisComplete:Booleantime:TimebecomeComplete()makeLineItem()makePayment()getTtotal()publicclassSale{...privateListlineItems=newArrayList();}为了管理所有的销售行,需要一个集合属性,作为销售行的容器。1从设计到代码的映射方法的映射从交互图中寻求方法体进一步的扩充方法体的细节2:makeLineItem(spec,qty)enterItem(id,qty)1:spec:=getSpecification(id):Register:Sale:ProductCatalog{ProductSpecificationspec=catalog.getSpecification(id);sale.makeLineItem(spec,qty);}从设计到代码的映射方法的映射另一个例子ProductCatalog...getSpecification(...)Saledate:DateisComplete:Booleantime:TimebecomeComplete()makeLineItem(...)makePayment(...)getTotal()CapturesLooks-inRegister...endSale()enterItem(id:ItemID,qty:Integer)makeNewSale()makePayment(cashTendered:Money)publicclassRegister{privateProductCatalogcatalog;privateSalesale;publicRegister(ProductCatalogpc){...}publicvoidendSale(){...}publicvoidenterItem(ItemIDid,intqty){...}publicvoidmakeNewSale(){...}publicvoidmakePayment(MoneycashTendered){...}}1111代码实现的顺序—由低耦合开始SalesLineItemquantity:IntegergetSubtotal()ProductCatalog...getSpecification(...)ProductSpecificationdescription:Textprice:MoneyitemID:ItemID...Storeaddress:Addressname:TextaddSale(...)Paymentamount:Money...Contains1..*Contains1..*Register...endSale()enterItem(...)makeNewSale()makePayment(...)Saledate:DateisComplete:Booleantime:TimebecomeComplete()makeLineItem(...)makePayment(...)getTotal()CapturesHousesUsesLooks-inPaid-byDescribes1111111111111*Logs-completed*11234567CH21测试驱动开发和重构测试驱动下的开发(test-drivendevelopment(TDD))测试为先的思想先写测试后写产品单元测试部件的测试测试工具xUnitJava下的JUnitTDD的意义单元测试的保障产品开发成型后去写测试代码是很痛苦的单元测试往往会被忽略接口行为的细节优化设计中的斜截缺失会暴露后续迭代开发的基础后续的开发可以沿用便于发现变更的错误使用Junit和TDD测试的例子在编写Sale类之前编写TestSale类,并完成:①CreateaSalethethingtobetested(alsoknownasthefixture).②AddsomelineitemstoitwiththemakeLineItemmethod(themakeLineItemmethodisthepublicmethodwewishtotest).③Askforthetotal,andverifythatitistheexpectedvalue,usingtheassertTruemethod.JUnitwillindicateafailureifanyassertTruestatementdoesnotevaluatetotrue.使用Junit和TDD测试的例子测试方法的模式:①Createthefixture.②Dosomethingtoit(someoperationthatyouwanttotest).③Evaluatethattheresultsareasexpected.使用Junit和TDD测试的例子测试类:publicclassSaleTestextendsTestCase{Salefixture=newSale();total=newMoney(7.5);Moneyprice=newMoney(2.5);ItemIDid=newItemID(1);ProductDescriptiondesc=newProductDescription(id,price,product1);sale.makeLineItem(desc,2);assertTrue(sale.getTotal().equals(total));}}//…//testtheSale.makeLineItemmethodpublicvoidtestMakeLineItem(){//STEP1:CREATETHEFIXTURE//-thisistheobjecttotest//-itisanidiomtonameit'fixture'//-itisoftendefinedasaninstancefieldratherthanalocalvariable//setupsupportingobjectsforthetestMoney//STEP2:EXECUTETHEMETHODTOTEST//NOTE:Wewritethiscode**imagining**there//isamakeLineItemmethod.Thisactofimagination//aswewritethetesttendstoimproveorclarify//ourunderstandingofthedetailedinterfaceto//totheobject.ThusTDDhastheside-benefitof//clarifyingthedetailedobjectdesign.//testmakeLineItemsale.makeLineItem(desc,1);//STEP3:EVALUATETHERESULTS//therecouldbemanyassertTruestatements//foracomplexevaluation//verifythetotalis7.5重构重新构建代码代码的重新组织步步为营的策略重写--〉测试每次进行少量代码的重构重构哪些代码需要重构?大型方法具有大量实例变量的类具有大量代码的类明显类似的类设计中很少使用或没有使用的接口耦合度高的对象例子:P284和P285两个例子CH22UML工具UML作为草图引导思维,方便设计作图工具UML作为蓝图UML用于生成软件类的结构与编程语言开发工具的集成在IDE中添加代码的细节UML作为编程语言将UML写成的模型自动生成代码详细的UML描述前面两种使用更普遍