软考中级习题与解答——第五章_面向对象方法(2)
例题11
1、知识点总结
判断是否必需:问自己“没有这个子功能,主功能还能完成吗?”
如果不能(如:没有验证码核查,就不能取现),就是包含。
如果能(如:没有打印凭条,依然可以完成取现),就是扩展。
判断是否是“一种”:问自己“A是B的一种吗?”
如果是(如:“信用卡支付”是“支付”的一种),就是泛化(generalization)。
如果不是,就不是泛化
关系类型 | 表示法 | 含义 | 示例 |
---|---|---|---|
包含关系 (Include) | <<include>> | 必须的、强制的行为。基础用例必定会执行被包含的用例。就像一个子过程或函数调用。 | “取现” 必须 “核查验证码” |
扩展关系 (Extend) | <<extend>> | 可选的、有条件的行为。基础用例的执行可能会(在某些条件下)触发扩展用例。 | “下单” 可能会(在满足优惠条件下)触发“使用优惠券” |
泛化关系 (Generalization) | 空心三角箭头 | 继承关系。子用例继承父用例的行为和关系,并可以增加或覆盖自己的行为。 | “支付” 是父用例,“信用卡支付”和“支付宝支付”是它的子用例 |
关联关系 (Association) | 实线 | 参与者与用例之间的通信关系。表示参与者如何与系统交互。 |
2、选项分析
A. 包含关系 (√ 正确)
原因:“查询余额”和“取现”这两个用例都必须要执行“核查验证码”这个步骤,缺少这个步骤主线任务就无法完成。这是一种强制的、不可或缺的依赖关系,完全符合“包含关系”的定义。
B. 扩展关系 (× 错误)
原因:扩展关系用于表示可选的行为。例如,“取现”用例可能会扩展一个“打印凭条”的用例(用户可以选择打或不打)。但“核查验证码”不是可选的,是必须的,所以不是扩展关系。
C. 泛化关系 (× 错误)
原因:泛化关系是“一般”与“特殊”的继承关系。“核查验证码”并不是“查询余额”或“取现”的一种特殊类型。它们不是父子关系。
D. 关联关系 (× 错误)
原因:关联关系描述的是参与者(Actor) 与用例(Use Case) 之间的交互关系,而不是用例与用例之间的关系。题目描述的是两个用例之间的关系,所以不可能是关联关系。
3、最终答案:A
例题12
1、知识点总结
图类型 | 主要用途 | 动态性 | 静态性 | 特点 |
---|---|---|---|---|
协作图 (Communication Diagram) (即协作图) | 描述对象间的交互关系和链接关系 | ✅ 显示对象间消息传递的顺序(动态) | ✅ 显示对象之间的连接结构(静态) | 同时反映动态和静态特性,强调对象的结构关系。 |
顺序图 (Sequence Diagram) | 强调消息的时间顺序 | ✅ 清晰显示消息的时间先后次序 | ❌ 不直接显示对象间的静态链接 | 强调交互的时序,而非对象间的结构。 |
状态图 (State Diagram) | 描述一个对象的状态变化 | ✅ 显示状态转移和触发事件 | ❌ 不描述对象间的交互和链接 | 关注单个对象的生命周期。 |
活动图 (Activity Diagram) | 描述业务流程或工作流 | ✅ 显示活动的流程和控制流 | ❌ 不强调对象间的链接关系 | 类似于流程图,用于建模业务流程。 |
2、选项分析
A. 活动图 (× 错误)
原因:活动图主要用于对业务流程、操作流程进行建模(动态性),它关注的是活动的流程,而不是对象之间的结构和链接。
B. 顺序图 (× 错误)
- 原因:顺序图虽然详细描述了对象间消息传递的时间顺序(动态性),但它不直接显示对象之间的静态链接关系。对象间的关联关系是隐含的,需要通过消息序列来推断。
C. 状态图 (× 错误)
- 原因:状态图专注于描述单个对象内部的状态如何响应事件而发生改变(动态性),它完全不涉及多个对象之间的交互和静态链接关系。
D. 协作图 (√ 正确)
- 原因:协作图(通信图)明确显示了对象之间的连接(静态结构)以及在这些连接上传递的消息(动态交互)。它完美地体现了题目中要求的“同时反映系统的动态和静态性”。
3、最终答案:D
例题13
1、知识点总结
UML图分为两大类别:
结构性视图(静态视图)
类图 (Class Diagram) (⑦):显示系统的静态结构,包括类、接口、关联、继承等。
对象图 (Object Diagram) (①):显示在某一时刻系统中的对象及其关系,是类图的实例。
构件图 (Component Diagram) (⑤):描述软件构件(如库、文件、可执行文件)的结构及其依赖关系。
部署图 (Deployment Diagram) (⑥):描述系统硬件节点的拓扑结构以及软件构件在这些节点上的部署。
包图 (Package Diagram) (③):用于对模型元素进行分组,表示包与包之间的关系,体现系统的分层结构。
复合结构图:描述类的内部结构(本题未涉及)
行为性视图(动态视图)
描述系统的动态行为,即系统随时间变化的行为。它们表示的是对象之间的交互和状态变化。
用例图 (Use Case Diagram) (②):它描述的是系统与外部的功能交互(谁用什么功能),这是一种行为,因此属于行为视图。不要被它的静态表现形式迷惑。
顺序图 (Sequence Diagram):强调消息时间顺序的交互行为(本题未涉及)。
通信图 (Communication Diagram):强调对象协作关系的交互行为(本题未涉及,原名协作图)。
定时图 (Timing Diagram) (④):强调消息跨越不同对象或状态时的时间约束,是行为视图。
状态图 (Statechart Diagram) (⑧):描述一个对象生命周期内状态的变化,是行为视图。
活动图 (Activity Diagram):描述业务流程或操作流程,类似于流程图(本题未涉及)。
2、最终答案:C
例题14
1、知识点总结
原则名称 | 英文 | 核心思想 | 通俗解释 | 题目中的选项 |
---|---|---|---|---|
开闭原则 (Open-Closed Principle) | OCP | 对扩展开放,对修改关闭。系统应该允许在不修改现有代码(闭)的情况下,通过扩展(开)来增加新功能。 | 就像搭积木,用新的积木块(扩展)来增加造型,而不是去锯已有的积木(修改)。 | A. JF (开闭) |
里氏替换原则 (Liskov Substitution Principle) | LSP | 所有引用基类的地方必须能透明地使用其子类的对象。子类可以扩展父类的功能,但不能改变父类原有的功能。 | “老鼠的儿子会打洞”,子类必须能完成父类承诺的所有事情,不能“坑爹”。 | B. 里氏替换 |
依赖倒置原则 (Dependency Inversion Principle) | DIP | 高层模块不应该依赖低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。 | 老板(高层)不直接指挥员工(低层),而是定下规章制度(抽象),员工按制度办事。 | C. 依赖倒置 |
接口隔离原则 (Interface Segregation Principle) | ISP | 客户端不应该被迫依赖于它不用的接口。一个类对另一个类的依赖应该建立在最小的接口上。 | 不要造“万能遥控器”,应该为不同的电器设计专门的、简单的遥控器。 | D. 接口隔离 |
单一职责原则 (Single Responsibility Principle) | SRP | 一个类应该有且仅有一个引起它变化的原因。 | “专事专办”,一个类只负责一项明确的职责。 | (本题未出现) |
2、选项分析
A. JF (开闭原则) (√ 正确)
原因:“扩展已有的系统” 和 “提供新的行为” 这两个关键词是开闭原则最直接、最经典的描述。该原则的核心目标就是通过扩展(如继承、实现接口、组合)来添加新功能,而不是通过修改现有代码。
B. 里氏替换原则 (× 错误)
原因:该原则关注的是继承关系中的行为一致性,确保子类能够无缝替换父类。它更多的是对“扩展”的一种约束(要求扩展不能破坏原有逻辑),而不是直接指导“如何扩展系统”。
C. 依赖倒置原则 (× 错误)
原因:该原则关注的是解耦,通过面向接口编程来减少模块间的依赖。它为提高系统的可扩展性和可维护性打下了良好基础(使得扩展更容易),但并非直接用于“扩展系统添加新行为”。
D. 接口隔离原则 (× 错误)
原因:该原则关注的是接口设计的粒度,避免出现“胖接口”。其目的是减少不必要的依赖,提高灵活性,与“扩展系统添加新行为”的关系不直接。
3、最终答案:A
例题15
1、知识点总结
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式的主要目的和优点:
复用成功的设计和体系结构:设计模式提供了对常见问题的标准解决方案,可以直接复用这些成熟的方案,避免重复造轮子。
提高代码的可维护性和灵活性,适应需求变化:许多模式(如策略模式、装饰器模式)的核心就是为了将变化的部分隔离,使得系统更容易扩展和修改,从而更好地应对需求变更。
提高代码的可靠性和健壮性,减少出错的可能性:模式是经过大量实践验证的解决方案,使用它们可以避免自己设计时可能引入的潜在缺陷和错误,提供更健壮的设计。
改善代码的可读性和沟通效率:模式提供了通用的设计词汇,开发者一说“这里我们用了一个工厂模式”,其他人立刻就明白了代码的意图和结构。
设计模式的局限性(什么不是设计模式要解决的):
设计模式不直接解决平台可移植性问题。可移植性通常与编程语言特性、系统API、硬件架构、以及使用的库和框架密切相关。设计模式是语言无关的设计思想,它关注的是代码的组织结构,而不是底层的运行平台。例如,一个用C++实现的观察者模式和一个用Java实现的观察者模式,其可移植性取决于C++和Java本身的可移植性,而非模式本身。
2、选项分析
A. 使用设计模式的主要目的是复用成功的设计和体系结构 (√ 正确)
这正是设计模式最核心的价值。模式本身就是对成功设计的总结和复用。
B. 设计模式具有适应需求变化的优点 (√ 正确)
许多行为型和结构型模式(如策略、状态、装饰器、适配器等)的核心目标就是提高系统的灵活性和可扩展性,从而更容易适应未来的需求变化。
C. 设计模式可以改善代码的平台可移植性 (× 不正确)
这是不正确的描述。设计模式是架构和设计层次的解决方案,它关注的是代码的组织和对象间的交互关系。而“平台可移植性”通常是指代码能否在不同的操作系统、硬件或运行时环境(如Windows, Linux, Android, JVM, .NET CLR)上不加修改或稍作修改即可运行。这更多地依赖于编程语言本身的特质、使用的系统API以及跨平台库(如Java的JVM,或C/C++的标准库和条件编译)。设计模式并不直接解决这个问题。
D. 设计模式可以减少方案出错的可能性 (√ 正确)
使用经过验证的、成熟的设计方案,相比自己从头设计一个解决方案,无疑更能避免常见的陷阱和错误,提高方案的可靠性。