《教学课件第7章 建立设计模型.ppt》由会员分享,可在线阅读,更多相关《教学课件第7章 建立设计模型.ppt(180页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、2022年4月23日星期六第1页第7章 建立设计模型o设计模型是对分析模型的细化;o设计模型和分析模型之间并没有严格的界线;o分析模型偏重于理解问题域,描述软件要做什么,而设计模型则偏重于理解解决方案,描述软件究竟要如何做;o分析模型只对系统作高层次的抽象,不关心技术与实现底层的细节,而设计模型则需要得到更详细更接近于程序代码的设计方案;o分析模型侧重于对象行为的描述,而设计模型则侧重于对象属性和方法的描述;o分析模型只关注功能性需求,而设计模型还需要考虑非功能性需求。2022年4月23日星期六第2页第7章 建立设计模型o7.1 设计模式的选择与应用o7.2构建设计类o7.3 详细设计类o7.
2、4 设计类间关系 o7.5 活动图o7.6 状态图o7.7 设计模型顺序图o7.8 设计模型的分包o7.9 逻辑视图到构件视图的映射o总结2022年4月23日星期六第3页7.1 设计模式的选择与应用o1. 问题引入问题引入n软件设计最重要的目标,一是要达到客户对系统功能和性能的要求;二是要考虑软件的生命周期,增强系统的可维护性,降低软件的维护费用。软件维护费用在软件开发成本中占有相当大的比例,一个软件项目能否盈利最关键的是看该软件的维护费用的高低。如果一个软件的可维护性较差,即可扩展性不强、可修改性差、可替换性不好,就会在该软件上花费太大的维护成本,甚至由于改动太大而将整个系统推翻重做。引入设
3、计模式的目的就是要达到第二个目标,即增强系统的可维护性。然而,设计模式一般不能提高软件的功能和性能。那么什么是“软件设计模式”呢? 2022年4月23日星期六第4页7.1 设计模式的选择与应用o2. 解答问题解答问题n设计模式(Design Patterns)这个术语是在1990年代,由Erich Gamma等人,从建筑设计领域引入到计算机科学里去的。是对软件设计中普遍存在而又反复出现的各种问题,所提出的解决方案。设计模式并不直接用来完成程序代码的编写,而是描述在各种不同的情况下,要如何解决问题的一种方案。设计模式主要是使不稳定的依赖于相对稳定、具体依赖于相对抽象,避免会引起麻烦的紧耦合,以增
4、强软件设计面对并适应变化的能力。 2022年4月23日星期六第5页7.1 设计模式的选择与应用o3. 分析问题分析问题n模式(Patterns)这个词,来自于Christopher Alexander的The Timeless Way of Building一书。nAlexander在研究建筑结构的优质设计时,把模式定义为“在某一个情景下的问题解决方案”。他认为,每一种模式,都描述了在我们的环境中不断重复出现的问题,并描述了该问题解决方案的核心。n有了模式,人们可以无数次地使用这种解决方式,以不变应万变,而不需要重新设计它。 2022年4月23日星期六第6页7.1 设计模式的选择与应用o我们为
5、什么要学习设计模式?它究竟能帮助我们为什么要学习设计模式?它究竟能帮助我们解决什么问题?我们解决什么问题?n设计模式至少可以让我们:o 复用解决方案o 建立通用的术语o 解放视角2022年4月23日星期六第7页7.1 设计模式的选择与应用o7.1.1 Facade(门面)模式o7.1.2 Adapter(适配器)模式o7.1.3 Factory(工厂)模式2022年4月23日星期六第8页7.1.1 Facade(门面)模式o1. 问题引入问题引入n当客户程序和组件中各种复杂的子系统之间有了太多的耦合,随着外部客户程序和各子系统不断演化,这种过多的耦合关系将使系统变得更加复杂而难以维护,因此,应
6、用Facade模式,要求一个子系统的外部与其内部的通信时必须通过一个统一的Facade对象进行。Facade模式提供了一个高层次的接口,使得子系统更易于使用,并达到解耦合的目的。那么,Facade模式的原理是怎样的? 2022年4月23日星期六第9页7.1.1 Facade(门面)模式o2. 解答问题解答问题 nFacade模式是对象的结构模式,它没有一个一般化的类图描述,图7-1显示了一个Facade模式的示意性对象图。 2022年4月23日星期六第10页7.1.1 Facade(门面)模式 Facade(门面) 客户端 子系统 图7-1 Facade模式对象结构示意图 2022年4月23日
7、星期六第11页7.1.1 Facade(门面)模式o在这个对象图中,有两个角色:n Facade(门面)角色n 子系统角色2022年4月23日星期六第12页7.1.1 Facade(门面)模式o在门面模式中,通常只需要一个门面类,并且该门面类只有一个实例。o但这并不意味着在整个系统里只能有一个门面类,一般地,每个子系统只有一个门面类。o如果一个系统有多个子系统,每个子系统有一个门面类,整个系统可以有多个门面类。 2022年4月23日星期六第13页7.1.1 Facade(门面)模式o3. 分析问题分析问题n在以下情况下应用门面模式:o(1) 希望包装或隐藏原有系统,提高原有系统的独立性。o(2
8、) 希望使用原有系统的功能,并且希望增加一些新的功能。o(3) 为一个复杂的子系统提供一个简单接口。o(4) 在层次化结构中,可以使用Facade模式定义系统中每一层的入口。2022年4月23日星期六第14页7.1.2 Adapter(适配器)模式(适配器)模式o1. 问题引入问题引入nAdapter模式的意图是将一个类的接口转换成客户希望的另外一个接口。nAdapter模式是用于解决由于接口不兼容而不能一起工作的类的问题。n使用Adapter模式后可以让这些不兼容的类一起工作。那么,Adapter模式的结构是怎样的? 2022年4月23日星期六第15页7.1.2 Adapter(适配器)模式
9、(适配器)模式o2. 解答问题解答问题nAdapter模式的结构,如图7-2所示。 子类1子类2子类3Client抽象类适配器类源类1111图7-2 Adapter模式的结构示意图 2022年4月23日星期六第16页7.1.2 Adapter(适配器)模式(适配器)模式o3. 分析问题分析问题n假如有点、线、圆三种形状,分别为这三种形状创建类,命名为Point、Line、Circle,这些类都有“显示”的行为。客户对象只需要知道,它们拥有的是这些形状中的一个,不必知道自己真正拥有的对象是点、线还是圆。n定义一个形状(Shape)类作为超类,然后由它派生出Point、Line、Circle三个类
10、。n客户对象仅与Shape对象直接打交道,如图7-3所示。 2022年4月23日星期六第17页7.1.2 Adapter(适配器)模式(适配器)模式PointLineCircleClientShape 图7-3 客户对象与Shape、Point、Line、Circle对象之间的关系 2022年4月23日星期六第18页7.1.2 Adapter(适配器)模式(适配器)模式o现在假设每个点(Point)、线(Line)、圆(Circle)对象都具有一些行为,比如“设置位置”、“获取位置”、“设置颜色”、“获取颜色”、“绘制自己”、“擦除自己”等。前四项对于每种类型的形状来说其操作都是相同的,而对于
11、后两项,不同类型的形状其操作略有不同。在此,使用多态来实现其接口问题,在Shape类中为这些行为定义了接口,然后在每个派生类中实现其相应的行为。其结构如图7-4所示。 2022年4月23日星期六第19页7.1.2 Adapter(适配器)模式(适配器)模式图7-4 包含操作的Point、Line、Circle类 2022年4月23日星期六第20页7.1.2 Adapter(适配器)模式(适配器)模式o利用多态,客户对象只需告诉Point、Line或Circle对象要做一些事,每个Point、Line或Circle都会根据自己的类型做出相应的行为。o到此,可能你会问,这与Adapter模式有什么
12、关系?2022年4月23日星期六第21页7.1.2 Adapter(适配器)模式(适配器)模式o假设现在客户要求我们实现一种新的形状(Shape)矩形(Rectangle)。有两种方法可以完成这个任务,最直接的方法是:创建一个新的类Rectangle类,来实现“矩形”这个“形状”,同样从Shape类派生出Rectangle类,这样我们仍然可以获得多态行为。但我们必须为Rectangle类编写paint()、erasure()这两个方法。这是一件比较费时费力的事。这样,我们可以采用另一种方法:找一个Rectangle类的替代品。它可能会很好地处理矩形的相关问题。但非常遗憾!我们找到的替代品可能不
13、兼容不兼容,并且不能被修改不能被修改。假设这个Rectangle类的替代品名为TrueRectangle,并且方法名也不是paint和erasure,而是display和undisplay。如图7-5所示。 2022年4月23日星期六第22页7.1.2 Adapter(适配器)模式(适配器)模式图7-5 包含不同方法名的TrueRectangle类 2022年4月23日星期六第23页7.1.2 Adapter(适配器)模式(适配器)模式o怎么办呢?我们不能直接使用TrueRectangle类,因为那样就无法保持Shape类的多态行为。主要是因为:n(1) 无法从Shape类直接派生出TrueR
14、ectangle类。要这样做的话,只能修改TrueRectangle类,将其超类改为Shape,但这是不被允许的,因为我们无权修改TrueRectangle类的代码(例如,TrueRectangle类已无源代码可修改)。n(2) TrueRectangle类中的方法名称和参数列表与Shape类的不同。 2022年4月23日星期六第24页7.1.2 Adapter(适配器)模式(适配器)模式o要解决这种不兼容性,我们只能另想办法。o我们可以创建一个新类Rectangle类,该类派生自Shape类。Rectangle类用来实现Shape接口而不必重写TrueRectangle类中矩形的实现代码。加
15、入Rectangle类和TrueRectangle类后,其结构如图7-6所示。2022年4月23日星期六第25页5.3.1 关联图7-6 Rectangle类组合了TrueRectangle类 2022年4月23日星期六第26页7.1.2 Adapter(适配器)模式(适配器)模式o由图中看出,Rectangle类派生自Shape类,Rectangle对象包含TrueRectangle对象,Rectangle对象将收到的消息转发给内部的TrueRectangle对象。Rectangle类与TrueRectangle类之间是组合关系,表示当一个Rectangle对象被实例化时,它必须实例化一个相
16、应的TrueRectangle对象。Rectangle对象收到的任何请求都将被转发给TrueRectangle对象,由TrueRectangle对象完成实际的任务。这里,Rectangle类被称为类被称为Adapter(适配(适配器),而器),而TrueRectangle类则被称为类则被称为Adaptee(源类)。(源类)。这就是所谓的Adapter模式。 2022年4月23日星期六第27页7.1.2 Adapter(适配器)模式(适配器)模式oAdapter模式有两种类型:n(1) 对象Adapter模式n(2) 类Adapter模式o究竟使用哪个Adapter模式,要视实际情况而定。o使用
17、Adapter模式的意义在于复用(reuse)。使控制范围之外的一个原有对象与某个接口匹配,当现有接口与现实环境要求不一致的时候使用。 2022年4月23日星期六第28页7.1.2 Adapter(适配器)模式(适配器)模式oAdapter模式实际的应用场合主要有两个:n复用早期版本的程序代码;o系统需要使用已有的类,而此类的接口不符合系统的需要。n设计系统时考虑使用第三方组件。o建立一个可以重复使用的类,用于将第三方组件融入到当前系统中。 2022年4月23日星期六第29页7.1.2 Adapter(适配器)模式(适配器)模式oFacade模式与模式与Adapter模式的比较:模式的比较:n
18、Facade模式的目的是简化接口,而模式的目的是简化接口,而Adapter模模式的目的是将一个接口转换成另一个现有的式的目的是将一个接口转换成另一个现有的接口。接口。n一个一个Facade背后隐藏了多个类,而一个背后隐藏了多个类,而一个Adapter只隐藏了一个类。只隐藏了一个类。2022年4月23日星期六第30页7.1.3 Factory(工厂)模式o假如有一个类A,当我们要实例化这个类时,最简单的方法就是A a = new A( )。如果要做一些初始化的工作,通常我们会把这些操作写在A的构造方法里,比如:oA a = new A(parameter);o但是,也许有很多的初始化内容,如果把
19、所有这些内容都放在构造方法里面,可能很不合适。在这种情形下可以使用工厂模式,协助完成一系列初始化工作。o工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。定将哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有三种形态:Simple Factory(简单工厂)模式、Factory Method(工厂方法)模式和Abstract Factory(抽象工厂)模式。下面就以农产品管理系统的几种水果和蔬菜(苹果、葡萄、橙子、番茄、冬瓜、胡萝卜)为例简要介绍这三种形态的
20、工厂模式。 2022年4月23日星期六第31页一、一、Simple Factory模式模式 o1. 问题引入问题引入nSimple Factory模式的目的,是专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。那么,简单工厂模式的结构是怎样的呢? 2022年4月23日星期六第32页一、一、Simple Factory模式模式o2. 解答问题解答问题nSimple Factory模式的结构如图7-7所示。图7-7 Simple Factory(简单工厂)模式 2022年4月23日星期六第33页一、一、Simple Factory模式模式o3. 分析问题分析问题n图7-7中,
21、水果(Fruit)被定义为接口,并定义了两个方法:grow()和expressedJuice()。苹果(Apple)、葡萄(Grape)和橙子(Orange)三个具体类实现了水果接口。水果工厂类(FruitFactory)定义了一个方法trafficFruit(which:int):Fruit,用来决定究竟要运送哪一种水果。其实现过程可用如下Java程序代码表示,参见书P124125。2022年4月23日星期六第34页一、一、Simple Factory模式模式o从上面的Java程序代码可以看出,当需要运送水果时,只需向水果工厂(FruitFactory)请求就可以了。水果工厂在接到请求后,会
22、自行判断创建和提供哪一种水果。2022年4月23日星期六第35页二、二、Factory Method模式模式o1. 问题引入问题引入n对于上面的简单工厂模式来说,如果要增加一种或几种新的水果(比如还要增加梨、草莓等)就比较麻烦。这时除了要定义几个新增的水果类之外,还必须修改水果工厂和客户端。从而可以看出,Simple Factory(简单工厂)模式的开放性比较差。n如何来解决这种开放性比较差的问题呢?这就需要用到下面将要介绍的Factory Method(工厂方法)模式。然而,Factory Method模式的结构又是怎样的呢?2022年4月23日星期六第36页二、二、Factory Meth
23、od模式模式o2. 解答问题解答问题n将对象的创建交由父类中定义的一个标准方法来完成,而不是其构造方法,究竟应该创建何种对象由具体的子类负责。如图7-8所示。2022年4月23日星期六第37页二、二、Factory Method模式模式图7-8 Factory Method(工厂方法)模式 2022年4月23日星期六第38页二、二、Factory Method模式模式o3. 分析问题分析问题n对于Factory Method模式,其实现过程用Java程序代码表示,参见书P126127。2022年4月23日星期六第39页二、二、Factory Method模式模式o从上面的Java程序代码可以看
24、出,工厂方法模式的核心在于一个抽象工厂类(FruitFactory),它允许多个具体类从抽象工厂类中继承其创建的行为,从而可以成为多个简单工厂模式的综合,推广了简单工厂模式。同样地,如果需要在工厂方法模式中新增加一种水果(如梨子),那么只需要再定义一个新的水果类(如Pear)以及它所对应的工厂类(如TrafficPear)。不需要修改抽象工厂(FruitFactory)和其它已有的具体工厂(TrafficApple、TrafficGrape和TrafficOrange),也不需要修改客户端(Client)。 2022年4月23日星期六第40页三、三、Abstract Factory模式模式o1
25、. 问题引入问题引入nFactory Method模式针对的只是一种类别(如本例中的水果类Fruit),如果我们还要运送蔬菜,就不行了。n在这种情况下,必须用到下面我们将要介绍的Abstract Factory(抽象工厂)模式。那么,Abstract Factory模式的结构又是如何的呢? 2022年4月23日星期六第41页三、三、Abstract Factory模式模式o2. 解答问题解答问题nAbstract Factory模式提供一个共同的接口来创建相互关联的多个对象。如图7-9所示。2022年4月23日星期六第42页三、三、Abstract Factory模式模式图7-9 Abstra
26、ct Factory(抽象工厂)模式 2022年4月23日星期六第43页三、三、Abstract Factory模式模式o3. 分析问题分析问题n对于Abstract Factory模式,其实现过程用Java程序代码表示,参见书P128129。2022年4月23日星期六第44页三、三、Abstract Factory模式模式oAbstract Factory模式只需向客户端提供一个接口,使得客户端在不必指定运送农产品的具体类型的情况下,创建多个类型中的产品对象。 2022年4月23日星期六第45页7.2 构建设计类o分析模型是逻辑上的解决方案,是设计模型的蓝本。设计模型是物理上实现解决方案的蓝
27、本。在体系结构方面,分析模型面向问题领域,而设计模型面向实现环境。o分析模型中类与类之间的关系,是最顶层的关系,我们把在分析阶段得到的类称为“分析类”;然而要实现这些类,还必须在设计阶段做很多工作,比如增加接口、类、事件等以实现这些分析类,这个阶段的类被称为“设计类”。2022年4月23日星期六第46页7.2.1 从分析类生成设计类o1. 问题引入问题引入n分析模型中的所有类都是分析类。分析类展示的是高层次的属性和操作的集合,面向问题领域。它们表示最终的设计类可能具有的属性和操作。分析模型是设计模型的输入,设计模型是把实现技术加入分析模型后对分析模型的细化。如何从分析类生成设计类呢?2022年
28、4月23日星期六第47页7.2.1 从分析类生成设计类o2. 解答问题解答问题n分析类表示设计元素实例扮演的角色,可以使用一个或多个设计模型元素来实现这些角色。n当然,单个设计元素也可以实现多个角色。n如在分析阶段的“客户资料”类,在设计阶段分成了两个类,如图7-10所示。2022年4月23日星期六第48页7.2.1 从分析类生成设计类CustomercustomerID : intname : Stringlinkman : Stringphone : Stringaddress : String CustomercustomerID : intname : StringLinkMethod
29、linkman : Stringphone : Stringaddress : String1.*1 11.* 分析类 设计类 图7-10 从分析类生成设计类 2022年4月23日星期六第49页7.2.1 从分析类生成设计类o3. 分析问题分析问题n分析类Customer中包含了联系方式的一些属性,如果客户的联系方式改变了,或者一个客户不止一个联系方式,就会增加Customer类的维护难度,因此,在设计阶段必须把这些容易发生变化的部分抽取出来,封装成另一个类,以提高其重用性。联系方式(LinkMethod)类与客户(Customer)类之间是聚合关系,可以使得一个客户的联系方式也可以用在其它的
30、场合。2022年4月23日星期六第50页7.2.1 从分析类生成设计类o设计类实现分析角色的一些基本方法:n(1) 分析类可以成为设计模型中的单个设计类。n(2) 分析类可以成为设计模型中的设计类的一部分。n(3) 分析类可以成为设计模型中的聚集设计类。(表示不能将该聚集中的部件显式建模为分析类)。n(4) 分析类可以成为从设计模型中的相同类继承的一组设计类。n(5) 分析类可以成为设计模型中的一组功能相关的设计类。n(6) 分析类可以成为设计模型中的设计子系统。 2022年4月23日星期六第51页7.2.1 从分析类生成设计类n(7) 分析类可以成为设计子系统的部件,例如一个或多个接口以及它
31、们的对应实施。n(8) 分析类可以成为设计模型中的关系。n(9) 分析类之间的关系可以成为设计模型中的设计类。n(10) 分析类主要处理功能需求并对来自“问题域”的对象建模;设计类在处理功能需求的同时还处理非功能需求并对来自“解决方案域”的对象建模。n(11) 可以使用分析类来表示“希望系统支持的对象”,而无需决定用硬件支持分析类的多少部分,用软件支持分析类的多少部分。因此,可以使用硬件实现部分分析类,而根本不在设计模型中对分析类进行建模。 2022年4月23日星期六第52页7.2.2 确定类的大小o1. 问题引入问题引入n定义一个类时一个重要的方面,就是需要确定这个类的大小,这是决定类是否可
32、以被方便地使用或重用的关键所在。太大或者太复杂的类难以维护和改变,但只要它所有的特征都建立在一个独立的重要抽象之上,就可以设计一个相对来说比较大一些的类。客户服务系统中的CustomerService(客户服务人员)类就是一个相对比较大但容易理解的类。如何确定这个类的大小呢?2022年4月23日星期六第53页7.2.2 确定类的大小o2. 解答问题解答问题n如图7-11所示。该类具有可以处理的操作有:创建咨询记录、修改咨询记录、添加经验库等,这些操作都建立在客户服务人员这个独立的抽象模型之上。2022年4月23日星期六第54页7.2.2 确定类的大小图7-11 客户服务人员类的部分操作 202
33、2年4月23日星期六第55页7.2.2 确定类的大小o3. 分析问题分析问题n一般地,一个类所包含的属性或操作最好不要超过20个,如果类所包含的属性或操作太多,应该考虑将这个类根据其特征及职责范围划分成几个更小的类。2022年4月23日星期六第56页7.2.2 确定类的大小o一个类的特征必须可以提供它所需要的所有功能。一个完善的类操作可以提供以下四个方面的功能:n(1) 实现功能n(2) 访问功能n(3) 管理功能n(4) 辅助功能2022年4月23日星期六第57页7.3 详细设计类 o7.3.1 设计公用类o7.3.2 设计类接口o7.3.3 设计属性和方法2022年4月23日星期六第58页
34、7.3.1 设计公用类o1. 问题引入问题引入n一些公共算法通常以自由子程序或非成员函数的方式实现。如果将它们放在一个(或一些)已经存在的类中,就会降低这个类(或这些类)的内聚性。那么,在设计阶段要如何来处理这些公共算法呢?2022年4月23日星期六第59页7.3.1 设计公用类o2. 解答问题解答问题n最好将这些公共算法封装成一个特定的类。这些用来包含非成员函数的特定的类被称为公用公用类类。2022年4月23日星期六第60页7.3.1 设计公用类o3. 分析问题分析问题n软件设计通常会考虑软件的生命周期,提高软件的可维护性。n为了解决设计上的问题,最好应用软件设计模式。设计模式的相关知识详见
35、7.1设计模式的选择与应用。2022年4月23日星期六第61页7.3.2 设计类接口o1. 问题引入问题引入n类接口是指其它类可以通过它访问该类的方法。类接口通常被定义为公有的访问方法。当为类接口确定最佳设计时,需要决定是创建尽可能多的特性(属性)还是创建尽可能少的特性(属性)。也就是说是要创建一个单独但复杂的操作来处理所有复杂的行为,还是要创建使用一系列设计良好的简单操作,每一个操作完成一项任务?2022年4月23日星期六第62页7.3.2 设计类接口o2. 解答问题解答问题n用一系列设计良好的简单操作对行为建模,比用复杂的操作更好一些。由于每一个简单操作都只完成比较少的任务,接口的内聚性较
36、高,所以更容易理解,也更容易重用,如图7-12所示。2022年4月23日星期六第63页7.3.2 设计类接口图7-12 设计良好的简单操作的类 2022年4月23日星期六第64页7.3.2 设计类接口o3. 分析问题分析问题n用一个单独但复杂的操作来处理所有复杂的行为可以使类接口变得非常简单,但是这个操作的参数和实现部分会变得相当复杂,因此,这部分内容的可理解性会变得很差,降低了系统的可维护性。n如图7-13所示,对整个用户信息的获取与设置只用了两个接口,每个接口实现了比较复杂的行为,这种接口的设计凸显出很大的弊病:目标不明确。因为可能所获得的某些用户信息并不会被使用。2022年4月23日星期
37、六第65页7.3.2 设计类接口图7-13 具有简单接口但复杂操作的类 2022年4月23日星期六第66页7.3.2 设计类接口o但使用过多的简单操作会使类的接口变得很复杂、很难理解。因为可能存在几个操作协作完成某一项任务的情况,这样就降低了类接口的内聚性,增强了类接口之间的耦合性。2022年4月23日星期六第67页7.3.2 设计类接口o结论结论:一个有着复杂操作的接口和有着太多操作的接口同样难于理解。所以,通常会在这两者之间进行权衡,可以通过尽可能地使类接口变得简洁来使类变得容易理解和操作。2022年4月23日星期六第68页7.3.3 设计属性和操作o分析模型中已经描述了类的属性和操作,它
38、们包含了类的大体状态和职责。但在建立分析模型时仅仅是为属性和操作命名,而没有详细的定义。在建立设计模型时,需要对类的属性和操作添加更多的详细信息。比如,需要为属性确定数据类型和初始值,还需要为操作添加参数和返回类型。2022年4月23日星期六第69页一、设计属性一、设计属性o1. 问题引入问题引入n我们在前面的分析模型中确定了类的属性名,如何确定属性的数据类型与初始值并使用建模工具Rational Rose描述出来呢?2022年4月23日星期六第70页一、设计属性一、设计属性o2. 解答问题解答问题n属性的UML定义格式为:n 可见性可见性 属性名:数据类型属性名:数据类型 初始值初始值n以C
39、ustomerService(客户服务人员)类的属性设计为例,结果如图7-14所示。2022年4月23日星期六第71页一、设计属性一、设计属性图7-14 类的属性设计 2022年4月23日星期六第72页一、设计属性一、设计属性o3. 分析问题分析问题n在图7-14中,给CustomerService类定义了8个属性,详细情况见表8-1所示。2022年4月23日星期六第73页一、设计属性一、设计属性属性名中文对照数据类型初始值name姓名Stringsex性别String男age年龄int20phone联系电话Stringrank职位Stringdept部门StringloginName登录名S
40、tringpassword密码String表8-1 CustomerService类属性定义 2022年4月23日星期六第74页一、设计属性一、设计属性o在属性和操作的规格说明中,可以用“public”、“protected”和“private”来定义属性或操作的可见性。o由于对象的封装性和信息隐藏原则,类属性可见性默认定义为“private”(私有的)。2022年4月23日星期六第75页一、设计属性一、设计属性o属性名里通常不含有空格,所以,如果需要用多个单词来定义一个属性名,这些单词是紧挨着的。o人们习惯于把第一个单词小写,其它单词首字母大写。例如,name和loginName等。o一般使
41、用名词为属性命名。2022年4月23日星期六第76页一、设计属性一、设计属性o在设计属性时,还需要考虑属性的初始值。初始值有时也称为默认值,是描述属性时可选择的特征,它描述了在创建对象(实例化对象)时对象中这个属性的值,例如,CustomerService类的sex(性别)属性的初始值为“男”。不同的对象其属性值可能不相同,该值是可以改变的。2022年4月23日星期六第77页一、设计属性一、设计属性o并不是所有对象的某个属性都用同一个初始值。对某些属性来说,每一个拥有这个属性的对象需要的初始值是不同的。例如,来电咨询类有一个咨询时间属性,当创建一个来电咨询对象时,希望其咨询时间就是系统的当前时
42、间,所以,来电咨询类的咨询时间属性的初始值被设置为“Now”。虽然每个来电咨询对象的这个属性初始值的类型相同,但不同对象之间的属性值却是不同的,该值由创建对象的时间来决定。2022年4月23日星期六第78页一、设计属性一、设计属性oCustomerService类的sex属性在Rational Rose中的设计过程:n选择CustomerService类,鼠标右键单击,弹出快捷菜单;n选择【Open Specification】菜单项,打开【Class Specification for CustomerService】对话框;n在对话框中选择【Attributes】选项页;n在下面列表框的空
43、白处点击鼠标右键,在弹出的快捷菜单中选择【Insert】项;n在列表框中增加一项,将其名字改为“sex”并双击该项;n弹出【Class Attributes Specification for sex】对话框,分别在Type(数据类型)、Initial(初始值)中输入“String”、“男”。 2022年4月23日星期六第79页二、设计操作二、设计操作o1. 问题引入问题引入n在项目的详细设计阶段除了设计类的属性外,还需要为操作添加更多的详细信息。所以,除了在分析阶段为操作命名外,还需要详细描述操作的两个重要部分:参数列表和返回类型。如何确定操作的参数列表与返回类型并使用建模工具Rationa
44、l Rose描述出来呢?2022年4月23日星期六第80页二、设计操作二、设计操作o2. 解答问题解答问题n类操作的UML表示格式为:n 可见性可见性 操作名(参数列表):返回类型操作名(参数列表):返回类型n以设计CustomerService类的操作为例,其结果见图7-20和图7-21所示。2022年4月23日星期六第81页图7-20 CustomerService类的操作设计窗口 2022年4月23日星期六第82页二、设计操作二、设计操作图7-21 CustomerService类的部分操作的UML表示 2022年4月23日星期六第83页二、设计操作二、设计操作o3. 分析问题分析问题n
45、在图7-21中,我们为CustomerService类定义了18个操作,详细情况见书中P137138的表8-2所示。2022年4月23日星期六第84页二、设计操作二、设计操作o参数列表包含了0个或多个参数。如果参数个数多于1个,则参数之间用逗号(“,”)分隔。操作的参数描述了与操作执行相关的变量。o在客户服务系统中,customerID属性用来唯一标识一个Customer对象。当某一个客户资料需要修改时,必须根据该客户的customerID来查找其相关信息,所以,Customer类的deleteCustomer操作需要customerID参数。2022年4月23日星期六第85页二、设计操作二、
46、设计操作o就像属性的数据类型一样,参数的数据类型描述了操作所用的数据。所以,deleteCustomer操作的customerID参数的类型,与Customer类的customerID属性的类型一样,都是整型(int)。o属性的数据类型决定了引用或改变此属性操作的参数的数据类型。2022年4月23日星期六第86页二、设计操作二、设计操作o操作的返回类型描述了当操作完成后操作返回给对象的数据类型。o操作如果有返回值,可以返回一个像int这样的基本数据类型,或者把一个类作为返回类型。o有时操作是没有返回值的。在Java中用“void”表示操作没有返回值时的返回类型。2022年4月23日星期六第87
47、页二、设计操作二、设计操作o通常用动词或动词短语为操作命名。o操作名称里也没有空格,因此操作名称中包含的单词也是紧挨着的。o习惯上会把首单词除外的其它单词的首字母大写,例如:getName。2022年4月23日星期六第88页二、设计操作二、设计操作oCustomerService类操作deleteCustomer在Rational Rose中的设计过程:n 打开图7-15的对话框后,选择【Operations】选项页;n 在列表框的空白处右击鼠标,弹出快捷菜单,选择【Insert】菜单项,此时,在列表框中新插入一项,修改操作名为“deleteCustomer”;n 双击该操作项,打开【Oper
48、ation Specification for deleteCustomer】对话框; 2022年4月23日星期六第89页二、设计操作二、设计操作n 在【General】页的【Return】项输入返回类型:void;n 选择【Detail】选项页,在【Arguments】(参数列表)列表框的空白处右击鼠标,在弹出的快捷菜单中选择【Insert】菜单项;n 修改参数名、类型分别为“customerID”、“int”n如果操作有多个参数,则重复、两步。2022年4月23日星期六第90页二、设计操作二、设计操作o概念概念7-1:操作签名:操作签名n解答:解答:操作名、参数及其类型和操作的返回类型合在
49、一起称为操作的签名操作的签名。n扩展扩展:一个类中,操作的签名必须具有唯一性,也就是说,一个类中的两个操作不能具有相同的签名。 2022年4月23日星期六第91页二、设计操作二、设计操作o概念概念7-2:重载:重载n解答解答:一个类中,具有相同名称和不同参数(指参数个数与参数类型的组合不同)的操作被称为“重载重载”。n扩展扩展:具有相同名称和参数(参数个数和参数类型都相同)而返回类型不同的操作不是重载。因为调用操作时并不描述操作的返回类型,被调用的对象并不能分辨只是返回类型不同的两个操作。n操作的重载体现了面向对象的多态性,常常应用于面向对象的接口开发中。例如,我们在前面所举的例子中,Shap
50、e类的paint操作就是重载。Shape对象可以根据paint操作不同的参数画出不同的形状。 2022年4月23日星期六第92页7.4 设计类间关系o7.4.1 设计继承o7.4.2 设计聚合/组合o7.4.3 设计关联2022年4月23日星期六第93页7.4.1 设计继承o1. 问题引入问题引入n分析阶段所建立的继承关系没有考虑属性与操作的重组问题,为了加强重用性,细化分析阶段的继承层次可以减少代码量,有助于模型的一致性。这就意味着如果几个类继承了同一个超类,那么这几个类中相同的属性和操作将会做一些处理:n重新排列类的属性和操作。n将类分组以标识公共行为。n客户服务系统中,“系统用户”类与“