当前位置: 首页 > news >正文

软考中级-软件设计师(七)

一、UML

这一章知识点比较多,记得多考的多,可能考的不止考点上的内容,总的说来就是要多练题。

一、UML 基本定义(易考点:概念辨析)

  • 定义:UML(Unified Modeling Language,统一建模语言)是一种标准化的图形化建模语言,用于描述、可视化、分析和设计软件系统(及非软件系统)的结构与行为,是“建模工具”而非“软件开发方法”。
  • 核心作用:为不同角色(需求分析师、设计师、开发工程师)提供统一的“沟通语言”,确保对系统的理解一致。
  • 易考点/易错点
    • 区分“UML是建模语言”而非“开发方法”(如RUP是开发方法,UML是RUP的建模工具),考试常考此类概念辨析题。
    • UML的目标是“统一建模”,而非“直接生成代码”(部分工具支持代码生成,但非UML核心定义)。

二、UML 核心构造块(重点:所有内容均为高频考点)

UML的建模基础由事物(Things)、关系(Relationships)、图(Diagrams) 三类构造块组成,是考试中“符号识别”“概念判断”的核心考点。

(一)事物(Things):UML模型的“基本元素”

事物是UML中可建模的实体,分为4类,每类对应不同的系统维度:

事物类型核心元素(重点)定义与说明表示符号(易考点:图形识别)
结构事物1. 类(Class)描述具有相同属性、方法和关系的对象集合,是系统的静态结构核心矩形(分3层:类名、属性、方法)
(静态结构)2. 接口(Interface)描述类或构件的 “对外服务契约”(仅定义方法签名,无实现)。① 小圆圈+接口名;② 矩形(标注<>)
3. 用例(Use Case)描述“参与者与系统的一次交互行为”,用于需求建模(用户视角的功能需求)。椭圆+用例名
4. 构件(Component)描述系统中可复用的“物理模块”(如jar包、DLL文件),是实现层面的结构单元。矩形(标注<>,可带接口)
5. 对象(Object)类的“运行时实例”,具有具体的属性值。矩形(分3层,类名加下划线)
行为事物1. 交互(Interaction)描述对象间的“动态通信序列”(如序列图中的消息交互)。无独立符号,通过“消息+对象”组合表示
(动态行为)2. 状态机(State Machine)描述对象从创建到销毁的 “生命周期状态变化”(含状态、事件、转换)。圆角矩形(状态)+ 箭头(转换)
3. 活动(Activity)描述“步骤化的行为流程”(如业务流程、算法步骤),是活动图的核心元素。圆角矩形(活动名),可带输入输出
分组事物包(Package)用于“组织和管理模型元素”(如将多个类归为“用户模块”包),避免模型混乱。文件夹形状+包名,可嵌套
(组织元素)
注释事物注释(Note)用于为模型元素添加“说明性文字”(如类的设计思路、用例的业务背景),不影响模型语义。虚线连接的“便签”形状
(辅助说明)
  • 重点/易考点
    • 类、接口、用例、构件的符号识别(考试常给出图形,让判断是哪种事物);
    • 接口的“契约特性”(无实现,仅定义方法)、用例的“用户视角”(非技术功能)。
  • 易错点
    • 混淆“对象”与“类”的符号(对象类名加下划线,类不加);
    • 混淆“构件”(物理模块,如jar)与“类”(逻辑结构,如User类)的区别。
(二)关系(Relationships):事物间的“关联方式”(绝对重点+高频易错点)

UML定义6种基本关系,是考试中“关系判断”“区别辨析”的核心考点,需重点掌握每种关系的定义、符号、核心特征,尤其区分易混淆关系(如聚合vs组合、依赖vs关联)。

关系类型定义表示符号(易考点)核心特征(重点/易错点)
1. 泛化(Generalization)「一般-特殊」关系(如“动物”是一般类,“猫”是特殊类),子类继承父类的属性和方法。(即一类整体的抽象)带空心三角的实线(三角指向父类)- 子类可扩展父类(如重写方法);
- 符号“三角指向父类”是易错点(常考方向判断)。
2. 实现(Realization)「契约-实现」关系:① 类实现接口;② 用例实现(用例的技术落地)。带空心三角的虚线(三角指向接口/用例)- 类实现接口时,需包含接口的所有方法;
- 符号“虚线+空心三角”,区别于泛化的“实线”。
3. 关联(Association)「对象间的结构关系」(如“学生-课程”的选课关系),描述事物间的静态连接。实线(可标注关联名、角色、多重度)- 需标注“多重度”(如1:N、M:N,如学生与课程是M:N);
- 关联是“静态依赖”,区别于“动态依赖”。
4. 聚合(Aggregation)「弱整体-部分」关系(如“班级-学生”):部分可脱离整体独立存在带空心菱形的实线(菱形指向整体)- 生命周期独立(如班级解散,学生仍存在);
- 易错点:与组合的“强整体-部分”区分。
5. 组合(Composition)「强整体-部分」关系(如“汽车-发动机”):部分不能脱离整体独立存在带实心菱形的实线(菱形指向整体)- 生命周期一致(如汽车报废,发动机也报废);
- 符号“实心菱形”是关键识别点(易考图形判断)。
6. 依赖(Dependency)「动态依赖」关系:一个事物(客户端)的变化会影响另一个事物(提供者),是临时性的使用关系。带箭头的虚线(箭头指向提供者)- 临时性(如“学生调用成绩计算工具”,工具可替换);
- 易错点:与关联的区别(关联是静态结构,依赖是动态使用)。

在这里插入图片描述

  • 重点/易考点
    • 6种关系的符号识别(给出图形选关系类型);
    • 聚合vs组合的生命周期差异(考试常考“某场景属于聚合还是组合”,如“公司-员工”是聚合,“手机-屏幕”是组合);
    • 依赖vs关联的区别(依赖是“动态使用”,关联是“静态结构”)。
  • 易错点
    • 泛化与实现的符号混淆(均为空心三角,但泛化是实线,实现是虚线);
    • 聚合的“空心菱形”与组合的“实心菱形”记反。
(三)图(Diagrams):事物与关系的“可视化组合”(重点:13种图的分类与用途)

UML通过13种图从不同视角描述系统,考试重点考“图的分类”“图的用途判断”,需掌握每种图的核心场景(尤其静态图中的类图、用例图,动态图中的序列图、活动图、状态图)。

1. 静态图(描述系统“结构”,不涉及时间维度)【易考】
图类型核心用途(易考点)关键元素
类图(Class Diagram)描述系统的静态结构(类、接口、关系),是面向对象设计的核心图,用于“设计阶段建模”类、接口、泛化/关联/实现等关系
用例图(Use Case Diagram)描述 “用户与系统的交互需求”,用于“需求分析阶段”,明确系统边界和功能范围。参与者(Actor)、用例、关联、包含/扩展关系
对象图(Object Diagram)类图的“运行时实例”,描述某一时刻对象的状态(属性值、对象间关系),用于“调试或演示”。对象(类名加下划线)、属性值
构件图(Component Diagram)描述系统的“物理构件”(如jar、DLL)及构件间的依赖关系,用于“部署前的构件设计”。构件、接口、依赖关系
部署图(Deployment Diagram)描述系统的 “硬件节点”与“构件的部署关系”(如“服务器A部署Web构件”),用于“部署阶段”。节点(矩形加立体效果)、构件、部署关系
2. 动态图(描述系统“行为”,涉及时间或流程维度)
图类型核心用途(易考点)关键元素
序列图(Sequence Diagram)描述“对象间按时间顺序的交互”(强调“时间先后”),用于“接口设计或交互逻辑建模”。对象(生命线)、消息(带箭头的线,分同步/异步)、时间轴
通信图(Communication Diagram)描述“对象间的交互”(强调“对象间的连接关系”,不强调时间),与序列图语义等价但视角不同。对象、关联线、消息(标注顺序号)
状态图(State Diagram)描述“单个对象的生命周期状态变化”(如“订单”的状态:待支付→已支付→已发货→已完成),用于“复杂状态建模”。状态(圆角矩形)、事件(触发转换)、转换(箭头)
活动图(Activity Diagram)描述“流程化行为”(如业务流程、算法步骤,可跨对象),用于“流程建模”(如请假流程、订单处理流程)。活动(圆角矩形)、控制流(箭头)、分支(菱形)、泳道(分组)
时序图(Timing Diagram)描述“对象状态随时间的变化”(强调“时间点与状态的对应”),用于“实时系统建模”(如嵌入式系统)。对象、时间轴、状态条
交互概览图(Interaction Overview Diagram)用活动图的框架整合多个序列图/通信图,描述“复杂交互流程”(如“登录流程→下单流程→支付流程”)。活动、交互引用(指向其他图)
组合结构图(Composite Structure Diagram)描述“类或构件的内部结构”(如“订单类包含支付子模块、物流子模块”),用于“复杂结构建模”。类/构件、端口、内部子元素
  • 重点/易考点
    • 静态图vs动态图的分类(如“类图是静态图,序列图是动态图”);
    • 核心图的用途判断(如“需求分析用什么图?→用例图”“描述对象生命周期用什么图?→状态图”“描述时间顺序交互用什么图?→序列图”);
    • 活动图与状态图的区别(活动图描述“流程”,跨对象;状态图描述“单个对象的状态变化”)。
  • 易错点
    • 序列图与通信图的语义等价性(均描述交互,但视角不同:序列图重时间,通信图重连接);
    • 用例图中的“参与者”是“角色”而非“具体人”(如“管理员”是参与者,而非“张三”)。

三、UML 公共机制(易考点:细节识别)

公共机制是UML中通用的建模规则,用于增强模型的表达能力,考试常考“符号细节”:

  1. 规格说明(Specification)
    • 对事物的详细描述(如类的属性类型、方法参数),通常放在事物图形的“下方或旁边”(用小字体或附加说明)。
    • 易考点:规格说明的位置(非图形本身,而是附加描述)。
  2. 修饰(Adornment)
    • 对事物的补充标记(如“抽象类”的类名用斜体表示,“静态方法”用下划线表示)。
    • 易考点:抽象类、静态成员的符号修饰(如“类名斜体→抽象类”)。
  3. 通用划分(General Divisions)
    • 包括“泛化(一般-特殊)”“分类(对象-类)”“聚集(整体-部分)”,是对事物关系的通用抽象。
    • 易考点:聚集与聚合/组合的关联(聚集是通用概念,聚合/组合是聚集的具体类型)。

四、UML 建模规则(考点:语义一致性)

UML的规则确保模型的合法性和可读性,核心包括:

  1. 语义规则
    • 一致性:模型需符合UML的语义(如“类不能继承接口,只能实现接口”);
    • 完整性:模型需覆盖系统的必要元素(如“用例图需明确系统边界”)。
  2. 语法规则
    • 符号使用规范(如“泛化必须用空心三角实线”);
    • 命名规范(如“类名首字母大写,属性名首字母小写”)。
  • 易考点:语义一致性判断(如“某类图中‘类继承接口’,是否符合UML规则?→不符合,应是实现关系”)。

二、设计模式

一、相关概念(核心基础,贯穿所有考点)

1. 设计模式的定义(易考点:概念辨析)
  • 定义:设计模式是一套“被反复验证、可复用的软件设计解决方案”,用于解决特定场景下的通用设计问题(如“如何确保一个类只有一个实例”“如何让两个接口不兼容的类协同工作”)。
  • 本质:是“设计经验的总结”,而非“代码模板”,核心是封装变化、解耦依赖、提高可复用性和可维护性
  • 易考点/易错点
    • 设计模式≠算法(算法是“解决问题的步骤”,设计模式是“设计层面的方案”);
    • 设计模式≠框架(框架是“可运行的半成品”,设计模式是“设计思路”,框架常包含设计模式)。
2. 设计模式的核心要素(重点:4要素是理解模式的关键)

每个设计模式都包含4个核心要素,考试中“模式识别”“场景匹配”均基于此:

要素定义与作用示例(以“单例模式”为例)
模式名称简洁描述模式的核心意图(如“单例”“适配器”),便于沟通。单例模式(Singleton Pattern)
问题模式要解决的“特定场景问题”(如“多个对象频繁创建销毁导致资源浪费”“接口不兼容无法协同”)。需确保一个类在系统中只有一个实例,且全局可访问。
解决方案模式的“设计结构”(类/对象的协作方式),而非具体代码。私有构造方法+静态获取实例的方法+静态私有实例变量。
效果模式带来的“优缺点”(如可复用性、可维护性提升,或复杂度增加)。优点:节省资源、全局统一访问;缺点:难扩展、违背单一职责。
3. 设计模式的7大设计原则(绝对重点:所有模式的“设计依据”,高频考点)

设计原则是设计模式的“灵魂”,考试常考“某场景违反哪个原则”“某模式符合哪个原则”,需熟记定义、作用、反例

原则名称核心定义作用(重点)易错点/反例(易考点)
1. 开闭原则(OCP)对“扩展开放”,对“修改关闭”(新增功能时不修改原有代码,仅新增代码)。提高可扩展性,降低修改风险。新增支付方式时,修改原有支付类代码(违反OCP)。
2. 单一职责原则(SRP)一个类/接口只负责“一个职责”(只做一件事)。降低类的复杂度,提高可维护性。一个“用户类”同时处理用户信息管理和订单支付(违反SRP)。
3. 里氏替换原则(LSP)子类可“替换”父类,且替换后不改变原有程序的正确性(子类需兼容父类行为)。确保继承关系的合理性,支持多态。正方形类继承长方形类,重写setWidth/setHeight后导致面积计算错误(违反LSP)。
4. 依赖倒置原则(DIP)依赖“抽象”而非“具体实现”(高层模块不依赖低层模块,两者都依赖抽象)。降低模块耦合,提高扩展性。高层“订单模块”直接依赖低层“MySQL数据库类”(违反DIP,应依赖“数据库抽象接口”)。
5. 接口隔离原则(ISP)客户端不依赖“不需要的接口”(将大接口拆分为小接口,按需依赖)。避免接口冗余,降低耦合。一个“全能接口”包含用户管理、订单管理、支付功能,客户端只需支付却依赖整个接口(违反ISP)。
6. 迪米特法则(LoD)一个对象应“最少了解”其他对象(只与直接朋友通信,不与陌生对象交互)。降低对象间耦合,减少依赖传递。订单类直接调用商品类的库存方法,而商品类是订单类的“间接朋友”(应通过订单服务类转发,符合LoD)。
7. 合成复用原则(CRP)优先使用“组合/聚合”而非“继承”实现复用(继承会导致强耦合,组合更灵活)。提高复用灵活性,降低耦合。用“汽车类继承发动机类”实现动力功能(违反CRP,应通过“汽车组合发动机对象”实现)。
  • 易考点:开闭原则是“最核心原则”,其他原则均为实现OCP服务;依赖倒置原则是“解耦的关键”,常与“接口/抽象类”结合考查。

二、主要内容(按GoF 23种模式分类,重点讲高频考点模式)

设计模式按“功能”分为创建型、结构型、行为型三大类,考试中三类模式的考查占比约为3:3:4,需重点掌握以下高频模式:

(一)创建型模式(5种,核心:“如何创建对象”,封装对象创建过程)

解决“对象创建时的耦合、复杂度问题”,核心是“将对象创建与使用分离”。高频考点:单例、工厂方法、抽象工厂。

模式名称意图(解决的问题)适用场景(重点/易考点)结构(类图核心关系)优缺点(易错点)
1. 单例模式(Singleton)确保一个类“只有一个实例”,且全局可访问。① 全局共享资源(如配置类、日志类);② 频繁创建销毁的重量级对象(如数据库连接池)。类(私有构造+静态私有实例+静态getInstance方法)。优点:节省资源、全局统一;缺点:难扩展(违反开闭)、线程安全问题(需特殊处理)。
2. 工厂方法模式(Factory Method)定义“创建对象的接口”,让子类决定“实例化哪个类”(将创建逻辑延迟到子类)。① 产品种类不确定,需扩展新产品(如新增手机品牌);② 客户端不关心产品创建细节。抽象工厂(创建抽象产品)→ 具体工厂(创建具体产品);抽象产品→具体产品。优点:符合开闭(新增产品只需加具体工厂/产品);缺点:类数量膨胀(新增产品需加2个类)。
3. 抽象工厂模式(Abstract Factory)提供一个“创建一系列相关/依赖对象的接口”,无需指定具体类(创建“产品族”)。① 系统需独立于产品的创建/组合(如跨平台UI组件:Windows按钮+Windows文本框为一个产品族);② 产品族稳定,不易新增产品族。抽象工厂(创建多个抽象产品)→ 具体工厂(创建对应产品族的具体产品);多个抽象产品→对应具体产品。优点:隔离产品族依赖,易切换产品族;缺点:难扩展新产品(如新增“下拉框”产品,需修改所有工厂和抽象工厂,违反开闭)。
4. 建造者模式(Builder)将“复杂对象的构建过程”与“对象表示”分离,同一构建过程可创建不同表示(如“组装电脑”)。① 复杂对象(属性多、构建步骤固定);② 需不同表示的复杂对象(如高配/低配电脑)。指挥者(控制构建步骤)→ 建造者(抽象构建方法)→ 具体建造者(实现构建);产品(复杂对象)。优点:解耦构建与表示,易定制;缺点:类数量多(适合极复杂对象)。
5. 原型模式(Prototype)通过“复制现有对象”创建新对象,而非重新实例化(避免重复初始化开销)。① 对象创建成本高(如初始化需查数据库);② 需批量创建相似对象(如批量生成报表模板)。原型类(实现clone方法)→ 具体原型(重写clone);客户端通过clone获取新对象。优点:提高创建效率;缺点:深克隆实现复杂(引用类型需特殊处理)。
  • 易考点/易错点
    • 单例模式的“线程安全实现”:饿汉式(类加载时创建,线程安全但浪费资源)、懒汉式(双重检查锁+volatile,线程安全且懒加载);
    • 工厂方法vs抽象工厂:工厂方法创建“单一产品”,抽象工厂创建“产品族”(如工厂方法造“手机”,抽象工厂造“手机+耳机+充电器”)。
(二)结构型模式(7种,核心:“如何组合类/对象”,优化结构耦合)

解决“类/对象组合时的结构灵活性问题”,核心是“通过继承/组合实现功能复用或接口适配”。高频考点:代理、适配器、装饰器、组合。

模式名称意图(解决的问题)适用场景(重点/易考点)结构(类图核心关系)优缺点(易错点)
1. 代理模式(Proxy)为其他对象提供“代理”,控制对原对象的访问(如权限控制、延迟加载)。① 远程代理(访问远程对象,如RPC代理);② 保护代理(权限控制,如管理员代理);③ 虚拟代理(延迟加载,如大图片加载代理)。抽象主题(定义接口)→ 真实主题(原对象)、代理(持有真实主题引用,实现抽象主题,添加额外逻辑)。优点:解耦访问者与原对象,增强功能;缺点:增加一层代理,性能略有损耗。
2. 适配器模式(Adapter)将“一个类的接口”转换为“客户端期望的另一个接口”,使接口不兼容的类可协同工作。① 复用老系统(老接口与新系统接口不兼容);② 集成第三方组件(第三方接口与自研接口不一致)。目标接口(客户端期望的接口)→ 适配器(实现目标接口,持有适配者引用,转换逻辑)→ 适配者(老接口/第三方接口)。优点:复用老代码,降低改造成本;缺点:过多适配器会增加系统复杂度。
3. 装饰器模式(Decorator)动态给对象“添加额外功能”,且不改变原对象结构(如“给咖啡加奶、加糖”)。① 需动态扩展对象功能(且功能可组合);② 避免用继承扩展(继承会导致类爆炸)。抽象组件(定义核心功能)→ 具体组件(核心功能实现)、装饰器(持有抽象组件引用,实现抽象组件,添加额外功能)→ 具体装饰器(具体额外功能)。优点:动态扩展、功能可组合;缺点:多层装饰会增加调试难度。
4. 组合模式(Composite)将“对象组合成树形结构”,使客户端对“单个对象”和“对象组合”的访问一致(如“文件-文件夹”)。① 处理树形结构数据(如文件系统、部门组织架构);② 客户端无需区分单个/组合对象。抽象构件(定义统一接口)→ 叶子构件(单个对象,无子节点)、容器构件(组合对象,持有子构件列表)。优点:统一访问逻辑,简化客户端;缺点:叶子与容器的职责差异可能导致设计模糊。
5. 外观模式(Facade)为“复杂子系统”提供一个“统一的高层接口”,简化客户端与子系统的交互(如“医院挂号→就诊→缴费”的统一服务窗口)。① 子系统复杂,客户端需调用多个子系统接口;② 需隔离客户端与子系统(降低耦合)。外观类(持有子系统引用,提供统一接口)→ 多个子系统类(复杂逻辑实现)。优点:简化调用,降低耦合;缺点:外观类可能成为“上帝类”(职责过多)。
6. 桥接模式(Bridge)将“抽象部分”与“实现部分”分离,使两者可独立扩展(如“手机品牌”与“手机功能”分离)。① 抽象与实现需独立扩展(如品牌可加华为/苹果,功能可加通话/拍照);② 避免多维度继承导致的类爆炸。抽象化角色(定义抽象接口,持有实现化角色引用)→ 修正抽象化角色;实现化角色(定义实现接口)→ 具体实现化角色。优点:解耦抽象与实现,易扩展;缺点:增加系统复杂度(需理解抽象与实现的分离)。
7. 享元模式(Flyweight)复用“细粒度对象”,减少对象创建数量(如“围棋棋子”“字符串常量池”)。① 大量相似对象(如游戏中的敌人、文档中的字符);② 对象大部分属性可共享(内部状态),少部分随环境变化(外部状态)。享元工厂(管理享元对象,复用已有对象)→ 享元角色(抽象接口,区分内部/外部状态)→ 具体享元(实现享元)、非享元(不可共享的对象)。优点:减少内存占用;缺点:增加工厂复杂度,需处理外部状态传递。
  • 易考点/易错点
    • 适配器vs装饰器:适配器“改变接口”(让不兼容的接口协同),装饰器“不改变接口,只加功能”;
    • 组合模式的“透明方式”vs“安全方式”:透明方式中叶子和容器都有add/remove方法(叶子抛出异常),安全方式中仅容器有add/remove(客户端需区分叶子和容器),考试常考透明方式。
(三)行为型模式(11种,核心:“如何交互”,优化对象间的通信与职责分配)

解决“对象间的行为协作、职责分配问题”,核心是“封装行为变化、解耦交互逻辑”。高频考点:观察者、策略、模板方法、迭代器、责任链。

模式名称意图(解决的问题)适用场景(重点/易考点)结构(类图核心关系)优缺点(易错点)
1. 观察者模式(Observer)定义“对象间的一对多依赖”,当一个对象(主题)变化时,所有依赖它的对象(观察者)自动更新。① 事件通知(如GUI按钮点击、消息订阅);② 状态变化需同步通知多个对象(如订单状态变更通知库存、物流、财务)。主题(管理观察者列表,通知更新)→ 具体主题;观察者(定义更新接口)→ 具体观察者。优点:解耦主题与观察者,易扩展;缺点:观察者过多时通知效率低,可能循环依赖。
2. 策略模式(Strategy)定义“一系列算法”,将每个算法封装起来,使算法可互相替换(如“支付方式:支付宝/微信/银联”)。① 多个算法解决同一问题(且需动态切换);② 避免用多重if-else判断算法(如if(支付方式==支付宝)→调用支付宝逻辑)。策略接口(定义算法)→ 具体策略(实现算法);上下文(持有策略引用,调用算法)。优点:算法可切换、易扩展;缺点:客户端需了解所有策略(才能选择)。
3. 模板方法模式(Template Method)定义“算法的骨架”,将步骤延迟到子类实现(如“泡茶:烧水泡茶→加茶叶→加调料”,调料步骤子类定)。① 算法步骤固定,部分步骤可变(如流程固定,细节差异);② 复用算法骨架,约束子类行为。抽象类(定义模板方法:固定步骤+钩子方法)→ 具体子类(实现可变步骤)。优点:复用骨架,约束流程;缺点:子类需遵循骨架,灵活性受限(钩子方法可缓解)。
4. 迭代器模式(Iterator)提供一种“遍历聚合对象元素”的方法,且不暴露聚合对象的内部结构(如“遍历列表/集合”)。① 需遍历聚合对象(如数组、链表、树);② 客户端无需知道聚合对象的内部结构(如遍历ArrayList和LinkedList用同一迭代器)。迭代器接口(定义hasNext()/next())→ 具体迭代器;聚合接口(定义创建迭代器的方法)→ 具体聚合。优点:解耦遍历与聚合,易扩展新聚合;缺点:增加类数量(每个聚合需对应迭代器)。
5. 责任链模式(Chain of Responsibility)将“请求的处理者”连成链,请求沿链传递,直到有处理者处理(如“请假审批:员工→组长→经理→总监”)。① 多个对象可处理同一请求(且处理者不确定);② 避免请求发送者与处理者耦合(无需知道谁处理)。抽象处理者(定义处理方法+持有下一个处理者引用)→ 具体处理者(判断是否处理,否则传递)。优点:解耦发送者与处理者,易扩展;缺点:请求可能无人处理,或链过长导致效率低。
6. 命令模式(Command)将“请求”封装为对象,使请求可参数化、队列化、撤销(如“遥控器按钮:开/关电视”)。① 需记录请求(如日志、撤销);② 请求发送者与处理者解耦(如遥控器不直接控制电视,通过命令对象)。命令接口(定义execute())→ 具体命令(持有接收者引用,调用接收者方法);请求者(持有命令引用,触发命令);接收者(执行具体操作)。优点:支持撤销/重试,解耦发送者与接收者;缺点:类数量多(每个命令一个类)。
7. 备忘录模式(Memento)保存对象的“内部状态”,且不破坏封装,以便后续恢复(如“游戏存档”“文档撤销”)。① 需保存/恢复对象状态(如撤销操作、快照);② 不希望暴露对象内部结构(状态私有)。原发器(创建备忘录+从备忘录恢复);备忘录(存储原发器状态);管理者(管理备忘录,不访问状态)。优点:保护封装,支持恢复;缺点:状态多时有内存开销(如频繁存档)。
8. 状态模式(State)将“对象的状态”封装为独立类,使对象状态变化时行为也变化(如“订单状态:待支付→已支付→已发货”)。① 对象行为依赖状态(且状态多、变化频繁);② 避免用多重if-else判断状态(如if(状态==待支付)→允许支付)。环境类(持有当前状态引用,委托状态处理行为);状态接口(定义状态对应的行为)→ 具体状态(实现行为,切换状态)。优点:状态变化清晰,易扩展;缺点:状态多时有类爆炸(每个状态一个类)。
9. 访问者模式(Visitor)定义“作用于对象结构中元素的操作”,使操作可独立于元素结构扩展(如“文档解析:文本→图片→表格,分别统计字数/尺寸/行数”)。① 对象结构稳定(如文档元素固定),但需扩展新操作(如新增“导出”操作);② 避免在元素类中新增操作(违反开闭)。访问者接口(定义对每个元素的操作)→ 具体访问者;元素接口(定义接受访问者的方法)→ 具体元素;对象结构(管理元素,遍历并接受访问者)。优点:操作易扩展,集中管理;缺点:对象结构变化时需修改所有访问者(违反开闭)。
10. 中介者模式(Mediator)用“中介者对象”封装对象间的交互,使对象无需直接通信(如“聊天室:用户不直接发消息,通过聊天室转发”)。① 多个对象间交互复杂(网状依赖);② 需简化对象间耦合(如系统中多个模块互相调用,用中介者统一协调)。中介者接口(定义交互方法)→ 具体中介者(持有同事引用,协调交互);同事类(持有中介者引用,通过中介者交互)→ 具体同事。优点:解耦同事,简化交互;缺点:中介者可能成为“上帝类”(逻辑复杂)。
11. 解释器模式(Interpreter)定义“语言的语法”,并构建解释器解析语言(如“正则表达式解析”“公式计算”)。① 简单语法的语言(如自定义配置规则、简单公式);② 语法频繁变化(如动态调整规则)。抽象表达式(定义解释方法)→ 终结符表达式(语法的基本单位)、非终结符表达式(语法的组合);环境(存储解释所需的上下文)。优点:语法易扩展;缺点:复杂语法会导致类爆炸(如SQL解析不适合)。
  • 易考点/易错点
    • 策略vs模板方法:策略是“算法全替换”(不同算法完全独立),模板方法是“算法骨架固定,部分步骤替换”;
    • 观察者vs责任链:观察者是“一对多通知”(所有观察者都接收),责任链是“请求沿链传递,一个处理者处理”;
    • 状态vs责任链:状态是“对象自身状态驱动行为变化”(状态是对象内部属性),责任链是“请求驱动处理者变化”(处理者是外部对象)。

三、核心考点(按考查形式分类,覆盖选择/案例分析)

1. 设计原则类考点(占比约20%)
  • 考查形式:选择题(判断违反/符合哪个原则)、案例分析题(指出代码中的原则违反问题)。
  • 高频场景
    • 给出代码片段(如“一个类同时处理用户和订单”),判断违反“单一职责原则”;
    • 给出需求(如“新增支付方式需修改原有支付类”),判断违反“开闭原则”;
    • 给出设计(如“高层模块依赖具体数据库类”),判断违反“依赖倒置原则”。
2. 模式分类与识别(占比约30%)
  • 考查形式:选择题(判断模式类型、匹配场景)、案例分析题(识别代码中的模式)。
  • 高频场景
    • 给出场景(如“确保日志类只有一个实例”),选“单例模式”;
    • 给出场景(如“老系统接口与新系统不兼容,需适配”),选“适配器模式”;
    • 给出场景(如“订单状态变化通知多个模块”),选“观察者模式”;
    • 给出类图(如“抽象工厂创建多个产品”),判断模式类型。
3. 模式实现细节(占比约30%)
  • 考查形式:选择题(判断实现正确性)、简答题(写模式代码)。
  • 高频场景
    • 单例模式的线程安全实现(双重检查锁+volatile的作用);
    • 工厂方法模式的类结构(抽象工厂、具体工厂、抽象产品、具体产品的关系);
    • 装饰器模式的“组合而非继承”实现(装饰器持有组件引用);
    • 策略模式中上下文与策略的交互(上下文调用策略的方法)。
4. 模式对比与选择(占比约20%)
  • 考查形式:选择题(选择合适的模式)、案例分析题(重构代码选模式)。
  • 高频场景
    • 对比“适配器vs装饰器”,选择适合“接口适配”的模式(适配器);
    • 对比“工厂方法vs抽象工厂”,选择适合“产品族”的模式(抽象工厂);
    • 对比“策略vs模板方法”,选择适合“动态切换算法”的模式(策略)。

四、相关考题(覆盖高频考点,含详细解析)

(一)选择题(每题1分,共5题)
1. 设计原则类

题目:某电商系统中,“订单类”同时包含“订单信息管理”和“支付逻辑处理”功能。当需要新增“分期付款”功能时,需修改“订单类”的支付相关代码。该设计违反了UML设计原则中的( )。
A. 开闭原则 B. 单一职责原则 C. 依赖倒置原则 D. 里氏替换原则
答案:B
解析:“订单类”同时负责“订单管理”和“支付处理”两个职责,违反“单一职责原则”(一个类只做一件事);新增支付功能需修改订单类,也间接违反开闭原则,但核心问题是职责过多,故优先选B。

2. 模式识别类

题目:某物流系统中,“订单状态”包括“待发货”“已发货”“已签收”“已取消”,不同状态下订单支持的操作不同(如“待发货”可取消,“已发货”不可取消)。为避免用多重if-else判断状态,应采用的设计模式是( )。
A. 策略模式 B. 状态模式 C. 责任链模式 D. 观察者模式
答案:B
解析:场景核心是“对象行为依赖状态,且状态变化频繁”,状态模式将每个状态封装为独立类,订单的行为由当前状态决定,避免if-else;策略模式是“算法替换”,与状态无关,故排除A。

3. 模式实现类

题目:以下关于单例模式的实现,哪项是线程安全的懒汉式实现( )。
A.

public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

B.

public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

C.

public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

D.

public class Singleton {public static Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

答案:B
解析:A是普通懒汉式,线程不安全(多线程并发创建多个实例);B是双重检查锁+volatile,线程安全且懒加载(volatile防止指令重排);C是饿汉式,线程安全但非懒加载;D是饿汉式的错误实现(instance为public,破坏封装)。

4. 模式对比类

题目:某系统需处理“文件-文件夹”的树形结构,客户端需统一遍历“单个文件”和“文件夹中的所有文件”,无需区分两者。应采用的设计模式是( )。
A. 适配器模式 B. 装饰器模式 C. 组合模式 D. 享元模式
答案:C
解析:组合模式的核心是“将单个对象和组合对象统一为树形结构,客户端统一访问”,符合“文件-文件夹”场景;适配器是“接口适配”,装饰器是“加功能”,享元是“复用对象”,均不符合。

5. 模式分类类

题目:以下设计模式中,属于行为型模式的是( )。
A. 抽象工厂模式 B. 代理模式 C. 观察者模式 D. 桥接模式
答案:C
解析:A是创建型模式;B、D是结构型模式;C是行为型模式。

(二)简答题(共1题,10分)

题目:请编写单例模式的“懒汉式(线程安全)”实现代码,并说明关键技术点(如volatile的作用、双重检查锁的目的)。
答案

  1. 实现代码:
public class Singleton {// 1. 私有静态实例,volatile修饰防止指令重排private static volatile Singleton instance;// 2. 私有构造方法,防止外部实例化private Singleton() {}// 3. 静态公共方法,双重检查锁获取实例public static Singleton getInstance() {// 第一次检查:避免已创建实例时的同步开销if (instance == null) {// 同步锁:确保多线程下只有一个线程进入创建逻辑synchronized (Singleton.class) {// 第二次检查:防止多线程并发时多次创建实例if (instance == null) {instance = new Singleton(); // volatile防止指令重排}}}return instance;}
}
  1. 关键技术点说明:
    (1)私有构造方法:防止外部通过new关键字创建实例,确保实例唯一;
    (2)volatile关键字:防止instance = new Singleton()的指令重排(该操作分“分配内存→初始化对象→赋值引用”三步,重排可能导致其他线程获取到“未初始化的实例”);
    (3)双重检查锁:第一次检查避免“实例已存在时的同步锁开销”(提高效率),第二次检查防止“多线程并发进入同步块后重复创建实例”(保证线程安全)。
(三)案例分析题(共1题,15分)

题目:某在线购物系统中,“订单服务”需处理订单创建后的一系列操作:① 扣减库存;② 生成支付单;③ 发送短信通知用户。当前代码如下:

public class OrderService {private InventoryService inventoryService = new InventoryService();private PaymentService paymentService = new PaymentService();private SmsService smsService = new SmsService();public void createOrder(Order order) {// 1. 扣减库存inventoryService.reduceStock(order.getProductId(), order.getQuantity());// 2. 生成支付单paymentService.createPayment(order);// 3. 发送短信smsService.sendSms(order.getUserId(), "订单创建成功");}
}

(1)该代码违反了哪些设计原则?请说明理由。(5分)
(2)若后续需新增“记录订单日志”操作,需修改createOrder方法,违反了什么原则?如何用设计模式优化?(10分)

答案
(1)违反的设计原则及理由:
依赖倒置原则OrderService直接依赖InventoryService等具体实现类(new InventoryService()),而非抽象接口;若更换库存实现(如从MySQL改为Redis),需修改OrderService代码。
单一职责原则OrderService除了“创建订单”核心职责,还直接调用库存、支付、短信服务,职责过多(耦合了其他服务的调用逻辑)。

(2)新增操作的问题及优化方案:
违反原则:新增“记录日志”需修改createOrder方法,违反“开闭原则”(对修改关闭,对扩展开放)。
优化设计模式:采用“观察者模式”,将订单创建作为“主题”,库存扣减、支付生成、短信通知、日志记录作为“观察者”,订单状态变化时自动通知所有观察者。
优化后代码结构

  • 步骤1:定义“主题”接口(订单主题):
public interface OrderSubject {void registerObserver(OrderObserver observer); // 注册观察者void removeObserver(OrderObserver observer); // 移除观察者void notifyObservers(Order order); // 通知观察者
}
  • 步骤2:定义“观察者”接口(订单操作观察者):
public interface OrderObserver {void doAction(Order order); // 观察者的操作(扣库存、发通知等)
}
  • 步骤3:实现具体主题(订单服务):
public class OrderService implements OrderSubject {private List<OrderObserver> observers = new ArrayList<>();@Overridepublic void registerObserver(OrderObserver observer) {observers.add(observer);}@Overridepublic void removeObserver(OrderObserver observer) {observers.remove(observer);}@Overridepublic void notifyObservers(Order order) {for (OrderObserver observer : observers) {observer.doAction(order); // 通知所有观察者执行操作}}// 核心职责:创建订单,仅负责通知观察者public void createOrder(Order order) {// 订单创建逻辑(如保存订单到数据库)System.out.println("订单创建成功:" + order.getOrderId());// 通知所有观察者执行后续操作notifyObservers(order);}
}
  • 步骤4:实现具体观察者(库存、支付、短信、日志):
// 库存观察者
public class InventoryObserver implements OrderObserver {private InventoryService inventoryService = new InventoryService();@Overridepublic void doAction(Order order) {inventoryService.reduceStock(order.getProductId(), order.getQuantity());}
}
// 日志观察者(新增操作,无需修改原有代码)
public class LogObserver implements OrderObserver {private LogService logService = new LogService();@Overridepublic void doAction(Order order) {logService.recordLog("订单创建:" + order.getOrderId());}
}
  • 步骤5:客户端使用(新增观察者只需注册,无需修改订单服务):
public class Client {public static void main(String[] args) {OrderService orderService = new OrderService();// 注册观察者(库存、支付、短信、日志)orderService.registerObserver(new InventoryObserver());orderService.registerObserver(new PaymentObserver());orderService.registerObserver(new SmsObserver());orderService.registerObserver(new LogObserver()); // 新增日志观察者// 创建订单orderService.createOrder(new Order("O123", "P456", 2, "U789"));}
}

优化效果:新增操作(如日志)只需新增观察者类并注册,无需修改OrderServicecreateOrder方法,符合开闭原则;同时解耦订单服务与其他操作,符合依赖倒置原则。

http://www.dtcms.com/a/419926.html

相关文章:

  • CDN 网站是否需要重新备案链爱交易平台
  • 高端网站建设大概多少费用商城网站建设哪个公司好
  • C++ 多返回值的几种实现方式
  • 徐州网站建设的特点做企业网站用什么
  • 东莞营销网站网站虚拟主机 会计处理
  • CSS定位布局
  • 织梦首饰网站模板茶楼 网站
  • 怎样建设微网站课程推广
  • 网站建设前的ER图重庆怎样网站推广
  • 虹膜边缘预测函数
  • day82—数组 | 哈希桶—找到所有数组中消失的数字(LeetCode-448)
  • 人该怎样活着呢?版本61
  • 天纪标注平台TLP:用大模型赋能高质量数据标注
  • 免费网站建设 百度收录wordpress怎么调用api
  • linux 系统cshrc 文件
  • 【网络安全】一、入门篇:读懂 HTTP 协议
  • 建设在线教育网站国外做的好的医疗网站设计
  • 酒店网站建设案例策划书怎么写网站设计是什么专业
  • java-字符集,编码解码
  • 使用 SQLAlchemy 和 Alembic 处理 FastAPI 中的模型变更
  • 怎么搭建属于自己的网站超详细wordpress常用函数
  • 【Java初学基础10】一文讲清反射
  • 深圳外贸营销型网站建设网站优化和提升网站排名怎么做
  • 可以做电算化的网站鄂州网站推广
  • 驻马店哪家做网站好专业展馆展厅设计
  • 20250928的学习笔记
  • seo网站推广策略福州短视频seo程序
  • Tsinghua OJ 工作分配(Workload)C++ 数组指针实现
  • 免费网站知乎网页打不开但是qq能上是怎么回事
  • 宁波网站设计制作公司wordpress免费简约模板