版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件设计模式课程说明平时30%,期末70%平时:上机作业、考勤使用语言:java开发工具:Jcreator或者MyEclipce、JDK第一篇设计模式概述1.设计模式基础2.设计模式的描述语言:UML3.设计模式的原则1.设计模式基础设计模式的诞生与发展设计模式的定义与分类GoF设计模式简介设计模式的优点设计模式的诞生与发展模式的诞生与定义模式起源于建筑业而非软件业模式(Pattern)之父——美国加利佛尼亚大学环境结构中心研究所所长ChristopherAlexander博士《APatternLanguage:Towns,Buildings,Construction》——253个建筑和城市规划模式模式Context(模式可适用的前提条件)Theme或Problem(在特定条件下要解决的目标问题)Solution(对目标问题求解过程中各种物理关系的记述)设计模式的诞生与发展ChristopherAlexander设计模式的诞生与发展模式的诞生与定义Alexander给出了关于模式的经典定义:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的解决方案,无需再重复相同的工作。Apatternisasolutiontoaprobleminacontext
模式是在特定环境中解决问题的一种方案设计模式的诞生与发展软件模式1990年,软件工程界开始关注ChristopherAlexander等在这一住宅、公共建筑与城市规划领域的重大突破,最早将该模式的思想引入软件工程方法学的是1991-1992年以“四人组(GangofFour,GoF,分别是ErichGamma,RichardHelm,RalphJohnson和JohnVlissides)”自称的四位著名软件工程学者,他们在1994年归纳发表了23种在软件开发中使用频率较高的设计模式,旨在用模式来统一沟通面向对象方法在分析、设计和实现间的鸿沟。设计模式的诞生与发展GangofFour设计模式的诞生与发展ErichGamma苏黎世大学计算机科学博士,是Eclipse、JUnit
等项目主要技术负责人之一。JohnVlissides斯坦福大学计算机科学博士,原IBM研究员,于2005年11月24日因脑瘤去世,享年44岁。RalphJohnson
墨尔本大学计算机科学博士,原IBM研究员,现在波士顿顾问集团供职。RichardHelm康奈尔大学计算机科学博士,伊利诺伊大学教授。GangofFour设计模式的诞生与发展软件模式软件模式是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。软件模式并非仅限于设计模式,还包括架构模式、分析模式和过程模式等,实际上,在软件生存期的每一个阶段都存在着一些被认同的模式。软件模式可以认为是对软件开发这一特定“问题”的“解法”的某种统一表示,它和Alexander所描述的模式定义完全相同,即软件模式等于一定条件下的出现的问题以及解法。软件模式的基础结构由4个部分构成:问题描述、前提条件(环境或约束条件)、解法和效果。设计模式的诞生与发展软件模式设计模式的诞生与发展软件模式软件模式与具体的应用领域无关,在模式发现过程中需要遵循大三律(RuleofThree),即只有经过三个以上不同类型(或不同领域)的系统的校验,一个解决方案才能从候选模式升格为模式。设计模式的诞生与发展设计模式的发展1987年,KentBeck和WardCunningham借鉴Alexander的模式思想在程序开发中开始应用一些模式,在OOPSLA会议上发表了他们的成果。1990年,OOPSLA与ECOOP联合举办,ErichGamma和RichardHelm等人开始讨论有关模式的话题(BruceAnderson主持),“四人组”正式成立,并开始着手进行设计模式的分类整理工作。1991年,OOPSLA,BruceAnderson主持了首次针对设计模式的研讨会。1992年,OOPSLA,Anderson再度主持研讨会,模式已经逐渐成为人们讨论的话题。注:OOPSLA(Object-OrientedProgramming,Systems,Languages&Applications,面向对象编程、系统、语言和应用大会),编程语言及软件工程国际顶级会议,2010年改为SPLASH---Systems,Programming,LanguagesandApplications:SoftwareforHumanity设计模式的诞生与发展设计模式的发展1993年,KentBeck和GradyBooch
赞助了第一次关于设计模式的会议,这个设计模式研究组织发展成为著名的HillsideGroup研究组。1994年,由HillsideGroup发起,在美国伊利诺伊州(Illinois)的AllertonPark召开了第1届关于面向对象模式的世界性会议,名为PLoP(PatternLanguagesofPrograms,编程语言模式会议),简称PLoP‘94。1995年,PLoP‘95仍在伊利诺伊州的AllertonPark举行,“四人组”出版了《设计模式:可复用面向对象软件的基础》(DesignPatterns:ElementsofReusableObject-OrientedSoftware)一书,本书成为1995年最抢手的面向对象书籍,也成为设计模式的经典书籍。设计模式的诞生与发展设计模式的发展从1995年至今,设计模式在软件开发中得以广泛应用,在Sun的JavaSE/JavaEE平台和Microsoft的.net平台设计中就应用了大量的设计模式。诞生了越来越多的与设计模式相关的书籍和网站,设计模式也作为一门独立的课程或作为软件体系结构等课程的重要组成部分出现在国内外研究生和大学教育的课堂上。设计模式的定义与分类设计模式的定义设计模式(DesignPattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式的定义与分类设计模式的基本要素设计模式一般有如下几个基本要素:模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式,其中的关键元素包括以下四个方面:模式名称(Patternname)问题(Problem)解决方案(Solution)效果(Consequences)设计模式的定义与分类设计模式学习步骤本书将按照以下次序来学习设计模式:模式动机与定义模式结构与分析模式实例与解析模式效果与应用模式扩展设计模式的定义与分类设计模式的分类根据其目的(模式是用来做什么的)可分为创建型(Creational),结构型(Structural)和行为型(Behavioral)三种:创建型模式主要用于创建对象。结构型模式主要用于处理类或对象的组合。行为型模式主要用于描述对类或对象怎样交互和怎样分配职责。设计模式的定义与分类设计模式的分类根据范围,即模式主要是用于处理类之间关系还是处理对象之间的关系,可分为类模式和对象模式两种:类模式处理类和子类之间的关系,这些关系通过继承建立,在编译时刻就被确定下来,是属于静态的。对象模式处理对象间的关系,这些关系在运行时刻变化,更具动态性。GoF设计模式简介范围\目的创建型模式结构型模式行为型模式类模式工厂方法模式(类)适配器模式解释器模式模板方法模式对象模式抽象工厂模式建造者模式原型模式单例模式(对象)适配器模式桥接模式组合模式装饰模式外观模式享元模式代理模式职责链模式命令模式迭代器模式中介者模式备忘录模式观察者模式状态模式策略模式访问者模式GoF设计模式简介创建型模式抽象工厂模式(AbstractFactory)建造者模式(Builder)工厂方法模式(FactoryMethod)原型模式(Prototype)单例模式(Singleton)GoF设计模式简介结构型模式适配器模式(Adapter)桥接模式(Bridge)组合模式(Composite)装饰模式(Decorator)外观模式(Facade)享元模式(Flyweight)代理模式(Proxy)GoF设计模式简介行为型模式职责链模式(ChainofResponsibility)命令模式(Command)解释器模式(Interpreter)迭代器模式(Iterator)中介者模式(Mediator)备忘录模式(Memento)观察者模式(Observer)状态模式(State)策略模式(Strategy)模板方法模式(TemplateMethod)访问者模式(Visitor)设计模式的优点
设计模式是从许多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将避免我们做一些重复性的工作,而且可以设计出高质量的软件系统。设计模式的主要优点如下:设计模式融合了众多专家的经验,并以一种标准的形式供广大开发人员所用,它提供了一套通用的设计词汇和一种通用的语言以方便开发人员之间沟通和交流,使得设计方案更加通俗易懂。对于使用不同编程语言的开发和设计人员可以通过设计模式来交流系统设计方案,每一个模式都对应一个标准的解决方案,设计模式可以降低开发人员理解系统的复杂度。设计模式的优点设计模式使人们可以更加简单方便地复用成功的设计和体系结构,将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式使得重用成功的设计更加容易,并避免那些导致不可重用的设计方案。设计模式使得设计方案更加灵活,且易于修改。设计模式的使用将提高软件系统的开发效率和软件质量,且在一定程度上节约设计成本。设计模式有助于初学者更深入地理解面向对象思想,一方面可以帮助初学者更加方便地阅读和学习现有类库与其他系统中的源代码,另一方面还可以提高软件的设计水平和代码质量。2.设计模式的描述语言:UMLUML简介UMLUnifiedModelingLanguage统一建模语言统一建模语言统一建模语言UML简介UML的起源在一个现代化的工程中,人们要相互沟通和合作,就必须使用标准的工业化设计语言,用这些语言来对待开发的产品进行建模。建模过程把复杂的问题分解成为易于理解的小问题,以达到问题的求解。建模是开发优秀软件的所有活动中核心部分之一,其目的是把所要设计的结构和系统的行为联系起来,并对系统的结构进行可视化控制。UML发展历程从1994年起,GradyBooch和JamesRumbaugh在Rational软件公司开始了UML的创建工作。1995年,OOSE方法和Objectory方法的创建者IvarJacobson也加入其中。UML三位创始人正式联手,共同为创建一种标准的建模语言而一起工作,他们将开发出来的产品名称定为UML(UnifiedModelingLanguage,统一建模语言)。UML简介1997年11月,在IvarJacoboson、Grady
Booch以及JamesRumbaugh的共同努力下,UML1.1版本提交给OMG(ObjectManagementGroup,对象管理组织)并获得通过,UML1.1成为业界标准的建模语言。2003年6月,OMG技术会议上UML2.0获得正式通过,UML的发展与应用也上升到一个新的高度,越来越多的人开始学习和使用UML来进行软件建模。UML
UML是一种分析设计语言,即一种建模语言。UML是由图形符号表达的建模语言,其结构主要包括视图、图、模型元素和通用机制四部分。UML结构
(5-13)5类视图视图(View)用户视图:以用户的观点表示系统的目标,它是所有视图的核心,该视图描述系统的需求。结构视图:表示系统的静态行为,描述系统的静态元素,如包、类与对象,以及它们之间的关系。行为视图:表示系统的动态行为,描述系统的组成元素如对象在系统运行时的交互关系。实现视图:表示系统中逻辑元素的分布,描述系统中物理文件以及它们之间的关系。环境视图:表示系统中物理元素的分布,描述系统中硬件设备以及它们之间的关系。13种图用例图类图对象图包图组合结构图状态图活动图顺序图通信图定时图交互概览图组件图部署图UML常用图类图顺序图状态图UML简介UML的结构图(Diagram)用例图(UseCaseDiagram):
又称为用况图,对应于用户视图。在用例图中,使用用例来表示系统的功能需求,用例图用于表示多个外部执行者与系统用例之间以及用例与用例之间的关系。用例图与用例说明文档(UseCaseSpecification)是常用的需求建模工具,也称之为用例建模。类图类图(ClassDiagram):对应于结构视图。类图使用类来描述系统的静态结构,类图包含类和它们之间的关系,它描述系统内所声明的类,但它没有描述系统运行时类的行为。用例图与类图是UML13种图中使用频率最高的两种图。UML简介UML的结构图(Diagram)对象图(ObjectDiagram):对应于结构视图。对象图是类图在某一时刻的一个实例,用于表示类的对象实例之间的关系。包图(PackageDiagram):UML2.0新增图,对应于结构视图。包图用于描述包与包之间的关系,包是一种把元素组织到一起的通用机制,如可以将多个类组织成一个包。状态图状态图(StateDiagram):对应于行为视图。状态图用来描述一个特定对象的所有可能状态及其引起状态转移的事件。一个状态图包括一系列对象的状态及状态之间的转换。顺序图顺序图(SequenceDiagram):又称为时序图或序列图,对应于行为视图。顺序图用于表示对象之间的交互,重点表示对象之间发送消息的时间顺序。UML简介UML的结构图(Diagram)通信图(CommunicationDiagram):在UML1.x中称为协作图,对应于行为视图。通信图展示了一组对象、这些对象间的连接以及它们之间收发的消息。它与顺序图是同构图,也就是它们包含了相同的信息,只是表达方式不同而已,通信图与顺序图可以相互转换。
定时图(TimingDiagram):UML2.0新增图,对应于行为视图。定时图采用一种带数字刻度的时间轴来精确地描述消息的顺序,而不是像顺序图那样只是指定消息的相对顺序,而且它还允许可视化地表示每条生命线的状态变化,当需要对实时事件进行定义时,定时图可以很好地满足要求。
UML简介UML的结构图(Diagram)交互概览图(InteractionOverviewDiagram):UML2.0新增图,对应于行为视图。交互概览图是交互图与活动图的混合物,可以把交互概览图理解为细化的活动图,在其中的活动都通过一些小型的顺序图来表示;也可以将其理解为利用标明控制流的活动图分解过的顺序图。在UML中,顺序图、通信图、定时图和交互概览图又统称交互图(InteractiveDiagram),交互图是表示各对象如何依据某种行为进行协作的模型,通常可以使用一个交互图来表示和说明一个用例的行为。UML简介UML的结构图(Diagram)组件图(ComponentDiagram):又称为构件图,对应于实现视图。组件图用于描述每个功能所在的组件位置以及它们之间的关系。部署图(DeploymentDiagram):又称为实施图,对应于环境视图。部署图用于描述软件中各个组件驻留的硬件位置以及这些硬件之间的交互关系。UML简介UML的结构模型元素(Modelelement)在UML中,模型元素包括事物以及事物与事物之间的联系。事物是UML的重要组成部分,它代表任何可以定义的东西。事物之间的关系把事物联系在一起,组成有意义的结构模型。每一个模型元素都有一个与之相对应的图形元素。同一个模型元素可以在不同的UML图中使用,但是,无论在哪个图中,同一个模型元素都保持相同的意义和符号。UML简介UML的结构通用机制(Generalmechanism)UML提供的通用机制为模型元素提供额外的注释、修饰和语义等,主要包括规格说明、修饰、公共分类和扩展机制四种。扩展机制允许用户对UML进行扩展,以便一个特定的方法、过程、组织或用户来使用。UML简介UML的特点
工程化
规范化
可视化
系统化
文档化
智能化文字能描述的需求UML能描述的需求其他符号能描述的需求类图类与类图类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性、操作、关系的对象集合的总称。在系统中,每个类具有一定的职责,职责指的是类所担任的任务,即类要完成什么样的功能,要承担什么样的义务。一个类可以有多种职责,设计得好的类一般只有一种职责,在定义类的时候,将类的职责分解成为类的属性和操作(即方法)。类的属性即类的数据职责,类的操作即类的行为职责。类图类与类图在UML类图中,类一般由三部分组成:类名:每个类都必须有一个名字,类名是一个字符串。属性(Attributes):属性是指类的性质,即类的成员变量。类可以有任意多个属性,也可以没有属性。操作(Operations):操作是类的任意一个实例对象都可以使用的行为,操作是类的成员方法。可见性名称:类型[=默认值]可见性名称(参数列表):返回类型类图类之间的关系关联关系关联关系(Association)是类与类之间最常用的一种关系,它是一种结构化关系,用于表示一类对象与另一类对象之间有联系。在UML类图中,用实线连接有关联的对象所对应的类,在使用Java、C#和C++等编程语言实现关联关系时,通常将一个类的对象作为另一个类的属性。在使用类图表示关联关系时可以在关联线上标注角色名。类图类之间的关系关联关系publicclassLoginForm{privateJButton
loginButton;……}publicclassJButton{
……}类图类之间的关系双向关联默认情况下,关联是双向的。publicclassCustomer{privateProduct[]products;……}publicclassProduct{privateCustomercustomer;……}类图类之间的关系单向关联类的关联关系也可以是单向的,单向关联用带箭头的实线表示。publicclassCustomer{privateAddressaddress;……}publicclassAddress{……}类图类之间的关系自关联在系统中可能会存在一些类的属性对象类型为该类本身,这种特殊的关联关系称为自关联。publicclassNode{privateNodesubNode;……}类图类之间的关系重数性关联重数性关联关系又称为多重性关联关系(Multiplicity),表示一个类的对象与另一个类的对象连接的个数。在UML中多重性关系可以直接在关联直线上增加一个数字表示与之对应的另一个类的对象的个数。表示方式多重性说明1..1表示另一个类的一个对象只与一个该类对象有关系0..*表示另一个类的一个对象与零个或多个该类对象有关系1..*表示另一个类的一个对象与一个或多个该类对象有关系0..1表示另一个类的一个对象没有或只与一个该类对象有关系m..n表示另一个类的一个对象与最少m、最多n个该类对象有关系(m<=n)类图类之间的关系重数性关联publicclassForm{
privateButtonbuttons[];……}publicclassButton{…}类图类之间的关系聚合关系聚合关系(Aggregation)表示一个整体与部分的关系。通常在定义一个整体类后,再去分析这个整体类的组成结构,从而找出一些成员类,该整体类和成员类之间就形成了聚合关系。在聚合关系中,成员类是整体类的一部分,即成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。在UML中,聚合关系用带空心菱形的直线表示。类图类之间的关系聚合关系publicclassCar{privateEngineengine;publicCar(Engineengine){
this.engine=engine;}
publicvoidsetEngine(Engineengine){
this.engine=engine;}……}publicclassEngine{
……}类图类之间的关系组合关系组合关系(Composition)也表示类之间整体和部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在,部分对象与整体对象之间具有同生共死的关系。在组合关系中,成员类是整体类的一部分,而且整体类可以控制成员类的生命周期,即成员类的存在依赖于整体类。在UML中,组合关系用带实心菱形的直线表示。类图类之间的关系组合关系publicclassHead{privateMouthmouth;publicHead(){ mouth=newMouth();}……}publicclassMouth{
……}类图类之间的关系依赖关系依赖关系(Dependency)是一种使用关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系。大多数情况下,依赖关系体现在某个类的方法使用另一个类的对象作为参数。在UML中,依赖关系用带箭头的虚线表示,由依赖的一方指向被依赖的一方。类图类之间的关系依赖关系publicclassDriver{publicvoiddrive(Carcar){
car.move();}
……}publicclassCar{publicvoidmove(){......}
……}类图类之间的关系泛化关系泛化关系(Generalization)也就是继承关系,也称为“is-a-kind-of”关系,泛化关系用于描述父类与子类之间的关系,父类又称作基类或超类,子类又称作派生类。在UML中,泛化关系用带空心三角形的直线来表示。在代码实现时,使用面向对象的继承机制来实现泛化关系,如在Java语言中使用extends关键字、在C++/C#中使用冒号“:”来实现。类图类之间的关系泛化关系publicclassPerson{protectedStringname;protectedintage;publicvoidmove(){
……}publicvoidsay(){
……}}publicclassStudentextendsPerson{privateStringstudentNo;publicvoidstudy(){
……}}类图类之间的关系接口与实现关系接口之间也可以有与类之间关系类似的继承关系和依赖关系,但是接口和类之间还存在一种实现关系(Realization),在这种关系中,类实现了接口,类中的操作实现了接口中所声明的操作。在UML中,类与接口之间的实现关系用带空心三角形的虚线来表示。
类图类之间的关系接口与实现关系publicinterfaceVehicle{publicvoidmove();}publicclassShipimplementsVehicle{publicvoidmove(){
……}}publicclassCarimplementsVehicle{publicvoidmove(){
……}}类图类图实例实例说明某基于Java语言的C/S软件需要提供注册功能,该功能简要描述如下:用户通过注册界面(RegisterForm)输入个人信息,用户点击“注册”按钮后将输入的信息通过一个封装用户输入数据的对象(UserDTO)传递给操作数据库的数据访问类(DAO),为了提高系统的扩展性,针对不同的数据库可能需要提供不同的数据访问类,因此提供了数据访问类接口,如IUserDAO,每一个具体数据访问类都是某一个数据访问类接口的实现类,如OracleUserDAO就是一个专门用于访问Oracle数据库的数据访问类。根据以上描述绘制类图。为了简化类图,个人信息仅包括账号(userAccount)和密码(userPassword),且界面类无须涉及界面细节元素。类图类图实例实例解析类图注释(Comment)顺序图顺序图是最常用的系统动态建模工具之一,也是使用频率最高的交互图。它用于表示对象之间的动态交互,而且以图形化的方式描述了对象间消息传递的时间顺序。
顺序图顺序图定义
顺序图(SequenceDiagram)是一种强调对象间消息传递次序的交互图,又称为时序图或序列图。顺序图以图形化的方式描述了在一个用例或操作的执行过程中对象如何通过消息相互交互,说明了消息如何在对象之间被发送和接收以及发送的顺序。顺序图允许直观地表示出对象的生存期,在生存期内,对象可以对输入消息做出响应,还可以发送信息。顺序图顺序图定义
在软件系统建模中,顺序图的使用很灵活,通常包括如下两种顺序图:需求分析阶段的顺序图:主要用于描述用例中对象之间的交互,可以使用自然语言来绘制,用于细化需求,它从业务的角度进行建模,用描述性的文字叙述消息的内容。系统设计阶段的顺序图:确切表示系统设计中对象之间的交互,考虑到具体的系统实现,对象之间通过方法调用传递消息。顺序图顺序图组成元素与绘制在UML中,顺序图将交互关系表示为一个二维图,纵向是时间轴,时间沿竖线向下延伸;横向轴表示了在交互过程中的独立对象,对象的活动用生命线表示。顺序图由执行者(Actor)、生命线(Lifeline)、对象(Object)、激活框(Activation)和消息(Message)等元素组成。顺序图顺序图组成元素与绘制执行者是交互的发起人,使用与用例图一样的“小人”符号表示,在有些交互过程中无须使用执行者。生命线用一条纵向虚线表示。对象表示为一个矩形,其中对象名称标有下划线。激活是过程的执行,包括等待过程执行的时间。在顺序图中激活部分替换生命线,使用长条的矩形表示。消息是对象之间的通信,是两个对象之间的单路通信,是从发送者到接收者之间的控制信息流。消息在顺序图中由有标记的箭头表示,箭头从一个对象的生命线指向另一个对象的生命线,消息按时间顺序在图中从上到下排列。顺序图顺序图组成元素与绘制一个复杂的顺序图可以划分为几个小块,每一个小块称为一个交互片段(InteractionFragment)。每个交互片段由一个大方框包围,在方框左上角的间隔区内标注该交互片段的操作类型,该操作类型用操作符表示,常用的操作符包括:1)alt:多条路径,条件为真时执行。2)opt:任选,仅当条件为真时执行。3)par:并行,每一片段都并发执行。4)loop:循环,片段可多次执行。顺序图顺序图组成元素与绘制实例顺序图顺序图组成元素与绘制在顺序图中,有的消息对应于激活,表示它将会激活一个对象,这种消息称为调用消息(CallMessage);如果消息没有对应激活框,表示它不是一个调用消息,不会引发其他对象的活动,这种消息称为发送消息(SendMessage);如果对象的一个方法调用了自己的另一个方法时,消息是由对象发送给自身,这种消息称为自身消息(SelfCallMessage)。顺序图中的消息还包括创建消息和销毁消息,创建消息用于使用new关键字创建另一个对象,而销毁消息用于调用对象的销毁方法将一个对象从内存中销毁。顺序图顺序图实例实例说明某基于JavaEE的B/S系统需要提供登录功能,该功能简要描述如下:用户打开登录界面login.jsp输入数据,向系统提交请求,系统通过Servlet获取请求数据,将数据传递给业务对象,业务对象接收数据后再将数据传递给数据访问对象,数据访问对象对数据库进行操作,查询用户信息,再返回查询结果。根据以上描述绘制顺序图。顺序图顺序图实例实例解析需求分析顺序图顺序图实例实例解析-系统设计状态图对于系统中那些具有多种状态的对象,状态图是一种常用的建模手段。状态图用于描述对象的各种状态以及状态之间的转换。右图:某OA系统请假条对象状态图状态图状态图定义状态图(StatechartDiagram)用来描述一个特定对象的所有可能状态及其引起状态转移的事件。我们通常用状态图来描述单个对象的行为,它确定了由事件序列引出的状态序列,但并不是所有的类都需要使用状态图来描述它的行为,只有那些具有重要交互行为的类,我们才会使用状态图来描述,一个状态图包括一系列的状态及状态之间的转移。状态图状态图定义大多数面向对象技术都使用状态图来描述一个对象在其生命周期中的行为,对象从产生到结束,可以处于一系列不同的状态。状态影响对象的行为,当这些状态的数目有限时,就可以用状态图来建模对象的行为,状态图显示了单个类的生命周期,在不同状态下对象可能具有不同的行为。状态图适用于描述在不同用例之间的对象行为,但并不适合于描述包括若干协作的对象行为,因为一个状态图只能用于描述一个类的对象状态,如果涉及到多个不同类的对象,则需要使用活动图。状态图状态图组成元素与绘制状态(State):又称为中间状态,用圆角矩形框表示,在一个状态图中可有多个状态,每个状态包含两格:上格放置状态名称,下格说明处于该状态时对象可以进行的活动(Action)。初始状态(InitialState):又称为初态,用一个黑色的实心圆圈表示,在一个状态图中只能够有一个初始状态。结束状态(FinalState):又称为终止状态或终态,用一个实心圆外加一个圆圈表示,在一个状态图中可能有多个结束状态。转移(Transition):用从一个状态到另一个状态之间的连线和箭头说明状态的转移情况,并用文字说明引发这个状态变化的相应事件是什么。事件有可能在特定的条件下发生,在UML中这样的条件称为守护条件(GuardCondition),发生事件时的处理也称为动作(Action)。状态之间的转移可带有标注,由三部分组成(每一部分都可省略),其语法为:事件名[条件]/动作名。状态图状态图组成元素与绘制在一个状态图中,一个状态也可以被细分为多个子状态,包含多个子状态的状态称为复合状态。状态图状态图组成元素与绘制在绘制对象的状态图时,需要考虑如下三个问题:对象有哪些有意义的状态?不同状态下对象具有哪些行为?这些状态之间如何转换?状态图状态图实例实例说明某信用卡系统账户具有使用状态和冻结状态,其中使用状态又包括正常状态和透支状态两种子状态。如果账户余额小于零则进入透支状态,透支状态时既可以存款又可以取款,但是透支金额不能超过5000元;如果余额大于零则进入正常状态,正常状态时既可以存款又可以取款;如果连续透支100天,则进入冻结状态,冻结状态下既不能存款又不能取款,必须要求银行工作人员解冻。用户可以在使用状态或冻结状态下请求注销账户。根据上述要求,绘制账户类的状态图。状态图状态图实例实例解析3.设计模式的原则设计原则概述单一职责原则开闭原则里氏代换原则依赖倒转原则接口隔离原则合成复用原则迪米特法则为什么要有原则软件的可维护性和可复用性知名软件大师RobertC.Martin认为一个可维护性(Maintainability)较低的软件设计,通常由于如下4个原因造成:过于僵硬(Rigidity)过于脆弱(Fragility)复用率低(Immobility)黏度过高(Viscosity)RobertC.Martin为什么要有原则软件的可维护性和可复用性软件工程和建模大师PeterCoad认为,一个好的系统设计应该具备如下三个性质:可扩展性(Extensibility)灵活性(Flexibility)可插入性(Pluggability)PeterCoad为什么要有原则软件的可维护性和可复用性
软件的复用(Reuse)或重用拥有众多优点,如可以提高软件的开发效率,提高软件质量,节约开发成本,恰当的复用还可以改善系统的可维护性。面向对象设计复用的目标在于实现支持可维护性的复用。
在面向对象的设计里面,可维护性复用都是以面向对象设计原则为基础的,这些设计原则首先都是复用的原则,遵循这些设计原则可以有效地提高系统的复用性,同时提高系统的可维护性。面向对象设计原则概述软件的可维护性和可复用性面向对象设计原则和设计模式也是对系统进行合理重构的指南针,重构(Refactoring)是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。MartinFowler七大原则相互依赖互相补充设计原则名称设计原则简介重要性单一职责原则(SingleResponsibilityPrinciple,SRP)类的职责要单一,不能将太多的职责放在一个类中★★★★☆开闭原则(Open-ClosedPrinciple,OCP)软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能★★★★★里氏代换原则(LiskovSubstitutionPrinciple,LSP)在软件系统中,一个可以接受基类对象的地方必然可以接受一个子类对象★★★★☆依赖倒转原则(DependencyInversionPrinciple,DIP)要针对抽象层编程,而不要针对具体类编程★★★★★接口隔离原则(InterfaceSegregationPrinciple,ISP)使用多个专门的接口来取代一个统一的接口★★☆☆☆合成复用原则(CompositeReusePrinciple,CRP)在系统中应该尽量多使用组合和聚合关联关系,尽量少使用甚至不使用继承关系★★★★☆迪米特法则(LawofDemeter,LoD)一个软件实体对其他实体的引用越少越好,或者说如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,而是通过引入一个第三者发生间接交互★★★☆☆单一职责原则单一职责原则定义单一职责原则(SingleResponsibilityPrinciple,SRP)定义如下:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。其英文定义为:Everyobjectshouldhaveasingleresponsibility,andthatresponsibilityshouldbeentirelyencapsulatedbytheclass.另一种定义方式如下:就一个类而言,应该仅有一个引起它变化的原因。其英文定义为:Thereshouldneverbemorethanonereasonforaclasstochange.单一职责原则单一职责原则分析一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。单一职责原则是实现高内聚、低耦合的指导方针,在很多代码重构手法中都能找到它的存在,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。单一职责原则单一职责原则实例实例说明某基于Java的C/S系统的“登录功能”通过如下登录类(Login)实现:现使用单一职责原则对其进行重构。单一职责原则单一职责原则实例实例解析开闭原则开闭原则定义开闭原则(Open-ClosedPrinciple,OCP)定义如下:一个软件实体应当对扩展开放,对修改关闭。也就是说在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为。其英文定义为:Softwareentitiesshouldbeopenforextension,butclosedformodification.开闭原则开闭原则分析开闭原则由BertrandMeyer于1988年提出,它是面向对象设计中最重要的原则之一。在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。开闭原则开闭原则分析抽象化是开闭原则的关键。开闭原则还可以通过一个更加具体的“对可变性封装原则”来描述,对可变性封装原则(PrincipleofEncapsulationofVariation,EVP)要求找到系统的可变因素并将其封装起来。
开闭原则开闭原则实例实例说明某图形界面系统提供了各种不同形状的按钮,客户端代码可针对这些按钮进行编程,用户可能会改变需求要求使用不同的按钮,原始设计方案如图所示:现对该系统进行重构,使之满足开闭原则的要求。开闭原则开闭原则实例实例解析里氏代换原则里氏代换原则定义里氏代换原则(LiskovSubstitutionPrinciple,LSP)有两种定义方式,第一种定义方式相对严格,其定义如下:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有变化,那么类型S是类型T的子类型。其英文定义为:Ifforeachobjecto1oftypeSthereisanobjecto2oftypeTsuchthatforallprogramsPdefinedintermsofT,thebehaviorofPisunchangedwheno1issubstitutedforo2thenSisasubtypeofT.第二种更容易理解的定义方式如下:所有引用基类(父类)的地方必须能透明地使用其子类的对象。其英文定义为:Functionsthatusepointersorreferencestobaseclassesmustbeabletouseobjectsofderivedclasseswithoutknowingit.里氏代换原则里氏代换原则分析里氏代换原则由2008年图灵奖得主、美国第一位计算机科学女博士、麻省理工学院教授BarbaraLiskov和卡内基.梅隆大学JeannetteWing教授于1994年提出。其原文如下:Letq(x)beapropertyprovableaboutobjectsxoftypeT.Thenq(y)shouldbetrueforobjectsyoftypeSwhereSisasubtypeofT.芭芭拉·利斯科夫(BarbaraLiskov),美国计算机科学家,2008年图灵奖得主,2004年约翰.冯诺依曼奖得主,美国工程院院士,美国艺术与科学院院士,美国计算机协会会士。现任麻省理工学院电子电气与计算机科学系教授。她是美国第一个计算机科学女博士。周以真(JeannetteM.Wing),美国计算机科学家,卡内基.梅隆大学教授,美国国家自然基金会计算与信息科学工程部助理部长,ACM和IEEE会士。里氏代换原则里氏代换原则分析里氏代换原则可以通俗表述为:在软件中如果能够使用基类对象,那么一定能够使用其子类对象。把基类都替换成它的子类,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类的话,那么它不一定能够使用基类。里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。里氏代换原则里氏代换原则分析喜欢动物喜欢猫因为猫是动物里氏代换原则里氏代换原则实例实例说明某系统需要实现对重要数据(如用户密码)的加密处理,在数据操作类(DataOperator)中需要调用加密类中定义的加密算法,系统提供了两个不同的加密类,CipherA和CipherB,它们实现不同的加密方法,在DataOperator中可以选择其中的一个实现加密操作。如图所示:里氏代换原则里氏代换原则实例实例说明如果需要更换一个加密算法类或者增加并使用一个新的加密算法类,如将CipherA改为CipherB,则需要修改客户类Client和数据操作类DataOperator的源代码,违背了开闭原则。现使用里氏代换原则对其进行重构,使得系统可以灵活扩展,符合开闭原则。里氏代换原则里氏代换原则实例实例解析依赖倒转原则依赖倒转原则定义依赖倒转原则(DependenceInversionPrinciple,DIP)的定义如下:高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。其英文定义为:Highlevelmodulesshouldnotdependuponlowlevelmodules,bothshoulddependuponabstractions.Abstractionsshouldnotdependupondetails,detailsshoulddependuponabstractions.另一种表述为:要针对接口编程,不要针对实现编程。其英文定义为:Programtoaninterface,notanimplementation.依赖倒转原则依赖倒转原则分析依赖倒转原则是RobertC.Martin在1996年为《C++Reporter》所写的专栏EngineeringNotebook的第三篇,后来加入到他在2002年出版的经典著作《AgileSoftwareDevelopment,Principles,Patterns,andPractices》中。依赖倒转原则依赖倒转原则分析简单来说,依赖倒转原则就是指:代码要依赖于抽象的类,而不要依赖于具体的类;要针对接口或抽象类编程,而不是针对具体类编程。实现开闭原则的关键是抽象化,并且从抽象化导出具体化实现,如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要手段。依赖倒转原则依赖倒转原则分析依赖倒转原则的常用实现方式之一是在代码中使用抽象类,而将具体类放在配置文件中。“将抽象放进代码,将细节放进元数据”PutAbstractionsinCode,DetailsinMetadata(《程序员修炼之道:从小工到专家》(ThePragmaticprogrammer:fromjourneymantomaster))依赖倒转原则依赖倒转原则分析类之间的耦合零耦合关系具体耦合关系抽象耦合关系依赖倒转原则要求客户端依赖于抽象耦合,以抽象方式耦合是依赖倒转原则的关键。依赖倒转原则依赖倒转原则分析依赖注入构造注入(ConstructorInjection):通过构造函数注入实例变量。设值注入(SetterInjection):通过Setter方法注入实例变量。接口注入(InterfaceInjection):通过接口方法注入实例变量。
依赖倒转原则依赖倒转原则实例实例说明某系统提供一个数据转换模块,可以将来自不同数据源的数据转换成多种格式,如可以转换来自数据库的数据(DatabaseSource)、也可以转换来自文本文件的数据(TextSource),转换后的格式可以是XML文件(XMLTransformer)、也可以是XLS文件(XLSTransformer)等。依赖倒转原则依赖倒转原则实例实例说明由于需求的变化,该系统可能需要增加新的数据源或者新的文件格式,每增加一个新的类型的数据源或者新的类型的文件格式,客户类MainClass都需要修改源代码,以便使用新的类,但违背了开闭原则。现使用依赖倒转原则对其进行重构。依赖倒转原则依赖倒转原则实例实例解析接口隔离原则接口隔离原则定义接口隔离原则(InterfaceSegregationPrinciple,ISP)的定义如下:客户端不应该依赖那些它不需要的接口。其英文定义为:Clientsshouldnotbeforcedtodependuponinterfacesthattheydonotuse.注意,在该定义中的接口指的是所定义的方法。另一种定义方法如下:一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。其英文定义为:Onceaninterfacehasgottentoo'fat'itneedstobesplitintosmallerandmorespecificinterfaces
sothatanyclientsoftheinterfacewillonlyknowaboutthemethodsthatpertaintothem.接口隔离原则接口隔离原则分析接口隔离原则是指使用多个专门的接口,而不使用单一的总接口。每一个接口应该承担一种相对独立的角色,不多不少,不干不该干的事,该干的事都要干。(1)一个接口就只代表一个角色,每个角色都有它特定的一个接口,此时这个原则可以叫做“角色隔离原则”。(2)接口仅仅提供客户端需要的行为,即所需的方法,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。接口隔离原则接口隔离原则分析使用接口隔离原则拆分接口时,首先必须满足单一职责原则,将一组相关的操作定义在一个接口中,且在满足高内聚的前提下,接口中的方法越少越好。可以在进行系统设计时采用定制服务的方式,即为不同的客户端提供宽窄不同的接口,只提供用户需要的行为,而隐藏用户不需要的行为。接口隔离原则接口隔离原则实例实例说明下图展示了一个拥有多个客户类的系统,在系统中定义了一个巨大的接口(胖接口)AbstractService来服务所有的客户类。可以使用接口隔离原则对其进行重构。接口隔离原则接口隔离原则实例实例解析合成复用原则合成复用原则定义合成复用原则(CompositeReusePrinciple,CRP)又称为组合/聚合复用原则(Composition/AggregateReusePrinciple,CARP),其定义如下:尽量使用对象组合,而不是继承来达到复用的目的。其英文定义为:Favorcompositionofobjectsoverinheritanceasareusemechanism.合成复用原则合成复用原则分析合成复用原则就是指在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的。简言之:要尽量使用组合/聚合关系,少用继承。合成复用原则合成复用原则分析在面向对象设计中,可以通过两种基本方法在不同的环境中复用已有的设计和实现,即通过组合/聚合关系或通过继承。继承复用:实现简单,易于扩展。破坏系统的封装性;从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性;只能在有限的环境中使用。(“白箱”复用)组合/聚合复用:耦合度相对较低,选择性地调用成员对象的操作;可以在运行时动态进行。(“黑箱”复用)合成复用原则合成复用原则分析组合/聚合可以使系统更加灵活,类与类之间的耦合度降低,一个类的变化对其他类造成的影响相对较少,因此一般首选使用组合/聚合来实现复用;其次才考虑继承,在使用继承时,需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。合成复用原则合成复用原则实例实例说明某教学管理系统部分数据库访问类设计如图所示:合成复用原则合成复用原则实例实例说明如果需要更换数据库连接方式,如原来采用JDBC连接数据库,现在采用数据库连接池连接,则需要修改DBUtil类源代码。如果StudentDAO采用JDBC连接,但是TeacherDAO采用连接池连接,则需要增加一个新的DBUtil类,并修改StudentDAO或TeacherDAO的源代码,使之继承新的数据库连接类,这将违背开闭原则,系统扩展性较差。现使用合成复用原则对其进行重构。合成复用原则合成复用原则实例实例解析迪米特法则迪米特法则定义迪米特法则(LawofDemeter,LoD)又称为最少知识原则(LeastKnowledgePrinciple,LKP),它有多种定义方法,其中几种典型定义如下:(1)不要和“陌生人”说话。英文定义为:Don'ttalktostrangers.(2)只与你的直接朋友通信。英文定义为:Talkonlytoyourimmediatefriends.(3)每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。英文定义为:Eachunitshouldhaveonlylimitedknowledgeaboutotherunits:onlyunits"closely"relatedtothecurrentunit.迪米特法则迪米特法则分析迪米特法则来自于1987年秋美国东北大学(NortheasternUniversity)一个名为“Demeter”的研究项目。简单地说,迪米特法则就是指一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。迪米特法则迪米特法则分析在迪米特法则中,对于一个对象,其朋友包括以下几类:(1)当前对象本身(this);(2)以参数形式传入到当前对象方法中的对象;(3)当前对象的成
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 门诊部远程医疗服务
- 经合组织全球治理作用
- 2024版影视制作与发行合同标的
- 低碳生活的实践与体验考核试卷
- 2024年版游乐园设施临时租赁合同
- 2024版品牌授权与代理合同
- 森林改培对植被覆盖的提升作用考核试卷
- 2024年度影视版权购买合同:电影版权购买及海外发行协议
- 宠物肌肉和神经系统修复考核试卷
- 制鞋业市场调研方法研究研究考核试卷
- JJF(电子)0036-2019 示波器电流探头校准规范-(高清现行)
- 2020心肌梗死后心力衰竭防治专家共识课件
- 蓄水池防水施工方案
- 隧道的衬砌计算(85页清楚明了)
- 人教版八年级(初二)数学上册全册课件PPT
- Q∕GDW 10202-2021 国家电网有限公司应急指挥中心建设规范
- CNAS-CL01:2018(ISO17025:2017)改版后实验室首次内审及管理评审资料汇总
- 护理不良事件-PPT课件
- 商业银行两地三中心数据容灾备份方案建议书
- 审核评估报告(课堂PPT)
- 体育运动中的二次函数
评论
0/150
提交评论