




已阅读5页,还剩152页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章面向对象设计,本章计划学时:810学时,本章主要内容,设计体系架构分层模式包设计软件类设计软件类软件类的属性和方法为类添加方法泛化和关联的设计对象持久化和数据库设计原则和设计模式,9.1面向对象的设计,面向对象分析和设计基于相同的模型,一般认为没有严格的阶段性和很明显的界限。面向对象设计阶段还是有明确的目标,具体内容包括:设计软件体系结构,定义系统的高层划分,确定主要组件及其接口。详细设计软件类或接口。按照架构模式定义信息系统的边界类、控制类和实体类,详细设计类的属性和方法,设计程序执行的交互图。设计数据库接口,解决面向对象模型到数据库模型的过渡。,9.2设计软件体系结构,分层模式包子系统和接口,9.2.1层,下层组件负责对上层组件提供服务。上层组件可以使用下层组件定义的服务,但下层组件对上层组件一无所知。层与层之间通常是不透明的,每一层都具有独立的职责。不同层的软件构件可以分布在多台机器上,也可以部署在同一台机器上。,1、层的概念,自从C/S出现之后,软件就被分层了:Client端的软件完成前台任务,Server端的软件完成后台任务(一般是DBServer)Client使用Server端的服务,依赖于Server端自从Internet出现之后,软件进一步分层:Client端的软件(IE浏览器)完成输入输出任务,WebServer上的程序提供业务逻辑处理,后台DBServer完成数据的存取C/S常被称为传统的两层,B/S称为三层本书的分层将不包含有关系统软件(如IE、DBMS等),仅讨论应用系统,2、分层模式,传统C/S,无明显分层两层三层四层多层基本思想:将逻辑功能相似的类封装到一个组件中。比如都是用于数据库访问的类做成数据库访问组件,所有表达销售领域对象的类做成销售组件。,传统的C/S应用程序,界面窗口程序中包含所有的内容,如输入输出、界面逻辑控制、业务逻辑运算等,数据库,经典的三层结构,数据库,销售组件,支付组件,表示层,业务逻辑层,数据访问层,数据库访问组件,经典的三层结构,表现层:处理用户和信息系统之间的交互。可以是简单的命令行窗口,也可以功能完善的图形用户界面(胖客户端程序),如基于HTML的浏览器界面(瘦客户端程序)。业务逻辑层:也称为领域层或应用层,是信息系统所有和领域相关的工作。如根据输入数据或已有数据进行计算,依赖于数据访问层获取数据或保存数据,类库形式。数据访问层:一般指与数据库的交互,主要责任是数据库记录的存取。如专门的数据访问类,简化的层次结构,表现层业务层+数据访问层甚至简化成没有分层:窗口程序=表现+业务逻辑+数据存储程序几乎不能重用,扩展的四层结构,表现层:等同于三层中的表现层。控制层/中介层:是表现层和领域层的中介层,也称应用控制器。主要表示业务逻辑中的工作流,一般针对于用例的事件流控制。此外还负责会话状态、数据的合成或分解等事务。领域层:业务逻辑中的领域类的集合,不包含复杂工作流。数据访问/数据映射层:负责将基于对象的领域层数据映射到数据库关系表中的记录。也称为数据持久层,可自行开发或采用持久化框架。,模型视图控制器架构MVC,模型:即相关的数据,它是对象的内在属性视图:是模型的外在表现形式,一个模型可以对应一个或者多个视图,视图还具有与外界交互的功能控制器:是模型与视图的联系纽带,控制器提取通过视图传输进来的外部信息转化成相应事件,然后由对应的控制器对模型进行更新;相应的,模型的更新与修改将通过控制器通知视图,保持视图与模型的一致性,3、多层的物理配置,由于应用软件封装成不同层次的独立组件,这给软件部署带来了灵活性:物理一层:所有应用软件的组件都安装配置在一台机器上。比如全部Web程序都在Web服务器上物理两层:应用软件的组件配置在两台机器上,比如一部分安装在客户端,另一部分配置在应用服务器上物理多层:客户端、一台或多台应用服务器、数据库服务器,即多台服务器的方式,这是分布式结构的一种形式。,4、多层体系结构的动机,客户对数据的访问通过中间层进行了隔离,数据库的安全性提高了应用程序被分布部署在多个物理节点上,从而增强了处理大量的用户负载或计算任务的能力,系统可靠性和响应速度得到了提高业务逻辑处于不同的中间服务器,当业务规则变化后,客户端程序基本不做改动,而且某一层的改动不会影响其他层,这也意味着更好的重用和可维护性将不同层的开发任务在开发者之间适当地分配,有效地利用开发人员的专长和开发技巧,并且能够提高并行开发能力,9.2.2包,包(package)是一种逻辑分组手段,可以取UML模型中的任何一种事物,将相关成分聚在一起,以构成更高层的组织单元包。最常用的方法是将类以包为单位进行分组,比如上一节提到的层,每一层中的所有类组成一个包。一个包可以包含其他的包,高层包被分成若干子包,子包又可以在分成更小的包。但在Java中,包还指代了物理的组织手段,如何分包,分包(软件类的分组)有两种原则:共同封闭原则(CommonClosurePrinciple)。一个包中的各个类应该是由于相似的原则而改变,即将一组职责相似、但以不同方式实现的类归为一个包中。比如按照层来进行分包就是这种类型。共同复用原则(CommonReusePrinciple)。一个包中的各个类应该一起被复用,复用其中一个可能需要同时考虑同一个包中的其他协作类。通常和业务功能相关。,包图,包图用来描述包及其依赖关系。当表现层包中的类要使用领域包中的领域类提供的服务时,表示包就依赖于领域包。,9.2.3子系统,当按照业务功能或管理职能组织包,并对这样的包进行彻底的封装实现后,一个高层的具有特定功能的可以运行的独立构件就产生了,称为子系统(subsystem)子系统具有自身独立的功能,是物理的具体软件单位,而包只是软件对象的逻辑组织方式子系统对外可以提供有限的接口,只要接口不改变,不管子系统内部发生什么变化,也不会影响到依赖于该子系统接口的其他子系统。子系统及其关系使用构件图描述,子系统的关系,财务子系统将内部操作进行了封装,但对外提供必要的接口(比如一组函数)销售子系统在执行销售业务过程中可以使用该接口对销售数据执行某些财务操作。对于销售子系统而言,依赖的是财务子系统的接口,并不需要关心财务子系统的具体实现。,9.3设计软件类,软件类是设计阶段中讨论的对象和类,也称为设计类。软件类的设计的依据:来源于分析模型中的领域类:它们通常是现实事物或概念的抽象,这些类要转换为软件世界中的类,能够通过OOP实现计算机操作需要的类:比如为了完成用例所描述的功能,需要添加一些窗口界面类。复杂用例可能涉及到多个领域类的协作,添加控制类实现部分复杂控制流,9.3.1根据分层设计软件类,从分析模型的领域类导出设计阶段中的实体类增加边界类和控制类完成程序的交互和控制。为了分辨出类的这三种不同类型,可以采用UML提供的扩展机制构造型(stetreotype)及其表达符号来定义模型元素构造型,Rose中不同构造型的图符,系统边界,对象行为的控制和协调,系统服务和信息,分层的软件类协作实现一个用例,1、边界类,边界类的职责是完成系统与其参与者之间的交互。接收来自用户和外部系统的信息与请求将信息与请求提交给用户和外部系统通过用例图可以得知每个边界类至少应该与一个参与者有关,参与者类型不同,边界类的设计也不同边界类包括屏幕窗口、通信接口、打印机接口、传感器、终端以及专用API(应用程序编程接口)等软件对象。对于图书馆系统来说,参与者都是系统用户,因此边界类只有窗口界面这一种形式。假如考虑提供馆际互借业务,那么系统就会产生与其他外部合作的图书馆系统的交互,这时与外部系统间的通信接口也是一种边界类,识别边界类,根据用例图,每个参与者与一个用例交互,必定导出一个边界类,2、实体类,实体类来源于领域模型中的类。实体类是一个软件对象,表示了领域对象的信息,以及具有与它所表示的信息有关的复杂行为。实体类反映的信息需要在系统中进行处理,并需要进行持久化存储。,边界类和实体类的交互,边界类仅负责数据的输入和输出,不应承担和数据处理有关的业务逻辑边界类通过与实体类的交互,获得有关数据处理的结果,3、控制类,控制类代表协调、排序、事务处理以及对其他对象的控制,经常用于封装与某个具体用例有关的控制流。控制类处理和协调主要的动作和控制流,并将任务委派给其他对象。根据分层原则,控制类不封装与参与者交互有关的内容,也不封装与系统处理的长效持久的信息有关的问题,这些问题分别由边界类和实体类进行封装。,识别控制类,当用例逻辑较为复杂,并涉及到多个实体类时,可以考虑采用控制类简化方案:控制类的职责合并给边界类,不同类的职责分配,向下依赖的关系:边界类负责与参与者的交互(输入数据、显示数据)为GUI的每个弹出式屏幕创建一个边界对象。控制类(可选)负责一个用例的事件流,或部分复杂数据流实体类负责数据的封装为每个领域类创建一个实体类,图书馆系统的界面类,图书馆系统的控制类,图书馆系统的实体类,9.3.2详细设计类的属性,属性类型和初值属性的类型和默认的初始值应该在设计模型中表示出来。类型和属性名之间用冒号隔开,等号之后写初值。选择的数据类型最好是目标语言中可用的。属性的可见性类中的每个属性可以有可见性定义,指定该属性可以被其他类利用的程度,UML定义了4种属性可见性:公有(public)“+”受保护(protected)“#”私有(private)“-”包(package)“”,图书馆类图,9.3.3建立用户界面原型,用户界面原型是一个草图,包含用例提到的系统和用户进行交互的必要元素界面原型不描述太多细节,通常包含以下内容:需要由用户输入到系统中的数据窗口或表格;需要由系统执行的操作按钮;系统应及时做出回应的事件;需要由系统输出给用户的数据窗口或消息。,图书馆系统的借书界面,图书馆系统的还书界面,交互对话设计,9.3.4详细设计类的方法,每个软件类都有行为,这些行为是它们应承担的职责,也就是OOP中软件类的方法。职责是在对象设计过程中被分配给类的,该过程是用例驱动的通过对用例进行实现,可以构造出系统最重要的的动态模型顺序图或通信图,完整的交互模型,交互模型的设计内容:对象职责的识别,意味着对象协作过程中消息的分发定义消息的完整格式将消息映射为类的操作,并在实现时转化为类的方法,职责完成的两种情况,职责是在对象设计过程中表现为分发给对象的消息,消息响应有两种情况:由某个对象独立承担,比如“计算超期天数”由一个Loan对象负责主要由一个对象负责,但该对象将职责进行了二次分配,即又发送了请求消息给其他对象。比如“负责计算订单总额”应该由一个Order对象负责,Order类受到该消息后,又请求OrderItem对象提供每个订单项的小计金额(数量*单价)。,职责的两种类型,由以上例子,可知职责有两种类型:行为型:即对象本身的方法。比如进行一项计算、被创建时的初始化、执行控制或协调的各项活动。了解型:对象应掌握的信息。比如对象自身的数据和属性、相关联的对象以及能够派生或计算的对象,如Loan类需要了解借出和归还日期(属性),以及所借资源的有关情况,即ResourceItem或ResourceTitle对象(关联对象)。,1、详细设计消息,消息的表达式语法return:=message(parameter:parameterType):returnType如果类型信息非常明显或不重要的话,可以省略书写,如:reader:=getReader(cardID:String)消息的序号消息的次序用自小到大的顺序号来表示。按照消息的完成情况,消息可以有嵌套消息。嵌套消息的序号按照层次编号,所有嵌套的子消息都是服务于其上层消息。,嵌套消息,嵌套消息含义与结构化方法中的模块调用相同结构化方法中模块都是单个的,没有分组。面向对象方法也强调模块的概念,但模块都有一个主人对象OOD中的模块划分要解决两个问题:任务如何分解为子任务?各个任务应由谁承担?,嵌套消息示例,计算超期罚金,最高不超过书价Loan对象在计算超期罚金时还需要获取资源的价格和罚金标准,因此向ResourceItem发送请求价格的消息,向FineRule发送超期罚金标准,而ResourceItem对象并不记录价格,因此请求价格的消息还需要发送给ResourceTitle对象。,嵌套消息示例代码,Loan:getTotalFine():doubletitlePrice=itemObject.getTitlePrice();finePerDay=fineObject.getOverDueFine();doublefineAmount=finePerDay*(this.returnDatethis.dueDate);if(fineAmount0ThenVerifyUser=True成功EndIfEndIfEndIfEndFunction,User类操作代码,PublicFunctionqueryByUserName(userNameAsString)AsBooleanDimrstAsNewADODB.RecordsetDimsqlAsString,strGroupNameAsStringqueryByUserName=Truesql=select*fromT_userwhereUserName=+userName+rst.Opensql,mConnection,adOpenStatic,adLockReadOnly,adCmdTextIfrst.RecordCount0ThenmUserName=rst(UserName)mFullName=rst(FullName)mPassword=rst(Password)strGroupName=rst(GroupName)Setgroup=NewBusiness.group创建用户组对象group.groupName=strGroupNameElsequeryByUserName=FalseEndIfrst.CloseEndFunction,User类的操作,取得用户的组对象PublicFunctiongetGroup()AsBusiness.groupSetgetGroup=groupEndFunction,Group类的操作代码,PublicFunctiongetGroupRights()AsCollectionDimrgAsBusiness.RightDimrstAsNewADODB.RecordsetDimsqlAsStringDimrecCountAsIntegerSetrights=NewCollectionsql=select*fromT_grouprights,T_rightwhereGroupName=+mGroupName+andT_grouprights.RightID=T_right.RightIDrst.Opensql,mConnection,adOpenStatic,adLockReadOnly,adCmdTextIfrst.RecordCount0Thenrst.MoveFirstDoWhileNotrst.EOFSetrg=NewRightrg.rightID=rst(T_right.RightID)rg.rightDesc=rst(RightDesc)rights.Addrgrst.MoveNextLoopEndIfrst.CloseSetgetGroupRights=rightsEndFunction,9.4对象持久化与数据库,软件中的对象在程序中定义的对象,在系统运行期间其生命周期包含创建、使用和消亡三个阶段。因为程序所有代码和数据在运行时载入到内存,程序运行结束它们都要从内存中释放,所以这些对象实例都是瞬时的或暂时性的。信息系统中的对象一个信息系统中的领域类指代了系统中有意义的事物,这些领域对象及其所承载的信息是长期的,甚至是永久的。这些持久对象就是指生存期可以超越软件的一次执行时间而长期存在的对象。软件对象如何持久化?,持久化对象,持久对象就是指生存期可以超越程序的任意一次执行时间而长期存在的对象。比如新建了一名读者对象,程序结束后该读者的基本信息将转化为持久保存的读者数据,这个过程也是通常所说的“物化”。反过来,持久后的数据需要取出并重新生成对象,这个过程称为“反物化”。通常实体对象都会成为持久对象,实体类也称为持久类。,9.4.1几种持久化方案,文件从文件查询有关数据来初始化对象或创建一个新对象。对象发生改变或需要保存,则将对象数据写入到文件中(如XML文件)。但复杂灵活的数据存取和查询难以实现。面向对象数据库管理系统(OODBMS)一种理想的基于存储和管理永久对象的对象管理系统,只要程序员声明某个对象是永久的,OODBMS中数据库模型和对象模型一致。对象的存储、恢复、转换等问题由OODBMS自动解决。但目前尚未达到广泛应用的阶段。成熟的关系型数据库系统(RDBMS)关系型数据库以二维表中的一条记录来保存某个对象,记录的字段对应对象属性,继承关系或关联关系通过表之间的联系表现。对象与关系两个概念之间存在“阻抗”,因此需要进行映射。该方案是目前最普及的选择。其他的存储机制还有层次数据库、网状数据库等等,持久化设计的步骤,确定持久类及其持久属性确定持久化方案设计XML文件模式(Schema)或设计关系数据库的模型根据持久化方案设计持久化方法或持久化组件,关系型数据库的持久化方案,在确定持久类及其持久属性之后,还要解决以下问题:实体类如何对应到关系中的表呢?类的继承关系和对象关联如何体现?关系数据库的操作总结起来就是CRUD操作:创建记录(Create)、查询记录(Retrieve)、修改记录(Update)和删除记录(Delete),这些操作应该由谁来实现?什么时候使用?对象实例是内存的一个单元,使用实例名来标识,表中的记录则采用唯一的主键码来识别,如何实现特定对象实例和记录的一一对应呢?,9.4.2ORM设计问题,无论自己编写代码实现持久化,还是使用持久化组件,都要解决一个问题,那就是:对象与数据库的映射关系。采用关系型数据库实现对象的数据存储,这种映射也称为对象-关系映射ORM(ObjectRelationalMapping)。ORM的设计包括:确定对象和表的映射关系确定软件实现构架,1、对象-关系的映射,类映射到表关联关系的映射继承关系的映射,持久类映射到表,在一个第三范式的关系数据库中,表中每一行(每个“元组”)都被认为是一个对象。表中的列则对应于持久类的持久属性(注意:持久类也可能有临时属性)。在没有其他关联类的简单情况下,这两种模型间的映射将会很简单。类的属性对应于列,其数据类型转换为列允许的数据类型之一。,关联关系的映射,两个持久对象间的关联关系在OOAD中通常表现为一个对象存放了另一个对象的对象引用(也称为关联属性),而在表中则表现为外键。外键是一个表中的一列,其中存放所关联对象的主键值。对于对象关联中的特殊类型组成聚集,因为整体对象和部分对象具有相同的生存周期,因此为了在数据模型中实现引用完整性,数据库详细设计时还需要实施删除约束,比如删除图书馆某个资源品种就必须同时删除所有的资源项。以及参照完整性的设计,Reader,Loan,借阅,1,*,读者:读者编号,读者姓名,读者单位,当前限额借书记录:ID,读者编号,馆藏流水号,借书日期,到期日期,归还日期馆藏项:馆藏流水号,当前状态,ResourceItem,0.11,记载,继承关系的映射,三种可选方式:继承关系树的每个类对应一个表:使用不同的表来分别表示父类和子类。继承关系树的每个具体类对应一个表:将所有父类的属性复制为子类表中不同的列,父类不建立对应的表。继承关系树只对应一个表:使用一张表来描述父类和所有子类的属性,额外还需要增加一个列表示对象所属的子类型。,Book,Disc,ResourceTitle,1、三个表:品种:ISBN,名称,作者,出版日期,价格书籍:ISBN,开本光盘:ISBN,光盘类型,盘片数量,2、两个表:书籍:ISBN,名称,作者,开本光盘:ISBN,名称,作者,光盘类型,盘片数量3、一个表品种:ISBN,名称,作者,品种类别,开本,光盘类型,盘片数量,2、持久化软件架构设计,(1)在领域层实现,即直接在实体类中编写SQL语句访问数据库,或者为了减少数据库操作的代码数量,编写一个公用的数据访问类,各实体类将组装好的SQL语句传递给该类以实现数据库访问。(2)设计简单的数据映射层实现数据访问,即把SQL访问从业务逻辑中分离出来,放到独立的类中。当每个实体类映射为一张表时,可以为每个实体类建立一个数据访问类,一般包括数据查找方法以及更新、插入和删除方法。(3)设计功能独立具有数据映射器的持久层。业务逻辑层完全不用了解数据的存储,应用程序中的对象通过设置与表的映射关系后,可以在开发人员对底层数据库及其模型毫不知情的情况下实现数据的持久化。映射关系通过数据映射器来具体实施,它是分离内存对象和数据库的一个软件层,其职责是在内存对象和数据库之间传递数据并保持它们彼此独立。,三种设计方法的举例,参见用户权限的VB程序,实体类负责数据库的访问参见微软PetShop程序,数据库访问通过编写数据访问层的类来实现。比如业务层的类Order,有Insert、getOrder方法分别完成保存和查询的功能,这些方法中使用了数据访问层的类来读写数据库网上可查阅Hibernate示例程序,代码中不需要编写SQL语句,9.5面向对象设计原则,设计原则结构化方法:低耦合、高内聚、模块化面向对象方法:封装、重用、SRP、OCP、DIP,为什么要讨论设计原则?,设计良好的系统:容易理解、可变更性好、易于重用设计糟糕的系统如同腐化食物散发出臭味(smell),有以下症状:僵化性(rigidity):系统很难改变,即使一个简单的改动也会导致大量有耦合关联的其他部分的连锁反应。脆弱性(fragility):改变系统的某个部分会破坏许多无关的其他部分固化性(immobility):很难将系统分解成可供其他系统重用的部件。黏滞性(viscosity):当软件需要改动时,设计不容易保持稳定,逐渐脱离原形而走样。不必要的复杂性(needlesscomplexity):过分的或超前的设计不必要的重复性(needlessrepetition):大量代码重复,修改一处时,需要对每个重复副本一一修改。晦涩性(opacity):很难阅读理解,不能很好地表现出设计者的意图。,设计原则,采用设计原则来帮助消除臭味:单一职责原则(TheSingleResponsibilityPrinciple,简称SRP)开放-封闭原则(TheOpen-ClosePrinciple,简称OCP)Liskov替换原则(TheLiskovSubstitutionPrinciple,简称LSP)依赖倒置原则(TheDependencyInversionPrinciple,简称DIP),1、单一职责原则SRP,即内聚性原则。高内聚原则可以从模块设计引申到类的设计。一个类承担的职责过多,任一个职责的变化可能会削弱或者抑制该类完成其他职责的能力,并影响到构建、测试和部署等活动。多个职责的耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏。,职责过多的职工类,分离职责到不同的类,对“杂凑类”进行分解,2、开放封闭原则OCP,软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改的。“变化才是不变的真理”,但通过设计使得系统能够适应改变又能保持相对稳定,避免僵化的设计。开放-封闭原则实现两个目标:“对于扩展是开放的”(openforextension)。这意味着模块的行为是可扩展的,从而使其具有满足那些改变的新需求。“对于更改是封闭的”(closedformodification)。当对模块进行扩展时,不必改动模块的源代码或二进制代码(如DLL库文件)。自相矛盾吗?,什么是不封闭、不开放,如下的模型可以处理月薪制和时薪制职工工资,如果还要增加一种职工类型,其计酬方式不同(如提成制),则必定要修改Employee类,如何改进,利用抽象机制封闭:Employee及其子类是封闭的开放:可以派生新的子类,实现新的需求,3、Liscov替换原则LSP,实现OCP的主要机制是抽象和多态。怎样设计最佳的继承层次,BarbaraLiskov在1988年首次提出LSP:子类型(subtype)必须能够替换掉它们的基类型(basetype)。假设S是T的子类型,所有使用了T对象的程序(也称客户程序),用S对象替换T对象后,仍能成功执行。LSP是多态顺利实现的保证,从而使OCP成为可能。因为正是子类型的可替换性才使得使用基类的模块在无需修改的情况下就可以扩展。增加或修改任何一个子类型,基类不用修改(封闭)基类的使用者(客户程序)通过多态得到扩展或修改过的行为(开放)。,一个使用继承的例子,正方形是长方形的一种特例,会发生什么情况?,正方形有独特的行为方式通过覆盖父类的有关方法来实现子类行为,客户程序如何能了解,长方形的使用者按照长方形的特点来调用SetWidth和SetHeight两个函数,并测试面积,代码如下:voidtestArea(Rectangle如果传递进来的是Square对象又会如何呢?显然会出现断言错误,测试失败。对于客户程序来说,模型中的层次结构是脆弱的,因为违反了LSP替换原则,Square对象和Rectangle对象的行为方式不相容,这样的抽象即使采用虚函数也无法实现子类对父类的替换。违反LSP替换原则,多态的使用是不安全的。,4、依赖倒置原则DIP,高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。结构化设计时,高层模块总是依赖于低层模块。面向对象的分层模式中也是高层的类依赖于底层的类。按照自上而下的依赖关系,高层的策略设置模块往往是无法重用的,如果设法让高层模块独立于低层模块,则实现重用就变为可能。依赖倒置原则的启发式建议是“依赖于抽象”,具体做法是将高层需要的服务声明为抽象接口,高层使用这些接口,低层模块实现这些接口,使得高层不再依赖于低层,而是依赖于抽象接口,同样低层也依赖于抽象接口。,传统的依赖层次,高层使用低层的对象及其服务,都依赖于抽象,设计抽象接口,上层类使用接口,下层类实现接口这样Button类也可以得到重用,也许是开关灯,也许是开关电视,根据创建具体对象完成多态的行为。,如何遵守设计原则,设计原则不是死记硬背,而是要灵活运用一些成熟的设计模式可以帮助我们解决实际问题,并且符合设计原则,9.6设计模式,GRASP对象职责分配模式GRASP(GeneralResponsibilityAssignmentSoftwarePattern)是一组通用的基本原则和惯用的设计方案,用来指导对象职责的分配和交互图的创建。OOAD经典著作UML和模式应用进行了总结和应用。GoF23种设计模式由四人组的专著设计模式一书总结了广为应用的23种设计模式,每种模式解决了一个特定问题,包括一组合适的对象和对象接口,以及对象间协作的方式。,模式,模式在现实生活中随处可见,模式是对成功应用经验的总结与复用,模式无处不在,好莱坞电影模式社会题材、动作片、言情片、历史题材片中国象棋开局当头炮、顺炮、列炮、屏风马围棋布局星小目、三连星、中国流、宇宙流古代行军布阵八阵图、天门阵、一字长蛇阵建筑、服装、交通、社会、文化诸多模式,计算机中的模式?,如何在已排序的值列表中查找一个元素?,1.将列表一分为二。将要查找的值与中间元素的值相比较。如果相等,就找到我们要查找的值。如过要查找的值小于中间元素的值,将中间点设置为列表的新的顶点(并再次将列表一分为二)。如果要查找的值大于中间元素的值,将中间点设置为列表的新的尾点。然后再将列表一分为二。继续这种分割过程,直到列表不能再分为止。此时,如果要查找的值不再最后两个元素中,它就不在这个列表中。,2.使用二分查找,9.6.1模式的定义,美国建筑设计大师ChristopherAlexander,在他出版的一本关于城市规划和建筑设计的著作建筑的永恒方法中,是这样描述模式的:模式是一条由三部分组成的规则,它表示了一个特定环境、一个问题和一个解决方案之间的关系。每一个模式描述了一个在我们周围不断重复发生的问题以及该问题解决方案的核心内容。这样,你就能一次又一次地使用该方案而不必做重复劳动。Eachpatterndescribesaproblemwhichoccursoverandoveragaininourenvironments,andthendescribesthecoreofthesolutiontothatproblem,insuchawaythatyoucanusethissolutionamilliontimesover,withouteverdoingitthesamewaytwice.-ChristopherAlexander,APatternLanguage,1977,设计模式名成为专业词汇,讨论设计方案时,使用模式名能简化描述,设计模式,是:优秀的设计范例从优秀设计方案中发现和总结出来的经验在实践中反复出现的设计问题的优秀解决方案设计者相互交流的基本术语:设计语言培养优秀设计师的一条捷径不是:面向对象设计的框架可供简单组合的设计元件发明创造出来的创新思路解决面向对象设计问题的完整方案,设计模式的基本要素,名称:用于助记,形象表示这个模式问题:这个模式可以解决什么问题解决方案:这个模式怎样解决这个问题的步骤与方法效果:使用这个模式与不使用这个模式有什么区别,它有什么优点和缺点,一个问题可以有多种解法,好的解法都可以找到很多种,每种都有优缺点,某个模式也不一定永远是最好的,设计模式的基本思想-1,软件是在不断进化的需求在不断改变,所以软件应该适应变化设计模式是为了让软件更加适应变化,有更多的可复用性;就是有变化时你不用从头重写一次这个软件如何适应变化?就应该封装变化,让变化的影响最小封装复杂性,提供简单的接口,设计模式的基本思想-2,遵守上述设计原则:松耦合针对接口编程,而不是针对实现编程继承、组合、委托、多态、参数化,9.6.2GoF设计模式,GangofFour,简称GoF,他们是:ErichGammaRichardHelmRalphJohnsonJohnVlissides著作设计模式,23种GoF模式,GoF模式分类-1,根据模式的目的(用来完成什么工作的)创建型模式结构型模式行为型模式根据模式的作用范围(是处理类还是处理对象的):类模式对象模式,GoF模式分类-2,创建型模式创建型类模式将对象的部分创建工作延迟到子类创建型对象模式将它延迟到另一个对象中结构型模式结构型类模式使用继承机制来组合类结构型对象模式描述了对象间的组装方式行为型模式行为型类模式使用继承描述算法与控制法行为型对象模式则描述一组对象怎样协作完成单个对象无法完成的工作,GoF举例-State模式-1,/修改LegoSystem源代码caseBLUE:BlueProcess();break;,LegoSystem:ProcessColor()switch(color)caseRED:RedProcess();break;caseGREEN:GreenProcess();break;caseYELLOW:YellowProcess();break;,State模式-2,目的:允许一个对象在其内部状态改变时改变其行为结构适用性:一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示State模式将每一个条件分支放入一个独立的类中;这使得可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化,State模式-3,Yellow,process(),Red,process(),Green,process(),LegoSystem,color:Color,processColor(),Color,process(),State模式-4,LegoSystem:ProcessColor()Color-Process();CColorpublic:virtualvoidProcess();voidCRed:Process()RedProcess();voidCGreen:Process()GreenProcess();voidCYellow:Process()YellowProcess();,/有了新的状态和操作/仅需要增加新的类,/原有代码不需要任何变动voidCBlue:Process()BlueProcess();,学习模式的过程,这些模式我们能用吗?能,但可能还不能消化初学者能用什么?更小粒度的模式,9.6.3GRASP通用职责分配软件模式GeneralResponsibilityAssignmentSoftwarePattern,对象交互和职责分配的设计质量影响到系统的可维护性、可读性、可重用性和可扩充性GRASP模式用于建立交互图和职责分配信息专家(InformationExpert)创建者(Creator)高内聚(HighCohesion)低耦合(LowCoupling)控制者(Controller)多态(Polymorphism)纯虚构(PureFabrication),1、信息专家模式,问题:什么是最基本的职责分配原则?解决方案:将一个职责分配给信息专家(掌握了为履行职责所必需的信息的类)举例:在图书馆系统中,谁负责计算逾期罚款,信息专家模式举例,在销售点终端应用系统中,一些类需要知道一次销售的总额(也可以是订单、处方单),销售条目quantity:Integer,包含,参考描述,专家模式的职责分配,确定一次销售的总额,需要知道该销售对应的销售项条目,只有销售对象知道这些信息,因此按照专家模式,销售类作为信息专家应该履行该职责。销售总额是各项条目的金额的总和,而项目金额通过单价和数量计算得出,只有销售项条目知道数量和相关的产品描述,它是履行该责任的信息专家。商品单价由其信息专家产品规格说明提供。,自己做对象都是活的可以承担职责,专家模式的设计结果,借书程序的设计问题,publicBorrowControl(StringreaderID,StringbookID,DefaultTableModeldefaultModel,JTabletable)if(readerID.equals()elseif(bookID.equals()elseUseruser=newUser();user.setUserID(Integer.parseInt(readerID);Loanloan=newLoan(Integer.parseInt(readerID),Integer.parseInt(bookID);if(user.getUserID()=false)JOptionPane.showMessageDialog(null,请先登记再借书!);elseif(loan.getUserID
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025工业品买卖合同范本下载
- 2025技术开发委托合同模板
- 多学科诊疗实践探索
- 专师资培训课件
- 专家医生科普知识培训课件
- 2026届山东省济宁市田家炳中学七年级数学第一学期期末学业质量监测模拟试题含解析
- 2026届安徽省合肥市滨湖区寿春中学九年级数学第一学期期末质量检测模拟试题含解析
- 汽车行业从业者职业发展路径解析
- 山东省安丘市东埠中学2026届数学八年级第一学期期末质量跟踪监视试题含解析
- 2025合同模板股权众筹项目委托融资合同
- 2025年广东省公务员录用考试《行测》真题及答案解析
- 2026步步高六册同步物理必修3-章末检测试卷(三)
- 兴东线泰州段航道整治工程环评资料环境影响
- 踝关节超声检查
- 【成都】2025年四川成都高新区“蓉漂人才荟”招聘事业单位工作人员10人笔试历年典型考题及考点剖析附带答案详解
- 冠脉介入培训心得体会
- 中医高血压糖尿病课件
- 美容科规章制度
- 初中数学问题解决策略 特殊化教案2024-2025学年北师大版(2024)七年级数学下册
- 钢卷储存及装卸安全管理办法
- 患者发生静脉炎应急演练方案
评论
0/150
提交评论