软考系统架构师知识点整理(上)

目录

系统性概述

0~1分

系统架构概念&历史

  1. 信息系统架构三要素:构件、模式和规划
  2. 信息系统架构层级:概念层次、物理层次
  3. 软件架构是关于软件系统的结构、行为和属性的高级抽象
  4. 企业软件架构(企业架构),是应用全面、严格的方法,描述一个正对信息系统、流程处理、个人和组织当前和/或未来行为的抽象结构集合

系统架构设计师定义

  1. 系统架构设计师师系统给或产品线的设计责任人,是负责理解和管理并最终确认和评估非功能性系统需求,给出开发规范,搭建系统实现的核心架构,对整个软件架构、关键构件、接口进行总体设计并澄清关键技术细节的高级技术人员
  2. 系统架构设计师着眼于系统的“技术实现”,同事还要考虑系统的“组织协调”。是信息系统开发和演进的全方位技术与管理人才
  3. 系统架构设计师既应具有技术素质,还应具有管理素质,同时还应该和其他团队角色进行协调工作
  4. 系统架构设计师和产品经理的关系&区别:产品经理(负责产品设计)应具备较高的商业素质和较强的技术背景。要有深厚的领域经验“商业人士”。
  5. 系统架构设计师和项目经理的关系&区别:软件项目经理(关注项目本身的进度、质量、分配、调动、管理人财物)是指对项目控制/管理的负责人。对于项目经理来说,包括项目计划、进度跟踪/监控、质量保证、配置/发布/版本/变更、人员绩效评估等方面。优秀的项目经理不仅在于会使用集中软件或是了解若干抽象的方法论原则,更重要的是从大量的项目时间中获得的宝贵经验,以及交流、协调、激励能力,甚至还应具备某种个性魅力或领袖气质。一个是团队方向的综合能力,一个注重技术方面的进化演进能力的技术人员。
  6. 系统架构设计师和系统分析师的关系&区别:系统分析师师指对系统开发中进行业务需求分析、系统需求分析、可行性分析、业务建模和指导项目开发的人。系统分析师往往面临许多不确定性的事件,需要对这些不确定的事件进行分析总结,得出一个相对可靠的确定性结论或实施方案模型。系统分析师对业务系统进行分析建模,其任务和目标师明确的,系统架构设计师协助系统分析师的工作,建议系统分析师按什么标准、什么工具、什么模式、什么技术去思考系统。同时系统架构设计师应该对系统分析师所提出的问题、碰到的难题及时提出解决方法。

系统架构设计师基础能力

  1. 战略规划能力
  2. 业务流程建模能力
  3. 信息数据架构能力
  4. 技术架构选择与实现能力
  5. 应用系统架构的解决和实现能力
  6. 基础IT知识及基础设施、资源调配的能力
  7. 信息安全技术支持与管理保障能力
  8. IT审计、治理与基本需求分析、获取能力
  9. 面向软件系统可迁居与系统生命周期的质量保障服务能力

开发人员转型到系统架构设计师

  1. 基础计算机科学技术或软件工程知识
  2. 8年以上软件项目开发实际工作经验(工作经验,做到深度和广度兼备)

计算机与网络基础知识

2~6分

操作系统基础知识

  1. 操作系统(OS)是计算机系统中的核心系统软件,负责管理和控制计算机系统张的硬件和软件资源,合理的祖师计算机工作流程和有效利用资源,在计算机(硬件机器)与用户之间起接口的作用
  2. 操作系统特征:并发性(concurrency)、共享性(sharing)、虚拟性(virtual)、不确定性(non-determinacy)
  3. 操作系统功能:进程管理、文件管理、存储管理、设备管理、作业管理
  4. 典型操作系统:
    1. 批处理操作系统(Unix、Linux、Windows 等常见的自动化命令执行)
      • 原理:通过把用户提交的作业分类,将同一批中的作业编程一个作业执行序列
      • 分类批处理:分为联机批处理和脱机批处理
      • 主要特征:用户脱机使用计算机、成批处理任务、多道程序运行
    2. 分时操作系统(网络虚拟机、服务器)
      • 原理:采用分时技术,使多个用户同时以会话方式控制自己的程序运行,每个用户都逻辑上拥有独立的,支持自己请求服务的系统。分时技术把处理及的运行事件分成很短的时间片,按时间片轮转把处理及分配给各任务作业使用。
      • 主要特征:交互性、多用户同时性、独立性
    3. 实时操作系统(特殊专有设备);
      • 原理:专用系统和应用紧密结合,优先强调及时性、可靠性和完整性
      • 分类:实施过程控制与实时信息处理
      • 特征:及时响应、高可靠性
    4. 网络操作系统(网管系统?)
      • 原理:按照网络架构的各个协议标准进行开发,包括网络管理、通信、资源共享、系统安全和多种网络应用服务
      • 特征:互操作性、协作处理
    5. 分布式操作系统
      • 原理:逻辑上统一操作页面,逻辑一个内核,实际上在物理时间空间上可能使分离的。
      • 特征:未来大型应用的操作的发展方向之一
  5. 进程概述
    1. 进程和程序的比较
      • 进程是程序的依次执行,是一个动态概念;程序是静态的概念,是指令的集合,具有动态性和并发性
      • 程序是进程运行所对应的运行代码,一个进程对应于一个程序,一个程序可以同时对应多个进程。
    2. 进程的组成
      • 在操作系统中,进程是进行系统资源分配、调度和管理的最小单位。从静态的观点看,进程由程序、数据和进程控制块(Process Control Block, PCB)组成;从动态的观点看进程是计算机状态的一个有序集合
    3. 进程控制块(PCB):是进程存在的唯一标志,描述了进程的基本情况。随着进程的建立而产生,随着进程的完成而撤销
      • 调度信息:供进程调度使用,包括进程当前的一些基本属性
      • 执行信息:即现场,刻画了进程的执行情况
  6. 进程状态的划分
    1. 三态模型:运行态(占有处理器正在运行)、就绪态(具备运行条件,等待吗系统分配处理器以便运行)、等待态(阻塞态,不具备运行条件,正等待某个事件的完成)
      • 运行态 -> 等待态: 等待使用资源
      • 等待态 -> 就绪态: 进程运行所需资源得到满足
      • 运行态 -> 就绪态: 运行时间片结束,或出现更高优先权的进程
      • 就绪态 -> 运行态: CPU空闲时选择一个就绪进程
    2. 五态模型:运行态、活跃阻塞、静止阻塞、静止就绪、活跃就绪
      • 活跃阻塞态 -> 静止阻塞态: 如果当前不存在活跃就绪进程,那么至少有一个等待态进程被对换出去成为静止阻塞态(减少系统资源消耗)
      • 静止阻塞态 -> 静止就绪态: 引起进程等待的事件发生之后,相应的静止阻塞态进程将被转化为静止就绪态
      • 静止就绪态 -> 活跃就绪态: 当内存中没有活跃就绪态进行,或者静止就绪态进程具有比活跃就绪态进程更高的优先级,系统将把静止就绪态进程转为活跃就绪态
      • 活跃就绪态 -> 静止就绪态: 系统根据资源性能情况,将活跃就绪态转为静止就绪态
      • 静止阻塞态 -> 活跃阻塞态: 当一个进程等待一个事件时,原则上不需要把它调入内存。但是当一个进程退出后,内存重新获取自由空间,高优先级的静止阻塞线程,并且系统已得知导致它阻塞的事件即将结束
  7. 信号量与PV操作:系统同中进程之间经常会存在互斥(需要独占资源)和同步(异步进程协作)
    1. 信号量: 特殊变量,表现形式时一个整型S和一个队列
    2. P操作:申请资源,即S=S-1 若S < 0 进程暂停执行,进入阻塞队列
    3. V操作:释放资源,S=S+1。 若 S<=0 标示阻塞队列中存在等待该资源的进程,唤醒阻塞队列中的第一个进程
  8. PV操作理解:PV操作和信号量用来解决并发问题。使用资源前,使用P操作申请资源;使用资源后,使用V操作释放资源;
    • 在互斥关系中PV操作时在一个进程中成对出现
    • 在同步关系中PV操作在两个进程甚至多个进程中成对出现
  9. 利用PV操作实现进程的互斥控制
    • 互斥控制是为了保护共享资源,不让多个进程同时访问这个共享资源。这块共享资源称之为临界资源,这段阻止多个进程同时进入访问这些资源的代码段被称为临界区
    • P(信号量);临界区;V(信号量)
  10. 利用PV操作实现进程同步控制:生产者V操作;消费者P操作
  11. 生产者&消费者问题
    • empty 生产者信号量 初始值为0
    • full 消费者信号量 初始值为0
    • mutex 互斥信号量 保证只有N个线程访问资源因此初始值为1
  12. 管程与线程
    1. 管程
      • 组成:管程由管程名、局部子管程的变量说明、使用共享资源并在数据集上进行操作的若干过程,以及变量赋初值的语句4个基本部分组成
      • 执行过程:每一个管程管理一个临界资源(类似一个资源处理管道,实现对有限资源的控制)
    2. 线程
      • 线程时进程的活动成分,是处理器分配资源的最小单位,它可以共享进程的资源与地址空间,通过线程的活动,进程可以提供多种服务(对服务器进程而言)或实行子任务并行(对用户而言)。采用线程机制最大的优点是节省开销、创建时间短。
  13. 死锁问题
    1. 定义: 死锁是指多个进程之间互相等待对方的资源,而得到对方的资源之前又不释放自己的资源,导致循环等待的现象。
    2. 发生必要条件:互斥条件(资源独占);请求保持条件(持续请求);不可剥夺条件(不可放弃);环路条件(循环请求)
    3. 银行家算法(最优资源分配,导致死锁不分配,否则分配)
      • 进程最大资源需求不得超过系统资源数
      • 进程可以分期请求资源,但请求总数不能超过最大需求数
      • 现有系统资源不能满足进程尚需资源数时,对进程的请求可以推迟分配
      • 当系统现有的资源能满足进程尚需资源数时,必须测试系统现存的资源能否满足该进程尚需的最大资源数,若能满足则按当前的申请量分配资源;否则也要推迟分配。
  14. 存储管理
    1. 存储管理的主要任务:提高主存利用率、扩充主存以及对主存信息实现有效保护
    2. 存储管理的对象:主存(内存)
    3. 逻辑地址和物理地址:用户编程所使用的地址为逻辑地址(虚拟地址),实际内存地址则称物理地址(实地址),每次访问内存两者之间转化由硬件完成,而内存和外存之间的信息动态调度时硬件和操作系统两者配合完成的。
    4. 地址重定位:程序的逻辑地址转化为主存的物理地址的过程。重定位方式有静态重定位和动态重定位
    5. 最常见的虚拟存储技术有分段技术、分页技术、段页技术

数据库系统基础知识

  1. 基本概念
    1. 数据库(DataBase DB):是指长期存储在计算机内的、有组织的、可共享的数据集合。
    2. 数据库系统(DataBase System DBS):由数据库、硬件、软件和人员(操作数据的用户)组成,管理的对象是数据。(数据库管理系统是数据库系统的具体实现)
    3. 数据库管理系统(DataBase Management System DBMS):是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库。如:MySQL,Oracle,Redis
      • 关系数据库系统(RDBS)
      • 面向对象的数据库系统(OODBS)
      • 对象关系数据库系统(ORDBS)
    4. 数据库系统中分级方法(应用程序依赖于外模式,独立于概念模式和内模式)
      • 外模式:面向具体应用,独立于内模式和存储设备
      • 概念模式:是数据库的中心与关键
      • 内模式:依赖于概念模式,独立于外模式和存储设备
  2. 数据库结构
    1. 数据库结构的基础是数据模型,是用来描述数据的一组概念和定义
    2. 数据模型的三要素:数据结构、数据操作、数据的约束条件
  3. 常用数据模型
    1. 概念数据模型:又称实体联系模型,按照用户的观点来对数据和信息建模,主要用于数据库设计。主要用实体——联系方法(Entity-Relationship Approach)表示,简称E-R图。
      • 实体:矩形框表示,框内标注实体名称
      • 属性:用椭圆表示,并用连线与实体连接起来。
      • 实体之间的联系:用菱形框表示,框内标注联系名称,用连线将菱形框分别与有关实体相连,并在连线上标注联系类型。
    2. 基本数据模型:又称机构数据模型,是按照计算机系统的观点对数据合信息建模,主要用于DBMS的实现。基本数据类型是数据库系统的核心合基础,由数据结构(系统静态特性的描述)、数据操作(系统动态特性的描述)和完整性约束(一组完整性规则的集合)三部分组成
    3. 面向对象模型:用面向对象的观点来描述世界实体的逻辑组织、对象间限制、联系等模型。一个面向对象数据库系统是一个持久的、可共享的对象库的存储和管理者,而一个对象库是由一个面向对象模型所定义的对象的集合体。例如:MongoDB。面向对象的数据库系统在逻辑上和物理上从面向记录上升为面向对象、面向可具有复杂结构的一个逻辑整体。允许用自然的方法,并结合数据抽象机制在结构和行为上对复杂对象建立模型,从而大幅度提高管理效率,降低用户使用复杂性。
  4. 数据的规范化
    1. 函数依赖:R(U) 是属性U上的一个关系模式,X和Y是U的子集,r是R的任一关系,如果对于r中的任意两个元组u和v,只要有u[X]=v[X],就有u[Y]=v[Y]。这个成为X函数决定Y,或者称Y函数依赖于X,记为X->Y(关系数据库设计理论的核心就是数据间的函数依赖)。
    2. 三范式:BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF
      • 第一范式1NF:关系模式R的每个关系r的属性值都是不可分的原子值,那么称R是第一范式的模式,r是规范化的关系(关系数据库研究的关系都是规范化的关系)。
      • 第二范式2NF:如果关系模式R满足1NF,且每个非主属性完全函数依赖于候选键。
      • 第三范式3NF:如果关系模式R满足1NF,且每个非主属性都不传递依赖于R的候选码。
      • BC范式BCNF:如果关系模式R满足1NF,且每个非主属性都不传递依赖于R的候选键
  5. 事务管理
    1. DBMS运行的基本工作单位是事务,事务时用户定义的一个数据库操作序列,这些操作序列要么全做,要么全都不做,是一个不可分隔的工作单位。
    2. 事务的四个特性(ACID)
      • 原子性(Atomicity):事务时数据库的逻辑工作单位,事务的所有操作在数据库中要么全做,要么全都不做。
      • 一致性(Consistency):事务的执行使数据库从一个一致性状态变为另一个一致性状态。
      • 隔离性(Isolation):一个事务的执行不能被其他事务干扰。
      • 持续性(Durability):一个事务一旦提交,它对数据库的改变必须是永久的,即便系统出现故障时也是如此。
    3. 相关语句
      • BEGIN TRANSACTION:事务开始语句
      • COMMIT:事务提交语句
      • ROLL BACK:事务回滚语句
  6. 并发控制
    1. 并发操作:在多用户共享系统中,许多事务可能同时对同一数据进行操作,称为并发操作,此时数据库管理系统的并发控制子系统负责协调并发事务的执行,保证数据库的完整性不受破坏,同时避免用户得不到正确的数据。
    2. 封锁:并发控制的主要技术是封锁,主要有两种类型的分所,分别是X封锁和S封锁。
      • 排他型封锁(X封锁|排他性):如果事务T对数据A实现了X封锁,那么只允许事务T读取和修改数据A,其他事务要等事务T解除封锁以后才能操作。
      • 共享型封锁(S封锁):如果事务T对数据A实现了S封锁,那么允许事务T读取数据A,但是不能修改数据A,在所有S封锁解除之前决不允许任何事物对数据A实现X封锁。
  7. 数据库的备份与恢复
    1. 备份与恢复:
      • 备份是指通过数据转储和监理日志文件的方法建立冗余数据,DBA定期的将整个数据库复制到磁带或另一个磁盘上保存起来的过程。这些备用的数据文本称为后备副本。
      • 数据库的恢复时指吧数据库从错误状态恢复到某一个已知的正确状态的功能。当数据库遭到破坏后,就可以利用后备副本吧数据库回复,这时数据库只能恢复到备份时的状态,从那以后所有更新事务必须重新运行才能恢复到鼓掌时的状态。
    2. 备份分类
      • 静态备份(可用性低):数据库系统在备份时不允许任何存取、 修改活动
      • 动态备份(备份数据可能不正确):数据库系统在备份时允许任何存取、 修改活动(备份和用户事务可以并发执行)
      • 海量备份:每次备份全量数据
      • 增量备份:每次备份上次备份后更新的数据
    3. 数据库故障类型
      • 事务故障:执行事务异常,恢复:撤销事务(UNDO)和重做事务(REDO 事务重放)
      • 系统故障:数据库系统运行异常
      • 介质故障:存储介质异常,恢复:数据库管理员装入数据库副本和日志文件副本
      • 计算机病毒:恶意攻击导致
  8. 关系数据库设计
    1. 数据库设计:是指对一个给定的应用环境,构造最优的数据库,建立数据库及其应用系统,使之能有效存储数据,猫族各种用户需求。
    2. 数据库设计特点:从数据结构(数据模型)开始,并以之为核心展开;静态结构设计与动态行为设计分离;(试探性、反复性和多步性)
    3. 数据库设计方法:直观设计法、规范设计法、计算机辅助设计法、自动化设计法
    4. 数据库设计步骤:需求分析、概念结构设计、逻辑结构设计、物理结构设计、应用程序设计、运行维护
  9. 分布式数据库系统
    1. 分布式数据库系统(DDBS): 针对地理上分散而管理上又需要不同程度集中管理的需求,而提出的一种数据管理信息系统
    2. 分布式数据库系统的特点:数据的集中控制、数据独立性、数据冗余可控性、场地自治、存取有效性。
    3. 分布式数据库的体系结构:全局外层、全局概念层、局部概念层、局部内层。
  10. 商业智能(数据挖掘&展示)
    1. 商业智能(BI): 企业对商业数据的搜集、管理和分析的系统过程,目的是使企业各级决策者获得知识或洞察力,帮助企业决策。数据仓库、联机分析处理(OLAP)和数据挖掘共同组成了商业智能。
    2. 数据仓库(Data Warehouse):特征是一个面向主题的、集成的、非易失的、时边的数据集合
    3. 传统数据库与数据仓库比较
      image
    4. OLTP(联机事务处理)与OLAP(联机分析处理)的比较:
      image
    5. 数据挖掘与畅通数据分析的区别:数据挖掘时在没有明确假设的前提下去挖掘信息、发现知识。数据挖掘所得到的信息应具有先知、有效和可实用三个特征。是预先未曾预料到的,即发现那些不能靠直觉发现的信息或知识。
      • 数据挖掘的任务:关联分析、聚类分析、分类分析、异常分析、特异群组分析和演变分析等

计算机网络基础知识

  1. OSI七层协议&TCP/IP四层协议
    • OSI/ISO:应用层(处理网络应用)、表示层(数据表示)、会话层(互联主机通信)、传输层(端到端连接)、网络层(分组传输和路由选择)、数据链路层(传送以帧为单位的信息)、物理层(二进制位传输)
    • TCP/IP:应用层(应用层、表示层、会话层)、传输层(传输层)、网际层(网络层)、网络接口层(数据链路层、物理层)
      image
      image
  2. 网络分类、组网和接入技术
    1. 地理范围分类:局域网、城域网、广域网
    2. 链路传输控制技术分类:以太网(总线争用技术|标志)、令牌网、FDDI网、ATM网(异步传输模式)、帧中继网和ISDN网(走在那个和业务数据网)
    3. 网络拓扑结构分类:总线型、星型、树型、环型、网型
    4. 网络数据交换分为:电路交换、分组交换、ATM交换、全光交换和标记交换
    5. 网络接入技术:同轴电缆接入、铜线接入、无线接入
    6. 无线网络应用领域分为:无线个域网、无线局域网、无线城域网、蜂窝移动电信网
  3. 网络服务器(多用户多任务环境下的可靠性)和网络存储技术
    • 网络存储技术:DAS、NAS、SAN
  4. 网络规划、设计与实施(技术基础:交换以太网技术)
    1. 拓扑结构选择要素:地理环境、传输介质、传输距离、可靠性
    2. 汇聚层存在与否取决于网络规模大小。
    3. 通信设备选型要素:核心交换机选型、汇聚层/接入层交换机选型、远程接入与访问设备选型
  5. 网络安全及其防范技术
    1. 基本要素(机密性、完整性、可用性、可控性、可审查性)和所需工作(制定安全策略、用户验证、加密、访问控制、审计和管理)
    2. 网络攻击步骤:信息手机、试探寻找突破口、实施攻击、消(除)防(护)记录、保留访问权限
    3. 信息安全等级:用户自主保护级、系统审计保护级、安全标记保护级、结构化保护级、访问验证保护级。
    4. 防火墙局限性(无法阻止检测基于数据呢欧容的攻击和入侵、无法控制内部网络之间的违规)、扫描器局限性(无法发现正在进行的入侵)、防毒软件局限性(对于基于网络的攻击无能为力)
  6. 网络管理:包括对硬件、软件和人力的使用、综合与协调,以便对网络资源进行监视、测试、配置、分配、评价和控制。报告处理网络故障和备份相关信息。
  7. 综合布线系统包括六个子系统

多媒体技术及其应用

  1. 概念
    1. 媒体:承载信息的载体
    2. 多媒体:数字、文字、声音、图形、图像和动画等各种媒体的有机组合,并与先进计算机、通信和广播电视技术相结合,形成一个可组织、存储、操纵和控制的多媒体信息的继承环境和交互系统。
    3. 多媒体技术:以数字化为基础,能对多种媒体信息进行采集、编码、存储、传输、处理和表现,综合处理多找那个媒体信息并使之建立起有机的逻辑联系,集成为一个系统并能具有良好交互性的技术。特征:多样性、集成性、交互性、实时性。
    4. 多媒体计算机:MPC=PC + CD-ROM + 声卡 + 显卡 + 多媒体操作系统
  2. 多媒体数据压缩编码技术
    1. 静止图像压缩标准(JPEG):多种压缩程度的有损压缩方法,其文件名后缀包括.jpg 、.jpeg等
    2. 运动图像压缩标准(MPEG): 视频图像压缩的重要标准,兼顾了JPEG标准和CCITT专家组的H.261标准。MPEG-1 (1 Mbit/s ~ 1.5 Mbit/s) 普通电视质量信号压缩; MPEG-2 (30帧/s 720572分辨率信号),扩展模式下可对14401152 高清晰度电视HDTV信号进行压缩。
    3. 视频通信编码标准(H.261):1990年ITU-T 视频编码标准解码器,为带宽为64kb/s的倍数的综合业务数字网上传输质量可接受的视频信号。

系统性能

  1. 系统性能:性能指标、性能计算、性能设计、性能评估
  2. 性能指标是软、硬件性能指标的集成
    1. 计算机的性能指标:时钟频率(主频)、运算速度、运算精度、内存容量、存储器的存取周期、数据处理速率、吞吐率、响应时间、利用率、RASIS特性(可靠性、可用性、可维护性、完整性、安全性)、平均故障响应时间、兼容性、可扩充性、性价比。
    2. 网络性能指标:
      • 设备性能指标:吞吐量、延迟、丢包率、转发速度。
      • 网络性能指标:可达性、网络系统的吞吐量、传输速度、信道利用率、信道容量、带宽利用率、丢包率、平均传输延迟、平均延迟抖动、延迟/吞吐量的关系、延迟抖动/吞吐量的关系、丢包率/吞吐量的关系。
      • 应用性能指标:QoS(Quality of Service,服务质量 解决网络延迟和阻塞等问题的一种技术)、网络对语言应用的支持程度、网络对视频应用的支持程度、延迟/服务质量的关系、丢包率/服务质量的关系、延迟抖动/服务质量的关系。
    3. 操作系统性能指标:系统可靠性、系统吞吐量、系统响应时间、系统资源利用率、可移植性。
    4. 数据库管理系统性能指标:数据库描述功能、数据库管理功能、数据库查询和操纵功能、数据库维护功能。
      • 数据库本身:数据库大小、数据库中表的数量、单个表大小、表中允许记录行数、单个记录行大小、表上所允许的索引数量、数据库所允许的索引数量
      • 管理系统:最大并发事务处理能力、负载均衡能力、最大连接数等
  3. 性能指标计算的主要方法:定义法、公式法、程序检测法、仪器检测法
  4. 性能设计
    • 阿姆达尔定律(Amdahl's Law)是计算机科学中用于评估并行计算系统性能提升上限的理论,由吉恩·阿姆达尔于1967年提出,核心公式为 \(S = \frac{1}{(1 - P) + \frac{P}{N}}\),其中 \(S\) 为加速比,\(P\) 为可并行化部分比例,\(N\) 为处理器数量。该定律表明,系统性能提升受限于不可并行部分的占比。。
  5. 性能评估:对一个系统进行各项检测,并形成一份直观的文档,因此性能评估师通过各项测试来完成的。

信息系统基础知识

2~6分

信息化概述

  1. 信息的基本概念
    • 维纳(控制论创始人):信息就是信息,既不是物质也不是能量
    • 香农(信息化奠基人):信息是能够用来小吃不确定性地东西
    • 概念:本体论层次(纯客观层次,只与客体本身的因素有关,与主体地因素无关)和认知论层次(从主体立场来考察的信息层次,既与客体因素有关,又与主体因素有关)
  2. 信息的定量描述
    • 香农公式:\(H(X)=-\sum_{i} p_{i} \log p_{i}\)
    • H(X) 是X的信息熵;Pi是事件出现第i种状态的概率,在二进制的情况下,对数的底是2,这时信息熵可以作为信息的度量,成为信息量,单位时比特(bit)
  3. 信息的传输模型
  4. 信息的质量属性:精确性、完整性、可靠性、及时性、经济性、可验证性、安全性。
  5. 信息的特征: 客观性、普遍性、无限性、动态性、依附性、交换性、传递性、层次性、系统性。
  6. 信息化的含义:信息化主体是全体社会成员。空域是政治、经济、文化、军事和社会省会地一切领域。时域是一个长期过程
    • 产品信息化 -> 企业信息化 -> 产业信息化 -> 国民经济信息化 -> 社会生活信息化
    • 三个层次: 战略需求 > 运作需求 > 技术需求
  7. 信息化体系六要素:信息资源(核心)、信息网络(龙头)、信息技术和产业(基础)、信息化人才(关键)、信息化政策法规和标准规范(保障)
  8. 信息化战略纲要
    • 2017-2020年:小康社会,服务重大战略布局,促使信息化成为现代化建设地先导力量。
    • 2020-2025年:技术先进、产业发达、应用领先、网络安全坚不可摧
    • 2025-21世纪中叶:网络强国,引领全球信息化发展
  9. 两化融合地含义
    • 信息化与工业化发展战略地融合
    • 信息资源与材料、能源等工业资源地融合
    • 虚拟经济与工业实体经济融合
    • 信息技术与工业技术、IT设备与工业装备地融合

信息系统工程总体规划

  1. 信息系统定义
    1. 信息系统:硬件、软件、数据库、网络、存储设备、感知设备、外设、人员以及把数据处理成信息的规程等
    2. 信息系统集成:采用现代管理理论(软件工程、项目管理等)作为计划、设计、控制的方法论,将硬件、软件、数据库、网络等部件按照规划的结构和秩序,有机地整合到一个有清晰边界地信息系统中,以达到既定系统目标,这个过程称为信息系统集成。
  2. 信息系统的生命周期:立项(系统规划)、开发(系统分析、系统设计、系统实施、系统验收)、运维和消亡
  3. 信息系统开发方法
    • 主流集成模式:面向信息集成(焦于将不同来源、不同格式的数据进行整合,以提供一个统一、一致的数据视图。它主要关注数据的获取、转换、存储和访问,旨在消除数据冗余和不一致性,使用户能够方便地获取所需的信息)、面向过程集成(强调将企业内的各种业务流程进行整合和优化,以实现业务流程的自动化和高效执行。它关注的是业务过程的建模、协调和控制,确保各个业务环节之间能够无缝衔接,提高企业的运营效率)、面向服务集成(将企业的各种业务功能封装成独立的服务,这些服务可以通过标准化的接口进行调用和组合。它强调服务的松耦合、可重用性和互操作性,使得企业能够快速响应业务变化,灵活地构建新的业务流程)。
  4. 信息系统工程总体规划的方法:关键成功因素法(CSF, 战略分析)、战略目标集转化法(SST, 战略分析)、企业系统规划法(BSP, 企业过程分析)
    • 关键成功因素法:识别关键成功因素(组织目标分解和关键因素识别、性能指标识别一直到产生数据字典),找出实现目标所需的关键信息集合,确定系统开发优先次序。
    • 战略目标集转化法:战略目标(信息集合,由使命、目标、战略)转为管理信息系统的战略目标过程
    • 企业系统规划法:自上而下识别系统目标、企业过程和数据,然后对数据分析,自下而上的设计信息系统。

信息系统的典型应用

image

  1. 电子政务
    • 政府对公务员(Government To Employee, G2E): 政府内部电子系统
    • 政府对企业(Government To Business, G2B): 在线采购招标、电子税务、电子证件办理、信息咨询服务和中小企业电子服务
    • 政府对公民(Government To Citizen, G2C): 就业服务、社保、交通管理、个人税务等
  2. 电子商务
    • B2B(Business To Business, 企业对企业):企业-企业、企业-平台-企业
    • B2C(Business To Customer, 企业对个人):平台企业面向个人的在线零售
    • C2C(Customer To Coustomer, 个人对个人):在线交易平台
  3. 电子商务发展基本原则
    • 企业主体、政府推动
    • 统筹兼顾、虚实结合
    • 着力创新、注重实效
    • 规范发展、保障安全
  4. 电子商务保障体系(法标安信在现技服运):法律法规体系、标准规范体系、安全认证体系、信用体系、在线支付体系、现代物流体系、技术装备体系、服务体系和运行监控体系
  5. 企业信息化: 企业作业、管理、决策的各个层面,科学计算、过程控制、事务处理、经营管理的各个领域,引入和使用现代信息技术,全面改革体制和机制,提高工作效率、市场竞争能力和经济效益。
    • 原则:效益原则;一把手(负责)原则;中长期与短期建设相结合原则;规范化和标准化原则;以人为本的原则;
    • 企业资源计划管理(ERP):
      • 企业资源:物质流、资金流和信息流
      • ERP核心概念:将管理的重心转移到财务上,在企业经营运作过程中贯穿了财务成本控制的概念。
      • ERP总体思路:一个中心(财务数据库为中心)、两类业务(计划与执行)、三条干线(供应链管理、生产管理和财务管理)
    • 客户关系管理(Customer Relationship Management, CRM): 改善企业与客户之间关系的管理机制。坚持以客户为中心的理念的基础上,重构市场营销和客户服务等业务流程。业务流程自动化的基础上确保前台应用系统能改进客户满意度、增加客户忠诚都。
    • 供应链管理(Supply Chain Management, SCM): 现代意义上的供应链师利用计算机网络技术全面规划供应链中的商流、物流、信息流、资金流等,并进行计划、组织、协调和控制。供应链管理至少包括一下六大应用功能:需求管理(预测和协作工作)、供应链计划(多工厂计划)、生产计划、生产调度、配送计划、运输计划
    • 企业门户:企业知识门户(Enterprise Knowledge Portal, EKP);企业信息门户(Enterprise Infomation Protal,EIP);企业应用门户(Enterprise Application Portal, EAP)

软件开发基础知识

软件开发方法

  1. 软件开发生命周期
    1. 需求规格说明书:包括系统名称、功能描述、接口、基本数据结构、性能、设计需求、开发标准、验收原则等。
    2. 概要设计:定义功能模块及功能模块之间的关系,详细设计研究模块内部,包括算法与数据结构、数据分布、数据组织、模块间信息接口和用户界面等设计。
    3. 测试:单元测试、集成测试、确认测试和系统测试
  2. 软件开发模型
    1. 瀑布模型(变种V模型):严格按照软件生命周期的各阶级顺序执行,有利于人员的组织管理,但明显的存在使用缺陷:用户并不能清晰定义及描述其需求、初始版本的呈现周期较长。只适合明确需求项目(大型项目很难明确需求)。

    2. 原型模型(简易系统的构造, 两种原型:抛弃型原型&演化型原型):原型模型的原理即提前通过可视化的方式呈现需求。适合需求不明确的项目。获取原型途径:
      • 利用模拟软件系统的人界界面和人机交互方式
      • 开发一个原型
      • 寻求一个或几个类似的软件
    3. 螺旋模型(快速原型+瀑布):实在快速原型的基础上扩展的,支持大型软件开发,适用于面向规格说明、面向规程和面向对象的软件开发方法,通常是将软件开发切割为多个周期,每个周期分为4个阶段:1. 目标设定; 2. 风险分析; 3. 开发和有效性验证; 4. 评审。
    4. 迭代(草台班子变成大佬团)与增量(强者不断加入团队):
    5. 构建组装模型
      • 基于构件的软件工程(CBSE 造不如买)
        • 顺序组装:C=A+B
        • 层次组装:C=A且C=B 兼容
        • 叠加组装:C=A+B且AB也可用
    6. 基于四代技术的模型,只侧重于支持软件的设计和实现阶段,并不支持全过程,其主要特征有:
      • 非过程化语言:通过生成器代替编程语言
      • 与数据库密切相关
  3. 敏捷方法(拥抱变化,以人为本平衡控制和自由,迭代增量开发过程。 适用于 1. 团队人数不能太多,较小规模项目; 2.项目变更频繁且需要快速改变,如果有比较高的关键性、可靠性、安全性方面的要求可能不完全适用; 3. 高风险项目; 4. 组织结构角度决定是否适用)
    1. 方法特点:适应性(√) 预设性(×) ; 面向人的(√) 面向过程的(×)
    2. 核心思想:
      • 适应性(√) 预设性(×)
      • 面向人的(√) 面向过程的(×), 以人为本而不是以过程为本
    3. 主要内容:
      • 4个核心价值观:沟通(设计-开发-客户之间坦率有效的沟通);简单(满足当下,代码简单化);反馈(坦率积极的沟通);勇气(改变的勇气)。
      • 12条过程实践原则:简单设计、测试驱动、代码重构、结对编程(设计-开发-客户)、持续集成、现场客户、发行版本小型化、系统隐喻、代码集体所有制、规划策略、40小时工作机制(每周工作时间不超过40小时的工作制度,推崇效率和团队工作的可持续性)。


  4. 统一过程(RUP)
    1. 9个核心工作流:业务建模、需求、分析与设计、实现、测试、部署、配置与管理、项目管理和环境。

    2. 4个阶段:初始、细化、构造和移交

    3. 特点:

      • 用例驱动
      • 以体系结构为核心:体系结构的设计与代码设计无关,不依赖于程序语言;体系结构层次的设计问题包括系统的总体组织和全局控制、通信协议、同步、数据存取、给设计元素分配特定功能、设计元素的组织、物理分布、系统的伸缩性和性能
      • 迭代与增量
    4. 不同人员视图重点:

      视图名称 关注点
      逻辑视图 描述系统功能,最终用户关注
      实现视图 描述系统配置、装配,程序员关注
      进程视图 描述系统性能、吞吐,集成人员关注
      部署视图 描述系统安装、拓扑结构,系统工程师关注
      用例视图 描述人机互动的系统行为,分析人员和测试人员关注
    5. 通用模板可以根据实际情况适量裁剪,裁剪步骤:

      • 确定开发过程涉及的工作流程
      • 确定工作流的产出
      • 确定4阶段间的演进
      • 确定每个阶段的迭代计划
      • 规划工作流内部结构(难点)
  5. 软件系统工具
    1. 软件工具衡量因素:功能、易用性、稳健性、硬件要求和性能、服务和支持
    2. 软件工具种类:需求分析工具、设计工具、编码与排错工具、测试工具等
    3. 软件系统工具一览表
工具分类 子分类 理解重点
需求分析工具 基于自然语言或图形描述的工具 反映用户需求的功能规范,帮助分析员提高需求文档的质量,降低功能规范的维护费用。结构化分析工具通常由图形编辑器、数据字典管理器和检测机制构成,典型的方法如数据流图
基于形式化需求定义语言的工具 以基于知识的需求智能助手形式出现,同行包括一个知识库和一个推理(运行)机制
其他需求分析工具 通过展示可执行的原型,方便进行需求确认
设计工具(设计规范) 概要设计规范:描述软件的功能模块及其相互关系,说明模块的处理过程和外部行为,同时还应描述数据的逻辑结构。
详细设计规范:描述每个模块的处理算法及涉及到的全部数据结构
编码与排错工具 编码工具 主要包括编辑程序、汇编程序、编译程序和生成程序。
其中:
编辑程序:对源程序进行增、删、改。
汇编程序:将汇编语言翻译成机器语言程序。
编译程序:将高级语言程序翻译成低级语言程序。
生成程序:通过特定语言描述的用户需求自动生成程序。
排错工具 包括源代码排错程序和排错程序的生成程序
软件维护工具 版本控制工具 用来存储、更新、恢复和管理一个软件的多个版本
文档分析工具 对文档进行分析,给出软件维护活动所需要的维护信息
开发信息库工具 用来维护软件项目的开发信息
逆向工程工具 反编译工具的使用属于逆向工程的范畴
再工程工具 目前的再工程工具主要集中在代码重构、程序结构重构和数据结构重构等方面
软件管理和软件支持工具 项目管理工具 一个项目管理工具通常把重点放在某一个或某几个特定的管理环节,而不是支持所有活动
配置管理工具 用以辅助完成软件配置项的标识、版本控制、变化控制、审计和状态统计等基本任务,简化审计过程,改进状态统计,减少错误,提高质量
软件评价工具 不能定量化度量的指标需要通过专家评分后再推送给评价工具,已经定量化的可利用评价工具自动获取。评价内容可以是程序结构,如Mc - Cabe可对环路复杂度进行度量

需求管理

需求管理(软件需求开发文档批准后,确立开发的需求基线)活动:变更控制、版本控制、需求跟踪、需求状态跟踪。

  1. 需求管理原则(CMM模型第2级关键过程域增加需求管理的内容)目标是:
    1. 为软件需求建立基线
    2. 软件计划、产品和活动与软件需求保持一致
  2. 需求规格说明的版本控制:版本控制信息应包括变更内容、日期、变更人员及变更原因
  3. 需求属性:创建时间、版本号、创建人、状态、原因和依据、涉及子系统、涉及产品版本号、验收/接受的标准、优先级、稳定性。
  4. 需求变更
    1. 严格控制软件项目,需要确保:评估(变更)、人选(评估&决策)、通知(所有人)
    2. 需求变更管理的目的是将变更产生的负面影响降低到最低,过程包括:问题分析和变更表述;变更分析和成本计算;变更实现;
    3. 需求变更应遵循原则:必须遵循变更控制程序;变更未经批准不得实施;变更应有变更控制委员会进行评估和决策;项目干系人有权获悉变更信息;变更库中的原始文档不得更改删除;变更的实施均应可追溯到已批准的变更请求。
    4. 变更控制委员会的总则/章程应包括变更控制委员会的目的、授权范围、成员构成、决策流程及操作步骤。
  5. 需求跟踪链类(Traceability link)型如下
    • 从客户需求向前追溯到软件需求(需求变更跟新至需求规格说明书)
    • 从软件需求回溯相应的客户需求(确认每个需求的源头)
    • 从软件需求向前追溯到下一级工作产品(逐步确保最终产品满足需求)
    • 从产品部件回溯到软件需求(验证部件来源)
  6. 需求变更的代价和风险
    • 变更只能在项目时间、预算、资源等的限制允许范围内进行协商
    • 进行影响分析的能力依赖于跟踪能力、数据的质量和完整性

开发管理

  1. 项目的范围、时间、成本
    1. 范围定义的输入:项目章程(初始的范围说明书)、项目范围管理计划、组织过程资产(过程性成果)、批准的变更申请。
    2. 时间管理的过程:活动定义(WBS)、活动排序、活动资源估算、活动历时估算、制定进度计划以及进度控制
    3. 成本管理活动:成本估算、成本预算(基线)、成本控制。
  2. 配置管理、文档管理
    1. 产品配置是指一个产品在其生命周期内个阶段产生的各种形式和各个版本的文档、计算机程序、部件及数据的集合。构成集合的元素称为配置项
    2. 配置项的分类:产品的工作成果,包括产品本身的文档;管理等过程中产生的文档
    3. 配置项的属性:名称、标识符、文件状态、版本、作者和日期
    4. 文档分类:用户文档(功能描述、安装文档、使用手册、参考手册、操作员指南)和系统文档(系统实现有关的文档)
  3. 软件开发的质量与风险
    1. 质量和等级的关系:质量数需求/要求的满足程度,等级是产品或服务的类别
    2. 风险的必要条件:与损失或收益相关、存在偶然性或不确定性、需要抉择

设计方法

  1. 结构化分析与设计:基本构件包括顺序、分支、循环
  2. 面向对象的分析设计
    1. 面向对象的分析模型:顶层架构图、用例与用例图、领域概念模型。
    2. 面向对象的设计模型:软件体系结构图、用例实现图、类图、状态图、活动图等。
    3. 步骤
      1. 根据用例设计实现方案(UML)
      2. 设计技术支撑设施(非功能性公共支撑件)
      3. 设计用户界面(类图)
    4. 设计模型则包含以包图表示的软件体系机构图、以交互图表示的用例实现图、完整精确的类图、描述复杂对象的状态图和用以描述流程化处理过程的活动图等。

软件重用

  1. 重用/复用的软件元素(软部件):需求分析文档、设计过程、设计文档、程序代码、测试用例和领域知识

  2. 软件重用的分类

    名称 对象 举例
    横向重用 不同应用领域中的软件元素 标准函数库
    纵向重用 共性应用领域间的软部件
  3. 软件重用的优势:提高生产率、降低开发成本、缩短开发周期、改善软件质量、提高灵活性和标准化程度

逆向工程与重构工程

  1. 基本概念: 逆向工程:分析已有程序,寻求比源码更高级的抽象表现形式(比如文档)的活动,是在不同抽象层级中进行的溯源行为;重构工程:是在同一抽象层级中转换系统描述的活动。
    • 逆向工程 -> 设计恢复 != 原设计
    • 对逆向工程所形成的系统进行修改或重构,生成新的版本称为重构工程
  2. 逆向工程信息恢复级别
  3. 逆向工程信息恢复方法

软件架构设计

软件架构概念

  1. 软件架构的定义:软件体系结构是指系统的一个或者多个结构,这些结构包括软件的构件(模块、类或者是中间件)、构件的外部可见属性及其之间的互相关系。体系结构的设计包括数据设计体系结构设计,后者主要关注软件构件的结构、属性和交互作用。

  2. 软件架构设计与生命周期

    1. 软件架构(SA) 是贯穿整个生命周期的,不同阶段的作用和意义不同。
    阶段 作用和意义
    需求阶段 有利于各阶段参与者的交流,也易于维护格阶段的可追踪性
    设计阶段 关注的最早和最多的阶段
    实现阶段 有效实现从软件架构设计向实现的转换
    构件组装阶段 可复用构件组装的设计能够提高系统实现的效率
    部署阶段 组织和展示部署阶段的软硬件架构、评估分析部署方案
    后开发阶段 主要围绕维护、演化、复用进行
    1. 体系结构描述语言(ADL) 是用于描述软件体系架构的语言,与其他建模语言最大的区别在于其更关注构件间互联机制(连接子,交互媒介), 典型的ADL语言包括:Unicon(支持构件和连接件的详细描述)、Rapide(体系结构的并发和事件驱动特性)、Darwin(描述动态变化的系统)、Wright(描述构件和连接件的交互协议)、C2SADL(描述基于C2风格的体系结构)、Acme(通用ADL,支持多种风格)、XADLOL、XYZ/ADL(精确的系统描述)和ABC/ADL(可扩展性和模块化)等。
    2. 多视图反映的是一组系统的不同方面,体现了关注点分散的思想,通常与ADL结合起来描述系统的体系结构。典型的模型包括:4+1模型、Hofmesiter的4视图模型、CMU-Sei的Views and Beyond模型。视图标准包括:IEEE的I471-2000、RM-ODP、UML以及IBM的Zachman。
    3. 视图不仅用于描述设计阶段的模型
    4. 实现阶段的体系结构研究的内容
      • 研究基于SA的开发过程支持
      • 寻求从SA向实现过度的途径
      • 研究基于SA的测试技术
    5. 缩小软件架构设计于底层实现概念差距的手段:模型转换技术、封装底层的实现细节、在SA模型中引入实现阶段的概念。
    6. 中间件支持的连接子(封装的连接机制)具有的优势
      • 中间件保证构件间通信完整性
      • 产品化的中间件能够更好的保证最终系统的质量属性
    7. 待复用构件对最终系统的结构体系和使用限定条件(环境假设)与实际状况不匹配造成的冲突,称为失配。包括:
      • 构件本身的失配
      • 连接子的失配
      • 部分和整体的失配
    8. 部署安装后(后开发阶段)的系统架构研究方向包括:动态软件体系结构、体系结构恢复与重建
    9. 体系结构重建的方法
      • 手工体系结构重建
      • 工具支持的手工重建
      • 通过查询语言来自动建立聚集
      • 使用其他技术(如数据挖掘)
  3. 软件架构的重要性

    1. 软件架构设计是降低成本、改进质量、按时和按需交付产品的关键因素
    2. 软件架构重要性:系统品质 ↑ ;受益人目标一致;支持计划编制过程;指导系统开发;降低管理复杂性;提高复用;降低维护费用;冲突分析。

基于架构的软件开发方法

  1. 体系结构的设计方法概述
    • 基于体系结构的软件设计方法(ABSD)从项目总体功能框架明确开始(需求尚未完成)
    • ABSD 方法的三个基础:功能分解通过选择体系结构风格来实现质量和商业需求软件模板的使用
  2. 概念与术语:ABSD 是自顶向下、递归细化的,迭代的每一步都有清晰的定义,有助于降低体系结构设计的随意性。
  3. 基于体系结构的开发模型:ABSDM模型把基于体系结构的软件开发过程依次划分为体系结构需求、体系结构设计、体系结构文档化、体系结构复审、体系结构实现和体系结构演化六个子过程。
  4. 体系结构需求
    • 体系结构需求工作包括获取用户需求和标识系统中拟用构件
    • 体系结构需求来源:质量目标系统的商业目标系统开发人员的商业目标
    • 标识构件分三步完成:生成类图 -> 对类进行分组 -> 把类打包成构件
    • 架构需求评审的审查重点包括需求是否真实反映了用户的要求、类的分组是否合理、构件合并是否合理等
  5. 体系结构设计
    • 软件的体系设计过程: 提出软件体系结构模型 -> 映射构件 -> 分析构件相互作用 -> 产生体系结构设计评审
    • 设计评审必须邀请独立于系统开发的外部人员
  6. 体系结构文档化:体系结构规格说明和测试体系结构需求的质量说明书
  7. 体系结构复审
    • 一个主版本的软件体系结构分析之后,要安排依次由外部人员(用户代表和领域专家)参加的复审
    • 复审的目的是标识潜风险,及早发现体系结构设计中的缺陷和错误,必要时,搭建demo模型测试是否满足需要。
  8. 体系结构实现
    • 体系结构实现过程是以复审后的文档化体系结构说明书为基础,具体为:分析与设计 -> 构件实现 -> 构件组装 -> 系统测试
    • 体系结构说明书中定义了系统中构件与构件之间的关系
    • 测试包括单个构件的功能性测试及被组装应用的整体功能和性能测试。
  9. 体系结构的演化
    • 体系结构演化使用系统演化步骤去修改应用,以满足新的需求
    • 演化步骤:需求变化归类 -> 体系结构演化计划 -> 构件变动 -> 更新构件的相互作用 -> 构件组装与测试 -> 技术评审 -> 演化后的体系结构

软件架构风格(软件复用/重用)

  1. 软件架构风格概述
    1. 一个体系结构定义一个词汇表和一组约束
    2. 词汇表包含构件连接件
    3. 约束定义构件和连接件的组合方式
  2. 经典软件体系结构风格
    1. 管道和过滤器:每个构件都有输入和输出
    2. 数据抽象和面向对象组:构件是对象,即抽象数据类型的实例
    3. 事件驱动系统:构件不直接调用一个过程,而是触发或广播一个或多个事件
    4. 分层系统:每一层为上层服务,并作为下层的接口。仅相邻层间具有层接口
    5. 仓库系统级知识库:
    6. C2风格:通过连接件连接构件或某个构建组,构件与构件之间无连接。
  3. 客户/服务器风格(C/S)
    1. 二层C/S 客户应用/服务器: 开发成本搞,客户端设计复杂,信息内容和形式单一,不利于推广,软件移植困难,软件维护和升级困难。
    2. 三层C/S 表示层(用户接口与应用逻辑层的交互,不影响业务逻辑)/功能层(处理业务逻辑)/数据层(读写数据库)
  4. 浏览器/服务器风格(B/S)
    1. B/S 风格是三层应用结构的实现方式:浏览器/Web服务器/数据库服务器
    2. 相比C/S不足之处:缺乏动态页面支持能力;系统拓展能力差;安全性难以控制;响应速度不足;数据交互性不强

特定领域软件体系结构

  1. DSSA的定义
    • DSSA 是在一个特定应用领域中为一组应用提供组织结构参考的标准软件体系结构,即用于某一类特定应用领域的标准软件构件集合
    • DSSA 特征:领域性、普遍性、抽象性、可复用性
  2. DSSA的基本活动(领域分析、领域设计、领域实现)
    • 领域分析:通过分析领域中系统的共性需求,建立领域模型
    • 领域设计:设计DSSA,且DSSA需要具备领域需求变化的适应性
    • 领域实现:获取可重用信息
  3. 参与DSSA人员:领域专家、领域分析师、领域设计人员和领域实现人员
  4. DSSA的建立过程:DSSA 过程是并发的、递归的、反复的螺旋模型,分为五个阶段
    1. 定义领域范围;
    2. 定义领域特定元素;
    3. 定义领域特定设计和实现约束;
    4. 定义领域模型和体系结构;
    5. 产生、搜集可重用的单元。

系统架构的评估

  1. 系统架构评估概述表
    属性 子属性 作用及要点
    性能 效率指标:处理任务所需时间或单位时间内的处理量
    可靠性 容错 出现错误后仍能保证系统争取运行,且自行修正错误
    健壮性 错误不对系统产生影响,按既定程序忽略错误
    可用性 正常运行的时间比例
    安全性 系统向合法用户提供服务并阻止非法用户的能力
    可修改性 可维护性 局部修复使故障对架构的负面影响最小化
    可拓展性 因松散耦合更易实现新特性/功能,不影响架构
    结构重组 不影响主体进行的灵活配置
    可移植性 适用于多样的环境(硬件平台、语言、操作系统等)
    功能性 需求的满足程度
    可变性 总体架构可变
    互操作性 通过可视化或接口方式提供更好的交互操作体验
  2. 评估中的重要概念
    • 敏感点:实现质量目标时应注意的点,即构件特性
    • 权衡点:影响多个质量属性的敏感点
    • 风险承担者(干系人|利益相关者):影响体系结构或体系结构影响的群体
    • 场景:确定架构质量评估目标的交互机制,一般采用触发机制、环境和影响三方面来描述
  3. 主要评估方法表
    项目 体系结构分析方法(Software Architecture Analysis Method, SAAM) 评价软件构架综合全面的方法(ATAM, SAAM基础上发展而来)
    特定目标 通过程序文档验证体系结构,注重发现潜在问题,可用于评价系统或进行多系统比较 确定在多个质量属性之间折中的必要性
    评估技术 场景技术 场景技术、启发式分析方法
    质量属性 可修改性是主要分析内容 性能、实用性安全性和可修改性
    风险承担者(干系人) 所有参与者 场景和需求手机过程中识别到的干系人
    体系结构描述 围绕功能、结构和分配描述 五个基本结构(逻辑视图、物理视图、过程视图、实现视图、需求视图)及其映射关系
    方法活动 场景开发、体系结构描述、单个场景评估、场景交互和总体评估 场景和需求收集、体系结构视图和场景实现、属性模型构造和分析、折中
    知识库可复用 不涉及 有基于属性的体系模型,可复用
    方法验证(应用领域) 空中交通管制系统、嵌入式音频系统、修正控制系统 仍处于研究中

建模与架构文档化

12-18分

UML基础

image
image

  1. UML的四种类型图特点及对应的视图
    • 用例图:从外部用户角度描述系统功能,并指出功能执行者
    • 静态图:显示了系统的静态结构,特别是存在事物的种类的内部结构相互之间的关系,包括类图、对象图、包图
    • 行为图:描述系统的动态模型和组成对象间的交互关系,包括交互图、状态图、活动图
    • 实现图:描述软件实现系统的组成和分布状况,包括构件图和部署图
  2. 用例和用例图
    • 用例图展现了一组用例、参与者及其之间的关系
    • 编写用例需识别的元素: 参与者; 用例间关系; 用例图; 用例之间的描述。
  3. 类图(类内部属性和行为)和对象图
    • 类与类之间的关系:① 关联; ② 聚集; ③ 组合; ④ 泛化; ⑤ 依赖
    • 建立类图步骤: ① 研究分析问题领域确定系统需求; ② 确定类,明确类的含义和职责、却动属性和操作; ③ 确定类之间的关系。
    • 对象图:表示在某一时刻一组对象及其之间的关系。可以看作是类图在系统某一时刻的实例。
    • 类图在系统的整个生命周期都是有效的,对象图只在系统的某一时间段存在。

  4. 包图:市一种维护和描述系统总体结构的模型的重要建模工具,描述系统的分解结构,表示包和包之间的关系,展现系统模块之间的依赖关系
  5. 交互图:描述对象之间的消息传递,包括:① 顺序图(时序图,对象之间交互); ② 协作图(描述系统的行为)。

  6. 状态图:对类图的补充,一个对象在其生命周期的动态行为
  7. 活动图:系统的工作图和并发行为
  8. 构件图:一组构件及其之间的相互关系。
  9. 部署图(配置图、实施图):可以用来显示系统中计算节点的拓扑结构和通信路径与节点上运行的软构件等,用于理解分布式系统

软件开发过程

  1. 基于UML进行需求分析。从业务需求描述出发获取执行者和场景,对场景进行汇总、分类、抽象,形成用例确定执行者与用例、用例与用例之间的关系,生成用例图。
  2. 面向对象设计
    • 设计步骤: ① 提取边界类、实体类和控制类;② 构造交互图; ③ 根据交互图精化类图。
    • 边界类:封装在用例内、外流动的信息或数据流。用于系统外部环境与内部运作之间的交互进行建模的类。隔离系统与外部环境的变更,阻止外部环境对系统其他部分造成影响。
    • 实体类:保存需要存储在永久存储体中的信息。一个参与者一般对应于实体类。
    • 控制类:控制用例工作的类,用于一个或几个用例特有的控制行为进行建模

系统架构文档化

  1. “4+1”视图:逻辑视图(Logical View)、过程视图(Process View)、物理视图(Physical View)、开发视图(Development View) + 场景。
    image
  2. 逻辑(设计)架构:设计的对象模型(使用面向对象的设计方法时)。支持功能性需求,采用抽象、封装或继承的原理,用来识别遍布系统各个部分的通用机制和设计元素。是类、子系统、包和用例实现的子集。
  3. 进程架构:捕捉设计的并发和同步特征。考虑非功能性需求,如性能和可用性。在几种层次的抽象上进行描述。是逻辑视图的一次执行实例。
  4. 开发架构:描述了在开发环境中软件的静态组织结构。用模块和子系统来表达,显示“输入”和“输出”关系
  5. 物理架构:描述了软件到硬件的映射,反映了分布式特性。主要关注系统非功能性需求如可用性、可靠性、性能和可伸缩性
  6. 场景:架构的描述,即所作的各种决定,可以围绕着这四个视图来组织,然后由一些用例(User Cases)或场景(Scenarios来说明形成“第五个视图”。

设计模式

4~8分

设计模式的原则

设计模式六大原则:① 单一职责原则; ② 里氏替换原则(子类替换父类); ③ 依赖倒置原则(高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象‌‌); ④ 接口隔离原则(不应依赖其不需要的接口,类的依赖应建立在最小化接口上); ⑤ 迪米特原则(最少知识法则); ⑥ 开闭原则(对扩展开放,对修改封闭| 抽象化)。
image

创建型模型

创建型模式:对对象实例化过程的抽象,通过采用抽象类所定义的接口,封装了系统中对象如何创建、组合等信息。

  1. 抽象工厂模式:提供一组或一系列相关的或相互依赖对象的接口。

    点击展开代码
    // 抽象产品:按钮
    interface Button {
        void render();
    }
    
    // 具体产品:Windows按钮
    class WindowsButton implements Button {
        @Override
        public void render() {
            System.out.println("Rendering a Windows Button");
        }
    }
    
    // 具体产品:MacOS按钮
    class MacOSButton implements Button {
        @Override
        public void render() {
            System.out.println("Rendering a MacOS Button");
        }
    }
    
    // 抽象产品:复选框
    interface Checkbox {
        void paint();
    }
    
    // 具体产品:Windows复选框
    class WindowsCheckbox implements Checkbox {
        @Override
        public void paint() {
            System.out.println("Painting a Windows Checkbox");
        }
    }
    
    // 具体产品:MacOS复选框
    class MacOSCheckbox implements Checkbox {
        @Override
        public void paint() {
            System.out.println("Painting a MacOS Checkbox");
        }
    }
    
    // 抽象工厂
    interface GUIFactory {
        Button createButton();
        Checkbox createCheckbox();
    }
    
    // 具体工厂:Windows工厂
    class WindowsFactory implements GUIFactory {
        @Override
        public Button createButton() {
            return new WindowsButton();
        }
    
        @Override
        public Checkbox createCheckbox() {
            return new WindowsCheckbox();
        }
    }
    
    // 具体工厂:MacOS工厂
    class MacOSFactory implements GUIFactory {
        @Override
        public Button createButton() {
            return new MacOSButton();
        }
    
        @Override
        public Checkbox createCheckbox() {
            return new MacOSCheckbox();
        }
    }
    
    // 客户端代码
    public class Application {
        private Button button;
        private Checkbox checkbox;
    
        public Application(GUIFactory factory) {
            button = factory.createButton();
            checkbox = factory.createCheckbox();
        }
    
        public void paint() {
            button.render();
            checkbox.paint();
        }
    
        public static void main(String[] args) {
            // 创建Windows UI
            GUIFactory windowsFactory = new WindowsFactory();
            Application windowsApp = new Application(windowsFactory);
            windowsApp.paint();
    
            // 创建MacOS UI
            GUIFactory macOSFactory = new MacOSFactory();
            Application macOSApp = new Application(macOSFactory);
            macOSApp.paint();
        }
    }
    
  2. 构建器模式:将复杂对象的构建与它的表示分离,是的同样的构建过程可以创造不同的表示

    点击展开代码
    // 产品类
    class Computer {
        private String cpu;
        private String ram;
        private String storage;
        private String gpu;
    
        // 参数为空的构造函数
        private Computer() {}
    
        // 静态内部类,构建器
        public static class ComputerBuilder {
            private String cpu;
            private String ram;
            private String storage;
            private String gpu;
    
            public ComputerBuilder(String cpu, String ram) {
                this.cpu = cpu;
                this.ram = ram;
            }
    
            public ComputerBuilder setStorage(String storage) {
                this.storage = storage;
                return this;
            }
    
            public ComputerBuilder setGpu(String gpu) {
                this.gpu = gpu;
                return this;
            }
    
            public Computer build() {
                Computer computer = new Computer();
                computer.cpu = this.cpu;
                computer.ram = this.ram;
                computer.storage = this.storage;
                computer.gpu = this.gpu;
                return computer;
            }
        }
    
        // Getter方法
        public String getCpu() {
            return cpu;
        }
    
        public String getRam() {
            return ram;
        }
    
        public String getStorage() {
            return storage;
        }
    
        public String getGpu() {
            return gpu;
        }
    }
    
    // 客户端代码
    public class BuilderPatternExample {
        public static void main(String[] args) {
            Computer gamingComputer = new Computer.ComputerBuilder("Intel Core i9", "32GB")
                    .setStorage("1TB SSD")
                    .setGpu("NVIDIA RTX 3080")
                    .build();
    
            System.out.println("Gaming Computer Specifications:");
            System.out.println("CPU: " + gamingComputer.getCpu());
            System.out.println("RAM: " + gamingComputer.getRam());
            System.out.println("Storage: " + gamingComputer.getStorage());
            System.out.println("GPU: " + gamingComputer.getGpu());
        }
    }
    
  3. 工厂方法模式:定义一个用于创建对象的接口,由子类决定实例化那个类的对象

    1. 优点:① 没有了将应用程序类绑定到代码中的要求,代码只处理接口,因此可以使用任何实现了接口的类; ② 允许子类提供对象的扩展版本; ③ 符合迪米特原则、依赖倒置原则、里氏替换原则。
    2. 缺点:需要Creator和相应的子类作为工厂类的载体,如果应用模型确实不需要Creator和子类存在,则需要增加一个类层次。
    3. 适用场景:① 当一个类不知道它所创建的产品的具体是哪个子类时; ② 当创建的对象希望下放到子类中进行时; ③ 类希望子类指定它要创建的对象。
    4. 应用举例:Woindows的COM组件与MFC,支付网关集成,数据库连接,游戏开发。
    点击展开代码
    // 1. 抽象产品接口
    interface Logger {
        void log(String message);
    }
    
    // 2. 具体产品实现
    class FileLogger implements Logger {
        @Override
        public void log(String message) {
            System.out.println("文件日志: " + message);
        }
    }
    
    class DatabaseLogger implements Logger {
        @Override
        public void log(String message) {
            System.out.println("数据库日志: " + message);
        }
    }
    
    class ConsoleLogger implements Logger {
        @Override
        public void log(String message) {
            System.out.println("控制台日志: " + message);
        }
    }
    
    // 3. 抽象工厂(创建者)
    abstract class LoggerFactory {
        // 工厂方法(核心)
        public abstract Logger createLogger();
        
        // 业务方法(使用工厂方法创建的产品)
        public void log(String message) {
            Logger logger = createLogger();
            logger.log(message);
        }
    }
    
    // 4. 具体工厂实现
    class FileLoggerFactory extends LoggerFactory {
        @Override
        public Logger createLogger() {
            return new FileLogger();
        }
    }
    
    class DatabaseLoggerFactory extends LoggerFactory {
        @Override
        public Logger createLogger() {
            return new DatabaseLogger();
        }
    }
    
    class ConsoleLoggerFactory extends LoggerFactory {
        @Override
        public Logger createLogger() {
            return new ConsoleLogger();
        }
    }
    
    // 5. 客户端使用
    public class FactoryMethodDemo {
        public static void main(String[] args) {
            // 创建文件日志工厂
            LoggerFactory fileFactory = new FileLoggerFactory();
            fileFactory.log("用户登录成功");
            
            // 创建数据库日志工厂
            LoggerFactory dbFactory = new DatabaseLoggerFactory();
            dbFactory.log("订单创建完成");
            
            // 创建控制台日志工厂
            LoggerFactory consoleFactory = new ConsoleLoggerFactory();
            consoleFactory.log("调试信息");
        }
    }
    
  4. 原型模式:指定创建对象的种类,并且通过拷贝这些原型创建新的对象。以一个对象作为原型,通过创建它来创建新的对象。主要用来创建创建非常消耗资源的对象。

    点击展开代码
    
    import java.util.ArrayList;
    import java.util.List;
    
    class Book implements Cloneable {
        private String title;
        private List<String> authors;
        private int pageCount;
    
        public Book(String title, List<String> authors, int pageCount) {
            this.title = title;
            this.authors = new ArrayList<>(authors); // 防御性复制
            this.pageCount = pageCount;
        }
    
        // 深拷贝实现
        @Override
        public Book clone() {
            try {
                Book clone = (Book) super.clone();
                // 对引用类型进行深拷贝
                clone.authors = new ArrayList<>(this.authors);
                return clone;
            } catch (CloneNotSupportedException e) {
                throw new AssertionError();
            }
        }
    
        // Getters and setters (同上)
        // ...
    }
    
    public class PrototypeDemo {
        public static void main(String[] args) {
            // 创建原始对象
            List<String> authors = new ArrayList<>();
            authors.add("J.K. Rowling");
            Book original = new Book("Harry Potter", authors, 400);
            
            // 克隆对象
            Book clone = original.clone();
            
            // 修改克隆对象
            clone.setTitle("Harry Potter - Clone Edition");
            clone.getAuthors().add("Ghost Writer");
            
            // 输出结果
            System.out.println("Original: " + original);
            System.out.println("Clone: " + clone);
        }
    }
    
    点击展开代码-原型注册表
    
    import java.util.HashMap;
    import java.util.Map;
    
    // 1. 原型接口
    interface Prototype extends Cloneable {
        Prototype clone();
    }
    
    // 2. 具体原型类
    class Novel implements Prototype {
        private String title;
        private String genre;
    
        public Novel(String title, String genre) {
            this.title = title;
            this.genre = genre;
        }
    
        @Override
        public Novel clone() {
            try {
                return (Novel) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new AssertionError();
            }
        }
    
        // Getters and setters
        // ...
    }
    
    // 3. 原型注册表(工厂)
    class PrototypeRegistry {
        private static final Map<String, Prototype> prototypes = new HashMap<>();
        
        static {
            // 预加载常用原型
            prototypes.put("defaultNovel", new Novel("Untitled", "Fiction"));
            prototypes.put("sciFiNovel", new Novel("Space Odyssey", "Science Fiction"));
        }
        
        public static Prototype getPrototype(String type) {
            Prototype prototype = prototypes.get(type);
            if (prototype == null) {
                throw new IllegalArgumentException("Unknown prototype type: " + type);
            }
            return prototype.clone();
        }
        
        public static void addPrototype(String key, Prototype prototype) {
            prototypes.put(key, prototype);
        }
    }
    
    // 4. 客户端使用
    public class RegistryDemo {
        public static void main(String[] args) {
            // 从注册表获取预定义原型
            Novel defaultBook = (Novel) PrototypeRegistry.getPrototype("defaultNovel");
            Novel sciFiBook = (Novel) PrototypeRegistry.getPrototype("sciFiNovel");
            
            // 定制克隆对象
            defaultBook.setTitle("My First Novel");
            sciFiBook.setTitle("Galaxy Quest");
            
            // 添加新原型到注册表
            PrototypeRegistry.addPrototype("mysteryNovel", new Novel("Secret Clues", "Mystery"));
            
            // 使用新原型
            Novel mysteryBook = (Novel) PrototypeRegistry.getPrototype("mysteryNovel");
            
            System.out.println("Default: " + defaultBook);
            System.out.println("Sci-Fi: " + sciFiBook);
            System.out.println("Mystery: " + mysteryBook);
        }
    }
    
  5. 单例模式:一个类只有一个实例,主要用于系统中一些核心对象创建。

    • 优点:① 对单个实例的受控制访问; ② 节省命名空间; ③ 允许改进操作和表示; ④ 允许可变数目的实例; ⑤ 比类操作更灵活。
    • 缺点:单例类的扩展困难,且职责过重,与“单一职责原则”存在冲突。
    • 适用场景:只能由一个类实例
    • 应用举例:主键生成器
    点击展开代码-饿汉模式(线程安全)
    public class EagerSingleton {
        // 类加载时就初始化实例
        private static final EagerSingleton instance = new EagerSingleton();
        
        // 私有构造器防止外部实例化
        private EagerSingleton() {}
        
        // 全局访问点
        public static EagerSingleton getInstance() {
            return instance;
        }
        
        // 示例方法
        public void doSomething() {
            System.out.println("EagerSingleton is doing something");
        }
    }
    
    点击展开代码-懒汉模式
    public class LazySingleton {
        private static LazySingleton instance;
        
        private LazySingleton() {}
        
        public static LazySingleton getInstance() {
            if (instance == null) {
                instance = new LazySingleton();
            }
            return instance;
        }
        
        public void doSomething() {
            System.out.println("LazySingleton is doing something");
        }
    }
    
    点击展开代码-懒汉模式(线程安全)
    public class SynchronizedSingleton {
        private static SynchronizedSingleton instance;
        
        private SynchronizedSingleton() {}
        
        // 同步方法保证线程安全
        public static synchronized SynchronizedSingleton getInstance() {
            if (instance == null) {
                instance = new SynchronizedSingleton();
            }
            return instance;
        }
        
        public void doSomething() {
            System.out.println("SynchronizedSingleton is doing something");
        }
    }
    
    点击展开代码-懒汉模式(线程安全-双因子检测)
    public class DoubleCheckedSingleton {
        // 使用volatile确保可见性和禁止指令重排序
        private volatile static DoubleCheckedSingleton instance;
        
        private DoubleCheckedSingleton() {}
        
        public static DoubleCheckedSingleton getInstance() {
            if (instance == null) { // 第一次检查
                synchronized (DoubleCheckedSingleton.class) {
                    if (instance == null) { // 第二次检查
                        instance = new DoubleCheckedSingleton();
                    }
                }
            }
            return instance;
        }
        
        public void doSomething() {
            System.out.println("DoubleCheckedSingleton is doing something");
        }
    }
    
    点击展开代码-静态内部类(推荐)
    public class StaticNestedSingleton {
        private StaticNestedSingleton() {}
        
        // 静态内部类在第一次使用时加载
        private static class SingletonHolder {
            private static final StaticNestedSingleton INSTANCE = new StaticNestedSingleton();
        }
        
        public static StaticNestedSingleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
        
        public void doSomething() {
            System.out.println("StaticNestedSingleton is doing something");
        }
    }
    
    点击展开代码-枚举类型(推荐)
    public enum EnumSingleton {
        INSTANCE;
        
        // 添加业务方法
        public void doSomething() {
            System.out.println("EnumSingleton is doing something");
        }
    }
    public class SingletonDemo {
        public static void main(String[] args) {
            // 使用枚举单例
            EnumSingleton.INSTANCE.doSomething();
            
            // 使用静态内部类单例
            StaticNestedSingleton.getInstance().doSomething();
            
            // 测试单例唯一性
            testSingletonUniqueness();
        }
        
        private static void testSingletonUniqueness() {
            // 创建多个"实例"
            EnumSingleton s1 = EnumSingleton.INSTANCE;
            EnumSingleton s2 = EnumSingleton.INSTANCE;
            
            // 验证是否为同一个实例
            System.out.println("s1 == s2: " + (s1 == s2)); // 输出 true
            System.out.println("s1 hashCode: " + s1.hashCode());
            System.out.println("s2 hashCode: " + s2.hashCode());
        }
    }
    

结构型模型

结构型模式:主要用于如何组合已有的类和对象以获得更大的结构,采用继承机制来组合接口或实现,以提供统一的外部视图或新的功能。

  1. 适配器模式:将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作得那些类可以一起工作。

    • 优点:① 允许两个或多个不兼容的对象
    • 缺点:过多地使用适配器会让系统非常零乱,不易整体进行把握
    • 适用场景:① 要使用已有地类,而该接口与所需的接口并不匹配; ② 要创建可重复的类,该类可以与不相干或未知类进行协助,即类之间不需要兼容接口; ③ 要在一个不同于已知对象接口的接口环境重使用对象;④ 必须要进行多个源之间的接口转换的时候
    • 应用举例:IO流中
    点击展开代码-继承
    // 目标接口:客户端期望的接口
    interface MediaPlayer {
        void play(String audioType, String fileName);
    }
    
    // 被适配者:已有的MP3播放器
    class Mp3Player {
        public void playMp3(String fileName) {
            System.out.println("Playing MP3 file: " + fileName);
        }
    }
    
    // 被适配者:新的VLC播放器
    class VlcPlayer {
        public void playVlc(String fileName) {
            System.out.println("Playing VLC file: " + fileName);
        }
    }
    
    // 被适配者:新的MP4播放器
    class Mp4Player {
        public void playMp4(String fileName) {
            System.out.println("Playing MP4 file: " + fileName);
        }
    }
    
    // 类适配器:通过继承实现适配
    class MediaAdapter extends Mp3Player implements MediaPlayer {
        private VlcPlayer vlcPlayer = new VlcPlayer();
        private Mp4Player mp4Player = new Mp4Player();
    
        @Override
        public void play(String audioType, String fileName) {
            if (audioType.equalsIgnoreCase("mp3")) {
                super.playMp3(fileName); // 使用父类方法
            } else if (audioType.equalsIgnoreCase("vlc")) {
                vlcPlayer.playVlc(fileName); // 使用组合对象
            } else if (audioType.equalsIgnoreCase("mp4")) {
                mp4Player.playMp4(fileName); // 使用组合对象
            } else {
                System.out.println("Unsupported format: " + audioType);
            }
        }
    }
    
    // 客户端代码
    public class ClassAdapterDemo {
        public static void main(String[] args) {
            MediaPlayer player = new MediaAdapter();
            
            player.play("mp3", "song.mp3");
            player.play("vlc", "movie.vlc");
            player.play("mp4", "video.mp4");
            player.play("avi", "clip.avi"); // 不支持格式
        }
    }
    
    点击展开代码-组合
    // 目标接口:客户端期望的接口
    interface MediaPlayer {
        void play(String audioType, String fileName);
    }
    
    // 被适配者接口
    interface AdvancedMediaPlayer {
        void playVlc(String fileName);
        void playMp4(String fileName);
    }
    
    // 被适配者实现:VLC播放器
    class VlcPlayer implements AdvancedMediaPlayer {
        @Override
        public void playVlc(String fileName) {
            System.out.println("Playing vlc file: " + fileName);
        }
    
        @Override
        public void playMp4(String fileName) {
            // 不支持
        }
    }
    
    // 被适配者实现:MP4播放器
    class Mp4Player implements AdvancedMediaPlayer {
        @Override
        public void playVlc(String fileName) {
            // 不支持
        }
    
        @Override
        public void playMp4(String fileName) {
            System.out.println("Playing mp4 file: " + fileName);
        }
    }
    
    // 对象适配器:通过组合实现适配
    class MediaAdapter implements MediaPlayer {
        private AdvancedMediaPlayer advancedMediaPlayer;
    
        public MediaAdapter(String audioType) {
            if (audioType.equalsIgnoreCase("vlc")) {
                advancedMediaPlayer = new VlcPlayer();
            } else if (audioType.equalsIgnoreCase("mp4")) {
                advancedMediaPlayer = new Mp4Player();
            }
        }
    
        @Override
        public void play(String audioType, String fileName) {
            if (audioType.equalsIgnoreCase("vlc")) {
                advancedMediaPlayer.playVlc(fileName);
            } else if (audioType.equalsIgnoreCase("mp4")) {
                advancedMediaPlayer.playMp4(fileName);
            }
        }
    }
    
    // 具体播放器实现(支持旧格式和新格式)
    class AudioPlayer implements MediaPlayer {
        private MediaAdapter mediaAdapter;
    
        @Override
        public void play(String audioType, String fileName) {
            // 内置支持MP3
            if (audioType.equalsIgnoreCase("mp3")) {
                System.out.println("Playing mp3 file: " + fileName);
            } 
            // 使用适配器支持其他格式
            else if (audioType.equalsIgnoreCase("vlc") || 
                     audioType.equalsIgnoreCase("mp4")) {
                mediaAdapter = new MediaAdapter(audioType);
                mediaAdapter.play(audioType, fileName);
            } 
            // 不支持格式
            else {
                System.out.println("Invalid media type: " + audioType);
            }
        }
    }
    
    // 客户端代码
    public class ObjectAdapterDemo {
        public static void main(String[] args) {
            AudioPlayer audioPlayer = new AudioPlayer();
    
            audioPlayer.play("mp3", "beyond_the_horizon.mp3");
            audioPlayer.play("mp4", "alone.mp4");
            audioPlayer.play("vlc", "far_far_away.vlc");
            audioPlayer.play("avi", "mind_me.avi");
        }
    }
    
  2. 桥接模式:将一个辅助的组件分成两个独立但又相关的继承层次结构:功能性的抽象内部实现。(JDBC驱动)

    点击展开代码
    // 实现部分接口:渲染器
    interface Renderer {
        void renderCircle(float radius);
        void renderSquare(float side);
    }
    
    // 具体实现:矢量渲染器
    class VectorRenderer implements Renderer {
        @Override
        public void renderCircle(float radius) {
            System.out.println("Drawing a circle of radius " + radius + " using vector graphics");
        }
    
        @Override
        public void renderSquare(float side) {
            System.out.println("Drawing a square of side " + side + " using vector graphics");
        }
    }
    
    // 具体实现:栅格渲染器
    class RasterRenderer implements Renderer {
        @Override
        public void renderCircle(float radius) {
            System.out.println("Drawing a circle of radius " + radius + " using pixels");
        }
    
        @Override
        public void renderSquare(float side) {
            System.out.println("Drawing a square of side " + side + " using pixels");
        }
    }
    
    // 抽象部分:形状
    abstract class Shape {
        protected Renderer renderer;
        
        public Shape(Renderer renderer) {
            this.renderer = renderer;
        }
        
        public abstract void draw();
        public abstract void resize(float factor);
    }
    
    // 扩充抽象:圆形
    class Circle extends Shape {
        private float radius;
        
        public Circle(Renderer renderer, float radius) {
            super(renderer);
            this.radius = radius;
        }
        
        @Override
        public void draw() {
            renderer.renderCircle(radius);
        }
        
        @Override
        public void resize(float factor) {
            radius *= factor;
        }
    }
    
    // 扩充抽象:正方形
    class Square extends Shape {
        private float side;
        
        public Square(Renderer renderer, float side) {
            super(renderer);
            this.side = side;
        }
        
        @Override
        public void draw() {
            renderer.renderSquare(side);
        }
        
        @Override
        public void resize(float factor) {
            side *= factor;
        }
    }
    
    // 客户端代码
    public class BridgePatternDemo {
        public static void main(String[] args) {
            // 创建不同渲染器
            Renderer vectorRenderer = new VectorRenderer();
            Renderer rasterRenderer = new RasterRenderer();
            
            // 创建不同形状并绘制
            Shape circle = new Circle(vectorRenderer, 5);
            circle.draw();
            
            Shape square = new Square(rasterRenderer, 10);
            square.draw();
            
            // 调整大小后重新绘制
            System.out.println("\nResizing shapes:");
            circle.resize(2);
            circle.draw();
            
            square.resize(0.5f);
            square.draw();
        }
    }
    
  3. 组合模式:将对象组合成树型结构以表示“部分-整体”之间的层次结构

    • 优点:① 清楚地定义分层次地复杂对象,表示对象地全部或部分层次; ② 使得增加新构件更容易; ③ 提高了结构得灵活性和可管理得接口。
    • 缺点:使设计变得更加抽象,如果对象得业务规则很复杂,则实现组合模式很困难(并非所有方法都与叶子对象子类有关联)
    • 适用场景:① 表示对象得部分-整体层次结构; ② 希望用户忽略组合对象与单个对象得不同,用户统一使用组合结构中得所有对象; ③ 结构可以具有任何级别得复杂性,而且使动态的。
    • 应用举例:文件、文件夹的管理
    点击展开代码
    import java.util.ArrayList;
    import java.util.List;
    
    // 抽象组件:文件系统接口
    interface FileSystemComponent {
        void display(int indent);
        void add(FileSystemComponent component);
        void remove(FileSystemComponent component);
    }
    
    // 叶子节点:文件
    class File implements FileSystemComponent {
        private String name;
        
        public File(String name) {
            this.name = name;
        }
        
        @Override
        public void display(int indent) {
            System.out.println(" ".repeat(indent) + "- 文件: " + name);
        }
        
        @Override
        public void add(FileSystemComponent component) {
            throw new UnsupportedOperationException("不能向文件添加内容");
        }
        
        @Override
        public void remove(FileSystemComponent component) {
            throw new UnsupportedOperationException("不能从文件移除内容");
        }
    }
    
    // 组合节点:目录
    class Directory implements FileSystemComponent {
        private String name;
        private List<FileSystemComponent> children = new ArrayList<>();
        
        public Directory(String name) {
            this.name = name;
        }
        
        @Override
        public void display(int indent) {
            System.out.println(" ".repeat(indent) + "+ 目录: " + name);
            for (FileSystemComponent component : children) {
                component.display(indent + 2);
            }
        }
        
        @Override
        public void add(FileSystemComponent component) {
            children.add(component);
        }
        
        @Override
        public void remove(FileSystemComponent component) {
            children.remove(component);
        }
    }
    
    // 客户端使用
    public class CompositePatternDemo {
        public static void main(String[] args) {
            // 创建根目录
            Directory root = new Directory("根目录");
            
            // 创建子目录
            Directory documents = new Directory("文档");
            Directory images = new Directory("图片");
            
            // 创建文件
            File file1 = new File("简历.doc");
            File file2 = new File("报告.xlsx");
            File image1 = new File("照片.jpg");
            
            // 构建树形结构
            root.add(documents);
            root.add(images);
            
            documents.add(file1);
            documents.add(file2);
            
            images.add(image1);
            images.add(new Directory("截图")); // 目录中嵌套目录
            
            // 显示整个结构
            System.out.println("文件系统结构:");
            root.display(0);
        }
    }
    
  4. 装饰模式:动态的给对象添加一些额外的责任,在增加功能方面比生成子类更加灵活

    点击展开代码
    // 定义一个组件接口
    interface Component {
        void operation();
    }
    
    // 具体组件类
    class ConcreteComponent implements Component {
        @Override
        public void operation() {
            System.out.println("ConcreteComponent: 执行基本操作。");
        }
    }
    
    // 装饰器抽象类,继承自组件接口
    abstract class Decorator implements Component {
        protected Component component;
    
        public Decorator(Component component) {
            this.component = component;
        }
    
        @Override
        public void operation() {
            component.operation();
        }
    }
    
    // 具体装饰器类A
    class ConcreteDecoratorA extends Decorator {
        public ConcreteDecoratorA(Component component) {
            super(component);
        }
    
        @Override
        public void operation() {
            super.operation();
            addedBehaviorA();
        }
    
        private void addedBehaviorA() {
            System.out.println("ConcreteDecoratorA: 添加额外的行为A。");
        }
    }
    
    // 具体装饰器类B
    class ConcreteDecoratorB extends Decorator {
        public ConcreteDecoratorB(Component component) {
            super(component);
        }
    
        @Override
        public void operation() {
            super.operation();
            addedBehaviorB();
        }
    
        private void addedBehaviorB() {
            System.out.println("ConcreteDecoratorB: 添加额外的行为B。");
        }
    }
    
    // 客户端代码
    public class DecoratorPatternDemo {
        public static void main(String[] args) {
            Component component = new ConcreteComponent();
            System.out.println("基本组件操作:");
            component.operation();
    
            System.out.println("\n装饰后的组件操作(使用ConcreteDecoratorA):");
            Component decoratorA = new ConcreteDecoratorA(component);
            decoratorA.operation();
    
            System.out.println("\n装饰后的组件操作(使用ConcreteDecoratorA和ConcreteDecoratorB):");
            Component decoratorB = new ConcreteDecoratorB(decoratorA);
            decoratorB.operation();
        }
    }
    
  5. 外观模式:为子系统中的一组接口提供一个统一的接口,外观模式通过提供一个高层接口,隔离了外部系统与子系统间复杂的交互过程,简化复杂子系统的使用(操作界面)。

    • 优点:① 再不较少系统所提供的选项的情况下,为复杂系统提供了简单的接口; ② 对客户端屏蔽了子系统组件; ③ 提高了咨询欧统与其客户端之间的弱耦合度; ④ 将客户端请求转换后发送给能处理这些请求的子系统。
    • 缺点:① 不能很好的限制客户使用子系统类,如果对客户访问子系统类做太多限制,则减少二零可变性和灵活性; ② 在不引入抽象外观类的情况下,增加新的子系统可能需要需改外观类或客户端的源代码,违反了“开闭原则”
    • 适用场景:① 为复杂子系统提供简单接口;② 客户程序与抽象类的实现部分之间存在着依赖性; ③ 构建一个层次结构的子系统时,定义子系统中每层的入口点,如果子系统之间相互通过外观类通信,简化之间的依赖关系
    • 应用举例:IO流
    点击展开代码
    // 子系统组件:灯光
    class LightSystem {
        public void turnOn() {
            System.out.println("灯光已打开");
        }
        
        public void turnOff() {
            System.out.println("灯光已关闭");
        }
        
        public void dim(int level) {
            System.out.println("灯光调暗至 " + level + "%");
        }
    }
    
    // 子系统组件:空调
    class AirConditioner {
        public void turnOn() {
            System.out.println("空调已打开");
        }
        
        public void turnOff() {
            System.out.println("空调已关闭");
        }
        
        public void setTemperature(int temp) {
            System.out.println("空调温度设置为 " + temp + "°C");
        }
    }
    
    // 子系统组件:电视
    class Television {
        public void turnOn() {
            System.out.println("电视已打开");
        }
        
        public void turnOff() {
            System.out.println("电视已关闭");
        }
        
        public void setChannel(String channel) {
            System.out.println("电视频道切换到 " + channel);
        }
    }
    
    // 子系统组件:音响
    class SoundSystem {
        public void turnOn() {
            System.out.println("音响已打开");
        }
        
        public void turnOff() {
            System.out.println("音响已关闭");
        }
        
        public void setVolume(int level) {
            System.out.println("音响音量设置为 " + level);
        }
    }
    
    // 子系统组件:窗帘
    class CurtainSystem {
        public void open() {
            System.out.println("窗帘已打开");
        }
        
        public void close() {
            System.out.println("窗帘已关闭");
        }
    }
    
    // 外观类:智能家居控制中心
    class SmartHomeFacade {
        private LightSystem lights;
        private AirConditioner ac;
        private Television tv;
        private SoundSystem sound;
        private CurtainSystem curtains;
        
        public SmartHomeFacade() {
            this.lights = new LightSystem();
            this.ac = new AirConditioner();
            this.tv = new Television();
            this.sound = new SoundSystem();
            this.curtains = new CurtainSystem();
        }
        
        // 一键开启电影模式
        public void startMovieMode() {
            System.out.println("\n=== 启动电影模式 ===");
            curtains.close();
            lights.dim(10);
            ac.setTemperature(22);
            tv.turnOn();
            tv.setChannel("电影频道");
            sound.turnOn();
            sound.setVolume(25);
        }
        
        // 一键关闭所有设备
        public void turnOffAll() {
            System.out.println("\n=== 关闭所有设备 ===");
            lights.turnOff();
            ac.turnOff();
            tv.turnOff();
            sound.turnOff();
            curtains.open();
        }
        
        // 一键开启回家模式
        public void arriveHome() {
            System.out.println("\n=== 启动回家模式 ===");
            curtains.open();
            lights.turnOn();
            ac.turnOn();
            ac.setTemperature(24);
        }
        
        // 一键开启睡眠模式
        public void sleepMode() {
            System.out.println("\n=== 启动睡眠模式 ===");
            tv.turnOff();
            sound.turnOff();
            lights.dim(5);
            curtains.close();
            ac.setTemperature(26);
        }
    }
    
    // 客户端使用
    public class FacadePatternDemo {
        public static void main(String[] args) {
            SmartHomeFacade smartHome = new SmartHomeFacade();
            
            // 用户通过简单接口控制复杂系统
            smartHome.arriveHome();
            smartHome.startMovieMode();
            smartHome.sleepMode();
            smartHome.turnOffAll();
        }
    }
    
  6. 享元模式:通过共享对象减少系统中低等级的,详细的对象数目。

    点击展开代码
    import java.util.*;
    
    // 1. 享元接口:定义粒子的操作
    interface Particle {
        void draw(int x, int y, int size);
    }
    
    // 2. 具体享元类:实现粒子类型(包含内在状态)
    class ParticleType implements Particle {
        private final String color;
        private final String texture;
        
        public ParticleType(String color, String texture) {
            this.color = color;
            this.texture = texture;
        }
        
        @Override
        public void draw(int x, int y, int size) {
            System.out.printf("在(%d,%d)绘制一个%s的%s粒子,大小:%d\n", 
                             x, y, color, texture, size);
        }
        
        // 用于在享元工厂中作为键值
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            ParticleType that = (ParticleType) o;
            return Objects.equals(color, that.color) && 
                   Objects.equals(texture, that.texture);
        }
        
        @Override
        public int hashCode() {
            return Objects.hash(color, texture);
        }
    }
    
    // 3. 享元工厂:管理和复用粒子类型
    class ParticleFactory {
        private static Map<String, ParticleType> particleTypes = new HashMap<>();
        
        public static ParticleType getParticleType(String color, String texture) {
            String key = color + "_" + texture;
            ParticleType type = particleTypes.get(key);
            // 工厂中没有的则新出创建出来
            if (type == null) {
                type = new ParticleType(color, texture);
                particleTypes.put(key, type);
                System.out.println("创建新的粒子类型: " + key);
            }
            
            return type;
        }
        
        public static int getTypeCount() {
            return particleTypes.size();
        }
    }
    
    // 4. 上下文类:包含外部状态(位置、大小)
    class ParticleContext {
        private int x;
        private int y;
        private int size;
        private Particle particleType;
        
        public ParticleContext(int x, int y, int size, Particle particleType) {
            this.x = x;
            this.y = y;
            this.size = size;
            this.particleType = particleType;
        }
        
        public void draw() {
            particleType.draw(x, y, size);
        }
    }
    
    // 5. 粒子系统:管理大量粒子
    class ParticleSystem {
        private List<ParticleContext> particles = new ArrayList<>();
        private Random random = new Random();
        
        public void addParticle(int x, int y, String color, String texture) {
            // 随机大小:5-15像素
            int size = random.nextInt(10) + 5;
            Particle type = ParticleFactory.getParticleType(color, texture);
            particles.add(new ParticleContext(x, y, size, type));
        }
        
        public void drawAll() {
            System.out.println("\n绘制所有粒子...");
            for (ParticleContext particle : particles) {
                particle.draw();
            }
        }
        
        public int getParticleCount() {
            return particles.size();
        }
    }
    
    // 6. 客户端代码
    public class FlyweightPatternDemo {
        public static void main(String[] args) {
            // 创建粒子系统
            ParticleSystem system = new ParticleSystem();
            
            // 添加大量粒子(只使用少量类型)
            for (int i = 0; i < 100; i++) {
                // 只使用有限的几种颜色和纹理组合
                String color = getRandomColor();
                String texture = getRandomTexture();
                
                // 随机位置
                int x = new Random().nextInt(1000);
                int y = new Random().nextInt(1000);
                
                system.addParticle(x, y, color, texture);
            }
            
            // 绘制所有粒子
            system.drawAll();
            
            // 显示统计数据
            System.out.println("\n===== 系统统计 =====");
            System.out.println("粒子总数: " + system.getParticleCount());
            System.out.println("粒子类型数: " + ParticleFactory.getTypeCount());
            System.out.println("内存节省: " + (system.getParticleCount() - ParticleFactory.getTypeCount()) + " 个对象");
        }
        
        private static String getRandomColor() {
            String[] colors = {"红色", "蓝色", "绿色", "黄色", "紫色"};
            return colors[new Random().nextInt(colors.length)];
        }
        
        private static String getRandomTexture() {
            String[] textures = {"火焰", "水珠", "烟雾", "星光", "魔法"};
            return textures[new Random().nextInt(textures.length)];
        }
    }
    
  7. 代理模式:为控制对初始对象的访问,提供了一个代理或者占位符对象

    • 优点:① 远程代码可以隐藏对象位于不同的地址空间的事实; ② 虚拟代理可以执行优化操作。
    • 缺点:① 请求的处理速度变慢; ② 实现代理模式需要额外的工作,从而增加了系统实现的复杂度
    • 适用场景:① 当需要为一个对象在不同的地址空间提供局部的代表时; ② 当需要创建开销非常大的对象时;
    • 应用举例:防火墙代理
    点击展开代码
    import java.util.*;
    
    // 1. 服务接口:定义互联网访问功能
    interface Internet {
        void connectTo(String serverHost) throws Exception;
        void displayCache();
    }
    
    // 2. 真实服务:实现实际的互联网连接
    class RealInternet implements Internet {
        @Override
        public void connectTo(String serverHost) {
            System.out.println("✅ 成功连接到服务器: " + serverHost);
        }
    
        @Override
        public void displayCache() {
            System.out.println("真实服务没有缓存功能");
        }
    }
    
    // 3. 代理类:控制对真实服务的访问
    class InternetProxy implements Internet {
        private Internet realInternet = new RealInternet();
        private Set<String> bannedSites = new HashSet<>();
        private Map<String, Long> accessCache = new HashMap<>();
        private int maxConnectionsPerMinute = 3;
        private Map<String, Integer> connectionCounts = new HashMap<>();
        private long lastResetTime = System.currentTimeMillis();
    
        public InternetProxy() {
            // 初始化禁止访问的网站
            bannedSites.add("hacker.com");
            bannedSites.add("malware.org");
            bannedSites.add("piracy.net");
        }
    
        @Override
        public void connectTo(String serverHost) throws Exception {
            // 检查是否在禁止名单中
            if (bannedSites.contains(serverHost.toLowerCase())) {
                throw new Exception("🚫 访问被拒绝: " + serverHost + " 是禁止网站");
            }
    
            // 检查访问频率限制
            checkRateLimit(serverHost);
    
            // 检查缓存
            if (accessCache.containsKey(serverHost)) {
                System.out.println("⚡ 从缓存加载: " + serverHost + 
                                   " (上次访问: " + formatTime(accessCache.get(serverHost)) + ")");
                return;
            }
    
            // 记录访问时间并连接真实服务
            long accessTime = System.currentTimeMillis();
            realInternet.connectTo(serverHost);
            accessCache.put(serverHost, accessTime);
        }
    
        @Override
        public void displayCache() {
            System.out.println("\n🌐 访问缓存:");
            if (accessCache.isEmpty()) {
                System.out.println("缓存为空");
                return;
            }
            
            accessCache.entrySet().stream()
                .sorted(Map.Entry.comparingByValue())
                .forEach(entry -> 
                    System.out.println("- " + entry.getKey() + 
                                      " (访问时间: " + formatTime(entry.getValue()) + ")")
                );
        }
    
        // 添加禁止网站
        public void banSite(String site) {
            bannedSites.add(site.toLowerCase());
            System.out.println("🛑 已将 " + site + " 加入禁止名单");
        }
    
        // 解禁网站
        public void unbanSite(String site) {
            if (bannedSites.remove(site.toLowerCase())) {
                System.out.println("✅ 已解禁 " + site);
            }
        }
    
        // 检查访问频率限制
        private void checkRateLimit(String serverHost) throws Exception {
            // 每分钟重置计数器
            if (System.currentTimeMillis() - lastResetTime > 60_000) {
                connectionCounts.clear();
                lastResetTime = System.currentTimeMillis();
            }
    
            int count = connectionCounts.getOrDefault(serverHost, 0) + 1;
            connectionCounts.put(serverHost, count);
    
            if (count > maxConnectionsPerMinute) {
                throw new Exception("⚠️ 访问频率过高: " + serverHost + 
                                   " (每分钟最多 " + maxConnectionsPerMinute + " 次)");
            }
        }
    
        // 格式化时间戳
        private String formatTime(long timestamp) {
            return new Date(timestamp).toString().substring(11, 19);
        }
    }
    
    // 4. 客户端类:使用代理访问互联网
    public class ProxyPatternDemo {
        public static void main(String[] args) {
            Internet internet = new InternetProxy();
            Scanner scanner = new Scanner(System.in);
            
            System.out.println("=== 互联网访问系统 ===");
            System.out.println("可用命令:");
            System.out.println("connect <网站> - 连接到一个网站");
            System.out.println("ban <网站>    - 禁止一个网站");
            System.out.println("unban <网站>  - 解禁一个网站");
            System.out.println("cache         - 显示访问缓存");
            System.out.println("exit          - 退出系统");
            
            while (true) {
                System.out.print("\n> ");
                String command = scanner.nextLine();
                
                if (command.equalsIgnoreCase("exit")) {
                    break;
                }
                
                String[] parts = command.split(" ", 2);
                String action = parts[0].toLowerCase();
                String param = parts.length > 1 ? parts[1] : "";
                
                try {
                    switch (action) {
                        case "connect":
                            internet.connectTo(param);
                            break;
                        case "ban":
                            ((InternetProxy) internet).banSite(param);
                            break;
                        case "unban":
                            ((InternetProxy) internet).unbanSite(param);
                            break;
                        case "cache":
                            internet.displayCache();
                            break;
                        default:
                            System.out.println("未知命令: " + command);
                            System.out.println("可用命令: connect, ban, unban, cache, exit");
                    }
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
            
            scanner.close();
            System.out.println("系统已退出");
        }
    }
    
  8. 适配器模式 vs 装饰器模式 vs 代理模式

    模式 目的 关系
    适配器 转换接口 不同接口间的桥梁
    装饰器 增强功能 保持接口,添加功能
    代理 控制访问 提供接口的替代品

行为型模型

行为型模型:从大量实际行动中概括出来的理论抽象、基本框架和标准。该类模式主要用于对象之间的职责及其提供的服务,不仅描述对象或类的模式,还描述它们之间的通信模式。

  1. 责任链模式(Chain of Responsibility):在系统中建立一个链,消息可以首先接收到它的级别被处理,或者定位到可以处理它的对象。链式依次处理。

    • 优点:① 降低耦合度; ② 增加向对象指定责任的灵活性。
    • 适用场景:① 多个对象可以处理一个请求,而其处理器却是未知的; ② 可以动态指定能够处理请求的对象集。
    点击展开代码
    import java.util.Scanner;
    
    // 请求类:包含贷款申请信息
    class LoanRequest {
        private String customerName;
        private double amount;
        private int duration; // 贷款期限(月)
        private String purpose;
        
        public LoanRequest(String customerName, double amount, int duration, String purpose) {
            this.customerName = customerName;
            this.amount = amount;
            this.duration = duration;
            this.purpose = purpose;
        }
        
        public String getCustomerName() {
            return customerName;
        }
        
        public double getAmount() {
            return amount;
        }
        
        public int getDuration() {
            return duration;
        }
        
        public String getPurpose() {
            return purpose;
        }
        
        @Override
        public String toString() {
            return String.format("贷款申请: %s\n金额: ¥%.2f\n期限: %d月\n用途: %s", 
                                customerName, amount, duration, purpose);
        }
    }
    
    // 处理者接口
    interface LoanHandler {
        void setNextHandler(LoanHandler nextHandler);
        void handleRequest(LoanRequest request);
    }
    
    // 具体处理者:初级审批员(处理小额贷款)
    class JuniorLoanOfficer implements LoanHandler {
        private static final double MAX_AMOUNT = 50_000;
        private LoanHandler nextHandler;
        
        @Override
        public void setNextHandler(LoanHandler nextHandler) {
            this.nextHandler = nextHandler;
        }
        
        @Override
        public void handleRequest(LoanRequest request) {
            if (request.getAmount() <= MAX_AMOUNT) {
                System.out.println("\n🔹 初级审批员处理:");
                System.out.println(request);
                System.out.println("✅ 审批通过: 小额贷款由初级审批员批准");
                System.out.println("------------------------------");
            } else if (nextHandler != null) {
                System.out.println("🔸 初级审批员: 超出权限,转交上级");
                nextHandler.handleRequest(request);
            } else {
                System.out.println("❌ 无法处理该贷款申请");
            }
        }
    }
    
    // 具体处理者:高级审批员(处理中等额度贷款)
    class SeniorLoanOfficer implements LoanHandler {
        private static final double MAX_AMOUNT = 500_000;
        private LoanHandler nextHandler;
        
        @Override
        public void setNextHandler(LoanHandler nextHandler) {
            this.nextHandler = nextHandler;
        }
        
        @Override
        public void handleRequest(LoanRequest request) {
            if (request.getAmount() <= MAX_AMOUNT) {
                System.out.println("\n🔹 高级审批员处理:");
                System.out.println(request);
                
                // 特殊业务逻辑:短期大额贷款需要额外审查
                if (request.getAmount() > 300_000 && request.getDuration() < 6) {
                    System.out.println("⚠️ 需要额外审查: 短期大额贷款");
                    System.out.println("✅ 审批通过: 附加额外条件");
                } else {
                    System.out.println("✅ 审批通过: 中等额度贷款由高级审批员批准");
                }
                
                System.out.println("------------------------------");
            } else if (nextHandler != null) {
                System.out.println("🔸 高级审批员: 超出权限,转交上级");
                nextHandler.handleRequest(request);
            } else {
                System.out.println("❌ 无法处理该贷款申请");
            }
        }
    }
    
    // 具体处理者:贷款委员会(处理大额贷款)
    class LoanCommittee implements LoanHandler {
        private static final double MAX_AMOUNT = 5_000_000;
        private LoanHandler nextHandler;
        
        @Override
        public void setNextHandler(LoanHandler nextHandler) {
            this.nextHandler = nextHandler;
        }
        
        @Override
        public void handleRequest(LoanRequest request) {
            if (request.getAmount() <= MAX_AMOUNT) {
                System.out.println("\n🔹 贷款委员会处理:");
                System.out.println(request);
                
                // 委员会审批逻辑
                if (request.getPurpose().toLowerCase().contains("房产")) {
                    System.out.println("✅ 审批通过: 房产贷款项目优先批准");
                } else if (request.getAmount() > 2_000_000) {
                    System.out.println("⚠️ 需要股东会批准: 超大型贷款项目");
                    System.out.println("✅ 审批通过: 附加特别条款");
                } else {
                    System.out.println("✅ 审批通过: 大额贷款由委员会批准");
                }
                
                System.out.println("------------------------------");
            } else if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                System.out.println("❌ 拒绝: 贷款金额超过银行最大限额");
            }
        }
    }
    
    // 具体处理者:CEO(处理特殊贷款)
    class CEO implements LoanHandler {
        @Override
        public void setNextHandler(LoanHandler nextHandler) {
            // CEO是最终处理者,没有下一个
        }
        
        @Override
        public void handleRequest(LoanRequest request) {
            System.out.println("\n🔹 CEO亲自处理:");
            System.out.println(request);
            
            // CEO特殊审批逻辑
            if (request.getCustomerName().equalsIgnoreCase("VIP客户")) {
                System.out.println("⭐ 特殊批准: VIP客户特权");
                System.out.println("✅ 审批通过: 无附加条件");
            } else if (request.getPurpose().toLowerCase().contains("紧急")) {
                System.out.println("⚠️ 紧急贷款: 附加高利率");
                System.out.println("✅ 审批通过: 特殊紧急情况");
            } else {
                System.out.println("❌ 拒绝: 不符合CEO特殊批准条件");
            }
            
            System.out.println("------------------------------");
        }
    }
    
    // 客户端:构建责任链并提交请求
    public class ChainOfResponsibilityDemo {
        public static void main(String[] args) {
            // 构建责任链
            LoanHandler junior = new JuniorLoanOfficer();
            LoanHandler senior = new SeniorLoanOfficer();
            LoanHandler committee = new LoanCommittee();
            LoanHandler ceo = new CEO();
            
            // 设置链的顺序
            junior.setNextHandler(senior);
            senior.setNextHandler(committee);
            committee.setNextHandler(ceo);
            
            Scanner scanner = new Scanner(System.in);
            
            System.out.println("===== 银行贷款审批系统 =====");
            
            while (true) {
                System.out.println("\n请输入贷款申请信息 (输入 exit 退出):");
                
                System.out.print("客户姓名: ");
                String name = scanner.nextLine();
                if (name.equalsIgnoreCase("exit")) break;
                
                System.out.print("贷款金额: ");
                double amount = Double.parseDouble(scanner.nextLine());
                
                System.out.print("贷款期限(月): ");
                int duration = Integer.parseInt(scanner.nextLine());
                
                System.out.print("贷款用途: ");
                String purpose = scanner.nextLine();
                
                // 创建贷款请求
                LoanRequest request = new LoanRequest(name, amount, duration, purpose);
                
                System.out.println("\n=== 开始审批流程 ===");
                
                // 启动责任链处理
                junior.handleRequest(request);
            }
            
            scanner.close();
            System.out.println("系统已退出");
        }
    }
    
  2. 命令模式(Command):在对象中封装请求,保存命令并传递给方法以及像任何其他对象一样返回该命令。

    • 优点:① 添加新命令不用修改已有类;② 将操作对象与知道如何完成操作的对象相分离。
    • 适用场景:① 想要通过要执行的动作来参数化对象; ② 在不同的时间指定、排序以及执行请求。
    点击展开代码
    import java.util.*;
    
    // 1. 命令接口
    interface Command {
        void execute();
        void undo();
        String getDescription();
    }
    
    // 2. 接收者类:灯光
    class Light {
        private String location;
        private boolean isOn;
        private int brightness = 100; // 亮度百分比
        
        public Light(String location) {
            this.location = location;
        }
        
        public void on() {
            isOn = true;
            System.out.println(location + " 灯光已打开");
        }
        
        public void off() {
            isOn = false;
            System.out.println(location + " 灯光已关闭");
        }
        
        public void setBrightness(int level) {
            brightness = level;
            System.out.println(location + " 灯光亮度设置为 " + level + "%");
        }
        
        public int getBrightness() {
            return brightness;
        }
        
        public boolean isOn() {
            return isOn;
        }
    }
    
    // 3. 具体命令:灯光开
    class LightOnCommand implements Command {
        private Light light;
        
        public LightOnCommand(Light light) {
            this.light = light;
        }
        
        @Override
        public void execute() {
            light.on();
        }
        
        @Override
        public void undo() {
            light.off();
        }
        
        @Override
        public String getDescription() {
            return "打开 " + light.toString();
        }
    }
    
    // 4. 具体命令:灯光关
    class LightOffCommand implements Command {
        private Light light;
        private int previousBrightness;
        
        public LightOffCommand(Light light) {
            this.light = light;
        }
        
        @Override
        public void execute() {
            previousBrightness = light.getBrightness();
            light.off();
        }
        
        @Override
        public void undo() {
            light.on();
            light.setBrightness(previousBrightness);
        }
        
        @Override
        public String getDescription() {
            return "关闭 " + light.toString();
        }
    }
    
    // 5. 具体命令:设置灯光亮度
    class LightDimCommand implements Command {
        private Light light;
        private int brightness;
        private int previousBrightness;
        private boolean wasOn;
        
        public LightDimCommand(Light light, int brightness) {
            this.light = light;
            this.brightness = brightness;
        }
        
        @Override
        public void execute() {
            wasOn = light.isOn();
            previousBrightness = light.getBrightness();
            
            if (!wasOn) {
                light.on();
            }
            light.setBrightness(brightness);
        }
        
        @Override
        public void undo() {
            if (!wasOn) {
                light.off();
            }
            light.setBrightness(previousBrightness);
        }
        
        @Override
        public String getDescription() {
            return "设置 " + light.toString() + " 亮度为 " + brightness + "%";
        }
    }
    
    // 6. 接收者类:空调
    class AirConditioner {
        private int temperature = 24; // 默认温度
        
        public void setTemperature(int temp) {
            temperature = temp;
            System.out.println("空调温度设置为 " + temp + "°C");
        }
        
        public int getTemperature() {
            return temperature;
        }
    }
    
    // 7. 具体命令:设置空调温度
    class SetTemperatureCommand implements Command {
        private AirConditioner ac;
        private int temperature;
        private int previousTemperature;
        
        public SetTemperatureCommand(AirConditioner ac, int temperature) {
            this.ac = ac;
            this.temperature = temperature;
        }
        
        @Override
        public void execute() {
            previousTemperature = ac.getTemperature();
            ac.setTemperature(temperature);
        }
        
        @Override
        public void undo() {
            ac.setTemperature(previousTemperature);
        }
        
        @Override
        public String getDescription() {
            return "设置空调温度为 " + temperature + "°C";
        }
    }
    
    // 8. 接收者类:电视
    class Television {
        private boolean isOn;
        private int volume = 50; // 默认音量
        private String channel = "新闻";
        
        public void on() {
            isOn = true;
            System.out.println("电视已打开");
        }
        
        public void off() {
            isOn = false;
            System.out.println("电视已关闭");
        }
        
        public void setVolume(int volume) {
            this.volume = volume;
            System.out.println("电视音量设置为 " + volume);
        }
        
        public void setChannel(String channel) {
            this.channel = channel;
            System.out.println("电视频道切换到 " + channel);
        }
        
        public int getVolume() {
            return volume;
        }
        
        public String getChannel() {
            return channel;
        }
        
        public boolean isOn() {
            return isOn;
        }
    }
    
    // 9. 具体命令:电视开
    class TVOnCommand implements Command {
        private Television tv;
        
        public TVOnCommand(Television tv) {
            this.tv = tv;
        }
        
        @Override
        public void execute() {
            tv.on();
        }
        
        @Override
        public void undo() {
            tv.off();
        }
        
        @Override
        public String getDescription() {
            return "打开电视";
        }
    }
    
    // 10. 宏命令:执行多个命令
    class MacroCommand implements Command {
        private List<Command> commands;
        private String name;
        
        public MacroCommand(String name, Command... commands) {
            this.name = name;
            this.commands = Arrays.asList(commands);
        }
        
        @Override
        public void execute() {
            System.out.println("=== 开始执行宏命令: " + name + " ===");
            for (Command command : commands) {
                command.execute();
            }
            System.out.println("=== 宏命令执行完成 ===\n");
        }
        
        @Override
        public void undo() {
            System.out.println("=== 撤销宏命令: " + name + " ===");
            // 反向执行撤销操作
            List<Command> reversed = new ArrayList<>(commands);
            Collections.reverse(reversed);
            for (Command command : reversed) {
                command.undo();
            }
            System.out.println("=== 宏命令撤销完成 ===\n");
        }
        
        @Override
        public String getDescription() {
            return "宏命令: " + name;
        }
    }
    
    // 11. 空命令(避免空检查)
    class NoCommand implements Command {
        @Override
        public void execute() {
            System.out.println("未分配命令");
        }
        
        @Override
        public void undo() {
            System.out.println("无法撤销");
        }
        
        @Override
        public String getDescription() {
            return "空命令";
        }
    }
    
    // 12. 调用者类:遥控器
    class RemoteControl {
        private Command[] onCommands;
        private Command[] offCommands;
        private Command undoCommand;
        private Queue<Command> commandQueue;
        
        public RemoteControl(int slotCount) {
            onCommands = new Command[slotCount];
            offCommands = new Command[slotCount];
            commandQueue = new LinkedList<>();
            undoCommand = new NoCommand();
            
            // 初始化所有插槽为空命令
            Command noCommand = new NoCommand();
            for (int i = 0; i < slotCount; i++) {
                onCommands[i] = noCommand;
                offCommands[i] = noCommand;
            }
        }
        
        // 设置插槽命令
        public void setCommand(int slot, Command onCommand, Command offCommand) {
            onCommands[slot] = onCommand;
            offCommands[slot] = offCommand;
        }
        
        // 按下开按钮
        public void onButtonPressed(int slot) {
            onCommands[slot].execute();
            undoCommand = onCommands[slot];
            commandQueue.add(onCommands[slot]);
        }
        
        // 按下关按钮
        public void offButtonPressed(int slot) {
            offCommands[slot].execute();
            undoCommand = offCommands[slot];
            commandQueue.add(offCommands[slot]);
        }
        
        // 撤销最后操作
        public void undoButtonPressed() {
            undoCommand.undo();
        }
        
        // 执行命令队列
        public void executeCommandQueue() {
            System.out.println("\n=== 执行命令队列 ===");
            while (!commandQueue.isEmpty()) {
                Command command = commandQueue.poll();
                System.out.println("执行: " + command.getDescription());
                command.execute();
            }
            System.out.println("=== 队列执行完成 ===\n");
        }
        
        // 显示遥控器设置
        public void display() {
            System.out.println("\n===== 遥控器设置 =====");
            System.out.println("插槽\t开命令\t\t关命令");
            for (int i = 0; i < onCommands.length; i++) {
                System.out.printf("[%d]\t%-20s\t%s%n", 
                    i, 
                    onCommands[i].getDescription(),
                    offCommands[i].getDescription());
            }
            System.out.println("=====================\n");
        }
    }
    
    // 13. 客户端代码
    public class CommandPatternDemo {
        public static void main(String[] args) {
            // 创建接收者(智能家居设备)
            Light livingRoomLight = new Light("客厅");
            Light kitchenLight = new Light("厨房");
            AirConditioner ac = new AirConditioner();
            Television tv = new Television();
            
            // 创建具体命令
            Command livingRoomLightOn = new LightOnCommand(livingRoomLight);
            Command livingRoomLightOff = new LightOffCommand(livingRoomLight);
            Command kitchenLightOn = new LightOnCommand(kitchenLight);
            Command kitchenLightOff = new LightOffCommand(kitchenLight);
            Command dimKitchenLight = new LightDimCommand(kitchenLight, 30);
            Command setAC = new SetTemperatureCommand(ac, 22);
            Command tvOn = new TVOnCommand(tv);
            
            // 创建宏命令
            Command movieMode = new MacroCommand("电影模式",
                livingRoomLightOff,
                dimKitchenLight,
                setAC,
                tvOn
            );
            
            Command allOff = new MacroCommand("关闭所有设备",
                livingRoomLightOff,
                kitchenLightOff,
                tvOn // TVOnCommand的undo会关闭电视
            );
            
            // 创建遥控器(7个插槽)
            RemoteControl remote = new RemoteControl(7);
            
            // 设置插槽命令
            remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
            remote.setCommand(1, kitchenLightOn, kitchenLightOff);
            remote.setCommand(2, dimKitchenLight, new NoCommand()); // 没有对应的关闭命令
            remote.setCommand(3, setAC, new NoCommand());
            remote.setCommand(4, tvOn, new NoCommand());
            remote.setCommand(5, movieMode, allOff);
            
            // 显示遥控器设置
            remote.display();
            
            // 测试命令
            System.out.println("===== 测试基本命令 =====");
            remote.onButtonPressed(0); // 打开客厅灯
            remote.onButtonPressed(1); // 打开厨房灯
            remote.offButtonPressed(0); // 关闭客厅灯
            remote.offButtonPressed(1); // 关闭厨房灯
            remote.undoButtonPressed(); // 撤销关闭厨房灯
            
            System.out.println("\n===== 测试亮度调节 =====");
            remote.onButtonPressed(2); // 设置厨房灯亮度为30%
            remote.undoButtonPressed(); // 撤销亮度设置
            
            System.out.println("\n===== 测试宏命令 =====");
            remote.onButtonPressed(5); // 执行电影模式
            remote.offButtonPressed(5); // 执行关闭所有设备
            
            System.out.println("\n===== 测试命令队列 =====");
            remote.onButtonPressed(0); // 打开客厅灯
            remote.onButtonPressed(1); // 打开厨房灯
            remote.onButtonPressed(3); // 设置空调温度
            remote.onButtonPressed(4); // 打开电视
            remote.executeCommandQueue(); // 执行队列中的命令
        }
    }
    
  3. 解释器模式(Interpreter):解释定义其语法表示的语言(SQL解析、 符号处理、自定义一些解析引擎)

    点击展开代码
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Stack;
    
    // 抽象表达式接口
    interface Expression {
        boolean interpret(Map<String, Boolean> context);
    }
    
    // 终结符表达式:变量
    class Variable implements Expression {
        private String name;
        
        public Variable(String name) {
            this.name = name;
        }
        
        @Override
        public boolean interpret(Map<String, Boolean> context) {
            Boolean value = context.get(name);
            if (value == null) {
                throw new RuntimeException("未定义的变量: " + name);
            }
            return value;
        }
        
        @Override
        public String toString() {
            return name;
        }
    }
    
    // 终结符表达式:布尔常量
    class Constant implements Expression {
        private boolean value;
        
        public Constant(boolean value) {
            this.value = value;
        }
        
        @Override
        public boolean interpret(Map<String, Boolean> context) {
            return value;
        }
        
        @Override
        public String toString() {
            return Boolean.toString(value);
        }
    }
    
    // 非终结符表达式:逻辑与
    class AndExpression implements Expression {
        private Expression left;
        private Expression right;
        
        public AndExpression(Expression left, Expression right) {
            this.left = left;
            this.right = right;
        }
        
        @Override
        public boolean interpret(Map<String, Boolean> context) {
            return left.interpret(context) && right.interpret(context);
        }
        
        @Override
        public String toString() {
            return "(" + left + " AND " + right + ")";
        }
    }
    
    // 非终结符表达式:逻辑或
    class OrExpression implements Expression {
        private Expression left;
        private Expression right;
        
        public OrExpression(Expression left, Expression right) {
            this.left = left;
            this.right = right;
        }
        
        @Override
        public boolean interpret(Map<String, Boolean> context) {
            return left.interpret(context) || right.interpret(context);
        }
        
        @Override
        public String toString() {
            return "(" + left + " OR " + right + ")";
        }
    }
    
    // 非终结符表达式:逻辑非
    class NotExpression implements Expression {
        private Expression expression;
        
        public NotExpression(Expression expression) {
            this.expression = expression;
        }
        
        @Override
        public boolean interpret(Map<String, Boolean> context) {
            return !expression.interpret(context);
        }
        
        @Override
        public String toString() {
            return "NOT(" + expression + ")";
        }
    }
    
    // 表达式解析器
    class ExpressionParser {
        private static final Map<String, Integer> PRECEDENCE = new HashMap<>();
        
        static {
            PRECEDENCE.put("NOT", 3);
            PRECEDENCE.put("AND", 2);
            PRECEDENCE.put("OR", 1);
        }
        
        public static Expression parse(String expression) {
            // 转换为后缀表达式(逆波兰表示法)
            String[] tokens = expression.split("\\s+");
            Stack<String> operatorStack = new Stack<>();
            Stack<Expression> outputStack = new Stack<>();
            
            for (String token : tokens) {
                token = token.trim();
                if (token.isEmpty()) continue;
                
                if (token.equals("(")) {
                    operatorStack.push(token);
                } else if (token.equals(")")) {
                    while (!operatorStack.isEmpty() && !operatorStack.peek().equals("(")) {
                        processOperator(operatorStack.pop(), outputStack);
                    }
                    operatorStack.pop(); // 弹出左括号
                } else if (PRECEDENCE.containsKey(token.toUpperCase())) {
                    String op = token.toUpperCase();
                    while (!operatorStack.isEmpty() && 
                           PRECEDENCE.getOrDefault(operatorStack.peek(), 0) >= PRECEDENCE.get(op)) {
                        processOperator(operatorStack.pop(), outputStack);
                    }
                    operatorStack.push(op);
                } else {
                    // 处理操作数(变量或常量)
                    if (token.equalsIgnoreCase("true")) {
                        outputStack.push(new Constant(true));
                    } else if (token.equalsIgnoreCase("false")) {
                        outputStack.push(new Constant(false));
                    } else {
                        outputStack.push(new Variable(token));
                    }
                }
            }
            
            while (!operatorStack.isEmpty()) {
                processOperator(operatorStack.pop(), outputStack);
            }
            
            if (outputStack.size() != 1) {
                throw new RuntimeException("无效表达式: " + expression);
            }
            
            return outputStack.pop();
        }
        
        private static void processOperator(String operator, Stack<Expression> outputStack) {
            if (operator.equals("NOT")) {
                if (outputStack.size() < 1) {
                    throw new RuntimeException("无效的NOT表达式");
                }
                Expression expr = outputStack.pop();
                outputStack.push(new NotExpression(expr));
            } else {
                if (outputStack.size() < 2) {
                    throw new RuntimeException("无效的二元表达式");
                }
                Expression right = outputStack.pop();
                Expression left = outputStack.pop();
                
                if (operator.equals("AND")) {
                    outputStack.push(new AndExpression(left, right));
                } else if (operator.equals("OR")) {
                    outputStack.push(new OrExpression(left, right));
                }
            }
        }
    }
    
    // 上下文类:存储变量值
    class Context {
        private Map<String, Boolean> variables = new HashMap<>();
        
        public void setVariable(String name, boolean value) {
            variables.put(name, value);
        }
        
        public boolean evaluate(Expression expression) {
            return expression.interpret(variables);
        }
        
        public void clear() {
            variables.clear();
        }
    }
    
    // 客户端代码
    public class InterpreterPatternDemo {
        public static void main(String[] args) {
            Context context = new Context();
            context.setVariable("A", true);
            context.setVariable("B", false);
            context.setVariable("C", true);
            context.setVariable("D", false);
            
            // 测试简单表达式
            testExpression(context, "A", true);
            testExpression(context, "NOT A", false);
            testExpression(context, "A AND B", false);
            testExpression(context, "A OR B", true);
            
            // 测试复合表达式
            testExpression(context, "A AND (B OR C)", true);
            testExpression(context, "NOT (A AND B)", true);
            testExpression(context, "A AND NOT B", true);
            testExpression(context, "(A OR B) AND (C OR D)", true);
            testExpression(context, "NOT A OR (B AND C)", false);
            
            // 测试带常量的表达式
            testExpression(context, "true AND A", true);
            testExpression(context, "false OR NOT A", false);
            testExpression(context, "A AND true AND NOT false", true);
            
            // 测试复杂表达式
            testExpression(context, "NOT ( (A OR B) AND (C OR D) )", false);
            testExpression(context, "A OR B OR C OR D", true);
            testExpression(context, "A AND B AND C AND D", false);
        }
        
        private static void testExpression(Context context, String exprStr, boolean expected) {
            try {
                Expression expression = ExpressionParser.parse(exprStr);
                boolean result = context.evaluate(expression);
                
                System.out.println("表达式: " + exprStr);
                System.out.println("解析为: " + expression);
                System.out.println("结果: " + result);
                System.out.println("预期: " + expected);
                System.out.println("状态: " + (result == expected ? "✓ 正确" : "✗ 错误"));
                System.out.println();
            } catch (Exception e) {
                System.err.println("解析表达式出错: " + exprStr);
                e.printStackTrace();
            }
        }
    }
    
  4. 迭代器模式(Iterator):提供一种方法术后那些地访问一个聚合对象中地各个元素,而又不暴露该对象地内部表示。

    • 优点:① 支持集合不同遍历; ② 简化集合接口
    • 适用场景:① 在不开放结合对象内部表示地前提下,访问集合对象内容; ② 支持集合对象地多重遍历; ③ 为遍历集合中地不同接口提供了统一的接口
    点击展开代码
    import java.util.*;
    
    // 1. 媒体项接口
    interface MediaItem {
        String getTitle();
        int getYear();
        String getType();
        double getRating();
        void displayInfo();
    }
    
    // 2. 具体媒体项实现
    class Movie implements MediaItem {
        private String title;
        private int year;
        private String director;
        private double rating;
        private int duration; // 分钟
        
        public Movie(String title, int year, String director, double rating, int duration) {
            this.title = title;
            this.year = year;
            this.director = director;
            this.rating = rating;
            this.duration = duration;
        }
        
        @Override
        public String getTitle() { return title; }
        
        @Override
        public int getYear() { return year; }
        
        @Override
        public String getType() { return "电影"; }
        
        @Override
        public double getRating() { return rating; }
        
        public String getDirector() { return director; }
        
        public int getDuration() { return duration; }
        
        @Override
        public void displayInfo() {
            System.out.printf("🎬 %s (%d) | 导演: %s | 评分: %.1f | 时长: %d分钟\n", 
                             title, year, director, rating, duration);
        }
    }
    
    class Song implements MediaItem {
        private String title;
        private int year;
        private String artist;
        private double rating;
        private String album;
        
        public Song(String title, int year, String artist, double rating, String album) {
            this.title = title;
            this.year = year;
            this.artist = artist;
            this.rating = rating;
            this.album = album;
        }
        
        @Override
        public String getTitle() { return title; }
        
        @Override
        public int getYear() { return year; }
        
        @Override
        public String getType() { return "音乐"; }
        
        @Override
        public double getRating() { return rating; }
        
        public String getArtist() { return artist; }
        
        public String getAlbum() { return album; }
        
        @Override
        public void displayInfo() {
            System.out.printf("🎵 %s (%d) | 艺人: %s | 评分: %.1f | 专辑: %s\n", 
                             title, year, artist, rating, album);
        }
    }
    
    class EBook implements MediaItem {
        private String title;
        private int year;
        private String author;
        private double rating;
        private int pages;
        
        public EBook(String title, int year, String author, double rating, int pages) {
            this.title = title;
            this.year = year;
            this.author = author;
            this.rating = rating;
            this.pages = pages;
        }
        
        @Override
        public String getTitle() { return title; }
        
        @Override
        public int getYear() { return year; }
        
        @Override
        public String getType() { return "电子书"; }
        
        @Override
        public double getRating() { return rating; }
        
        public String getAuthor() { return author; }
        
        public int getPages() { return pages; }
        
        @Override
        public void displayInfo() {
            System.out.printf("📚 %s (%d) | 作者: %s | 评分: %.1f | 页数: %d\n", 
                             title, year, author, rating, pages);
        }
    }
    
    // 3. 迭代器接口
    interface MediaIterator {
        boolean hasNext();
        MediaItem next();
        void reset();
    }
    
    // 4. 媒体集合接口
    interface MediaCollection {
        MediaIterator createIterator();
        void addItem(MediaItem item);
        int size();
        List<MediaItem> getAllItems();
    }
    
    // 5. 具体集合实现:媒体库
    class MediaLibrary implements MediaCollection {
        private List<MediaItem> items = new ArrayList<>();
        
        @Override
        public MediaIterator createIterator() {
            return new LibraryIterator(this);
        }
        
        @Override
        public void addItem(MediaItem item) {
            items.add(item);
        }
        
        @Override
        public int size() {
            return items.size();
        }
        
        @Override
        public List<MediaItem> getAllItems() {
            return new ArrayList<>(items);
        }
    }
    
    // 6. 具体迭代器实现:基本迭代器
    class LibraryIterator implements MediaIterator {
        private MediaCollection collection;
        private int position;
        private List<MediaItem> items;
        
        public LibraryIterator(MediaCollection collection) {
            this.collection = collection;
            this.items = collection.getAllItems();
            this.position = 0;
        }
        
        @Override
        public boolean hasNext() {
            return position < items.size();
        }
        
        @Override
        public MediaItem next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return items.get(position++);
        }
        
        @Override
        public void reset() {
            position = 0;
        }
    }
    
    // 7. 具体迭代器实现:按类型过滤
    class TypeFilterIterator implements MediaIterator {
        private MediaIterator iterator;
        private String type;
        private MediaItem nextItem;
        
        public TypeFilterIterator(MediaIterator iterator, String type) {
            this.iterator = iterator;
            this.type = type;
            findNext();
        }
        
        @Override
        public boolean hasNext() {
            return nextItem != null;
        }
        
        @Override
        public MediaItem next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            MediaItem item = nextItem;
            findNext();
            return item;
        }
        
        @Override
        public void reset() {
            iterator.reset();
            findNext();
        }
        
        private void findNext() {
            nextItem = null;
            while (iterator.hasNext()) {
                MediaItem item = iterator.next();
                if (item.getType().equalsIgnoreCase(type)) {
                    nextItem = item;
                    return;
                }
            }
        }
    }
    
    // 8. 具体迭代器实现:按评分过滤
    class RatingFilterIterator implements MediaIterator {
        private MediaIterator iterator;
        private double minRating;
        private MediaItem nextItem;
        
        public RatingFilterIterator(MediaIterator iterator, double minRating) {
            this.iterator = iterator;
            this.minRating = minRating;
            findNext();
        }
        
        @Override
        public boolean hasNext() {
            return nextItem != null;
        }
        
        @Override
        public MediaItem next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            MediaItem item = nextItem;
            findNext();
            return item;
        }
        
        @Override
        public void reset() {
            iterator.reset();
            findNext();
        }
        
        private void findNext() {
            nextItem = null;
            while (iterator.hasNext()) {
                MediaItem item = iterator.next();
                if (item.getRating() >= minRating) {
                    nextItem = item;
                    return;
                }
            }
        }
    }
    
    // 9. 具体迭代器实现:按年份范围过滤
    class YearRangeIterator implements MediaIterator {
        private MediaIterator iterator;
        private int startYear;
        private int endYear;
        private MediaItem nextItem;
        
        public YearRangeIterator(MediaIterator iterator, int startYear, int endYear) {
            this.iterator = iterator;
            this.startYear = startYear;
            this.endYear = endYear;
            findNext();
        }
        
        @Override
        public boolean hasNext() {
            return nextItem != null;
        }
        
        @Override
        public MediaItem next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            MediaItem item = nextItem;
            findNext();
            return item;
        }
        
        @Override
        public void reset() {
            iterator.reset();
            findNext();
        }
        
        private void findNext() {
            nextItem = null;
            while (iterator.hasNext()) {
                MediaItem item = iterator.next();
                if (item.getYear() >= startYear && item.getYear() <= endYear) {
                    nextItem = item;
                    return;
                }
            }
        }
    }
    
    // 10. 组合迭代器:多个迭代器的组合
    class CompositeIterator implements MediaIterator {
        private List<MediaIterator> iterators;
        private int currentIteratorIndex;
        
        public CompositeIterator(MediaIterator... iterators) {
            this.iterators = Arrays.asList(iterators);
            this.currentIteratorIndex = 0;
        }
        
        @Override
        public boolean hasNext() {
            while (currentIteratorIndex < iterators.size()) {
                if (iterators.get(currentIteratorIndex).hasNext()) {
                    return true;
                }
                currentIteratorIndex++;
            }
            return false;
        }
        
        @Override
        public MediaItem next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return iterators.get(currentIteratorIndex).next();
        }
        
        @Override
        public void reset() {
            for (MediaIterator iterator : iterators) {
                iterator.reset();
            }
            currentIteratorIndex = 0;
        }
    }
    
    // 11. 客户端代码
    public class IteratorPatternDemo {
        public static void main(String[] args) {
            // 创建媒体库
            MediaLibrary library = new MediaLibrary();
            
            // 添加电影
            library.addItem(new Movie("肖申克的救赎", 1994, "弗兰克·德拉邦特", 9.3, 142));
            library.addItem(new Movie("阿甘正传", 1994, "罗伯特·泽米吉斯", 9.1, 142));
            library.addItem(new Movie("盗梦空间", 2010, "克里斯托弗·诺兰", 9.0, 148));
            library.addItem(new Movie("寄生虫", 2019, "奉俊昊", 8.6, 132));
            
            // 添加音乐
            library.addItem(new Song("Bohemian Rhapsody", 1975, "Queen", 9.5, "A Night at the Opera"));
            library.addItem(new Song("Imagine", 1971, "John Lennon", 9.2, "Imagine"));
            library.addItem(new Song("Blinding Lights", 2019, "The Weeknd", 8.7, "After Hours"));
            
            // 添加电子书
            library.addItem(new EBook("1984", 1949, "乔治·奥威尔", 9.0, 328));
            library.addItem(new EBook("三体", 2008, "刘慈欣", 9.3, 400));
            library.addItem(new EBook("人类简史", 2011, "尤瓦尔·赫拉利", 8.9, 512));
            
            System.out.println("===== 媒体库中的全部内容 =====");
            displayCollection(library.createIterator());
            
            System.out.println("\n===== 所有电影 =====");
            MediaIterator movieIterator = new TypeFilterIterator(library.createIterator(), "电影");
            displayCollection(movieIterator);
            
            System.out.println("\n===== 所有评分9.0以上的媒体 =====");
            MediaIterator highRatingIterator = new RatingFilterIterator(library.createIterator(), 9.0);
            displayCollection(highRatingIterator);
            
            System.out.println("\n===== 2000年以后的媒体 =====");
            MediaIterator recentIterator = new YearRangeIterator(library.createIterator(), 2000, 2023);
            displayCollection(recentIterator);
            
            System.out.println("\n===== 2010年以后的电影 =====");
            MediaIterator recentMoviesIterator = new TypeFilterIterator(
                new YearRangeIterator(library.createIterator(), 2010, 2023), "电影");
            displayCollection(recentMoviesIterator);
            
            System.out.println("\n===== 组合迭代器:音乐和电子书 =====");
            MediaIterator musicIterator = new TypeFilterIterator(library.createIterator(), "音乐");
            MediaIterator bookIterator = new TypeFilterIterator(library.createIterator(), "电子书");
            MediaIterator compositeIterator = new CompositeIterator(musicIterator, bookIterator);
            displayCollection(compositeIterator);
            
            System.out.println("\n===== 复杂过滤:2000年后评分8.5以上的非电影 =====");
            MediaIterator complexIterator = new CompositeIterator(
                new RatingFilterIterator(
                    new YearRangeIterator(
                        new TypeFilterIterator(library.createIterator(), "音乐"), 
                    2000, 2023), 8.5),
                new RatingFilterIterator(
                    new YearRangeIterator(
                        new TypeFilterIterator(library.createIterator(), "电子书"), 
                    2000, 2023), 8.5)
            );
            displayCollection(complexIterator);
        }
        
        private static void displayCollection(MediaIterator iterator) {
            int count = 0;
            while (iterator.hasNext()) {
                iterator.next().displayInfo();
                count++;
            }
            System.out.println("总计: " + count + " 个项目");
        }
    }
    
  5. 备忘录模式(Memento):保持对象状态的快照,在不向外界公开其内容的情况下返回到它的初始状态。

    • 优点:① 保持封装完整; ② 简化了返回到初始状态所需的操作。
    • 适用场景:① 必须保存对象的快照; ② 适用直接接口来获得状态可能会公开对象的实现细节,破坏对象的封装性。
    点击展开代码
    import java.util.ArrayDeque;
    import java.util.Deque;
    
    // 1. 备忘录类:存储编辑器的状态
    class EditorMemento {
        private final String text;
        private final int cursorPosition;
        private final long timestamp;
    
        public EditorMemento(String text, int cursorPosition) {
            this.text = text;
            this.cursorPosition = cursorPosition;
            this.timestamp = System.currentTimeMillis();
        }
    
        public String getText() {
            return text;
        }
    
        public int getCursorPosition() {
            return cursorPosition;
        }
    
        public long getTimestamp() {
            return timestamp;
        }
    
        @Override
        public String toString() {
            return String.format("快照 [位置: %d, 时间: %tT, 字符数: %d]", 
                                cursorPosition, timestamp, text.length());
        }
    }
    
    // 2. 原发器类:文本编辑器
    class TextEditor {
        private String text;
        private int cursorPosition;
        private final int maxHistory = 20; // 最大历史记录数量
    
        public TextEditor() {
            this.text = "";
            this.cursorPosition = 0;
        }
    
        // 添加文本
        public void addText(String newText) {
            String before = text.substring(0, cursorPosition);
            String after = text.substring(cursorPosition);
            text = before + newText + after;
            cursorPosition += newText.length();
        }
    
        // 删除文本
        public void deleteText(int count) {
            if (cursorPosition - count < 0) count = cursorPosition;
            if (count <= 0) return;
            
            String before = text.substring(0, cursorPosition - count);
            String after = text.substring(cursorPosition);
            text = before + after;
            cursorPosition -= count;
        }
    
        // 移动光标
        public void moveCursor(int position) {
            cursorPosition = Math.max(0, Math.min(position, text.length()));
        }
    
        // 创建备忘录(保存状态)
        public EditorMemento save() {
            return new EditorMemento(text, cursorPosition);
        }
    
        // 从备忘录恢复状态
        public void restore(EditorMemento memento) {
            this.text = memento.getText();
            this.cursorPosition = memento.getCursorPosition();
        }
    
        // 获取当前文本
        public String getText() {
            return text;
        }
    
        // 获取当前光标位置
        public int getCursorPosition() {
            return cursorPosition;
        }
    
        // 显示编辑器状态
        public void display() {
            System.out.println("文本内容: " + text);
            System.out.println("光标位置: " + cursorPosition);
            System.out.println("文本长度: " + text.length());
            System.out.print("光标指示: ");
            for (int i = 0; i < cursorPosition; i++) {
                System.out.print(" ");
            }
            System.out.println("^");
        }
    }
    
    // 3. 管理者类:负责管理备忘录历史
    class HistoryManager {
        private final Deque<EditorMemento> undoStack = new ArrayDeque<>();
        private final Deque<EditorMemento> redoStack = new ArrayDeque<>();
        private final int maxHistory;
    
        public HistoryManager(int maxHistory) {
            this.maxHistory = maxHistory;
        }
    
        // 保存状态
        public void saveState(EditorMemento memento) {
            // 当保存新状态时,清空重做栈
            redoStack.clear();
            
            // 如果历史记录过多,移除最旧的状态
            if (undoStack.size() >= maxHistory) {
                undoStack.removeFirst();
            }
            
            undoStack.push(memento);
        }
    
        // 撤销操作
        public EditorMemento undo() {
            if (undoStack.size() <= 1) {
                System.out.println("无法撤销:已在最初始状态");
                return null;
            }
            
            // 当前状态移到重做栈
            EditorMemento current = undoStack.pop();
            redoStack.push(current);
            
            return undoStack.peek();
        }
    
        // 重做操作
        public EditorMemento redo() {
            if (redoStack.isEmpty()) {
                System.out.println("无法重做:没有可重做的操作");
                return null;
            }
            
            EditorMemento nextState = redoStack.pop();
            undoStack.push(nextState);
            return nextState;
        }
    
        // 显示历史记录
        public void displayHistory() {
            System.out.println("\n===== 历史记录 =====");
            System.out.println("撤销栈 (" + undoStack.size() + "):");
            int index = 0;
            for (EditorMemento memento : undoStack) {
                System.out.printf("%2d. %s%n", index++, memento);
            }
            
            System.out.println("\n重做栈 (" + redoStack.size() + "):");
            index = 0;
            for (EditorMemento memento : redoStack) {
                System.out.printf("%2d. %s%n", index++, memento);
            }
            System.out.println("====================");
        }
    }
    
    // 4. 客户端代码
    public class MementoPatternDemo {
        public static void main(String[] args) {
            // 创建编辑器和历史管理器
            TextEditor editor = new TextEditor();
            HistoryManager history = new HistoryManager(10); // 最多保存10个历史状态
            
            // 初始状态保存
            history.saveState(editor.save());
            
            System.out.println("===== 文本编辑器演示 =====");
            editor.display();
            
            // 编辑操作1
            System.out.println("\n操作: 添加文本 'Hello'");
            editor.addText("Hello");
            history.saveState(editor.save());
            editor.display();
            
            // 编辑操作2
            System.out.println("\n操作: 添加文本 ' World!'");
            editor.addText(" World!");
            history.saveState(editor.save());
            editor.display();
            
            // 编辑操作3
            System.out.println("\n操作: 移动光标到位置 5");
            editor.moveCursor(5);
            history.saveState(editor.save());
            editor.display();
            
            // 编辑操作4
            System.out.println("\n操作: 添加文本 ', beautiful'");
            editor.addText(", beautiful");
            history.saveState(editor.save());
            editor.display();
            
            // 编辑操作5
            System.out.println("\n操作: 删除 7 个字符");
            editor.deleteText(7);
            history.saveState(editor.save());
            editor.display();
            
            // 显示历史记录
            history.displayHistory();
            
            // 撤销操作
            System.out.println("\n操作: 撤销");
            EditorMemento undoState = history.undo();
            if (undoState != null) {
                editor.restore(undoState);
                editor.display();
            }
            
            System.out.println("\n操作: 再次撤销");
            undoState = history.undo();
            if (undoState != null) {
                editor.restore(undoState);
                editor.display();
            }
            
            // 显示历史记录(撤销后)
            history.displayHistory();
            
            // 重做操作
            System.out.println("\n操作: 重做");
            EditorMemento redoState = history.redo();
            if (redoState != null) {
                editor.restore(redoState);
                editor.display();
            }
            
            System.out.println("\n操作: 再次重做");
            redoState = history.redo();
            if (redoState != null) {
                editor.restore(redoState);
                editor.display();
            }
            
            // 尝试多次撤销
            System.out.println("\n===== 尝试多次撤销 =====");
            for (int i = 0; i < 6; i++) {
                System.out.println("\n操作: 撤销 #" + (i + 1));
                undoState = history.undo();
                if (undoState != null) {
                    editor.restore(undoState);
                    editor.display();
                }
            }
            
            // 最终历史记录
            history.displayHistory();
            
            // 尝试多次重做
            System.out.println("\n===== 尝试多次重做 =====");
            for (int i = 0; i < 6; i++) {
                System.out.println("\n操作: 重做 #" + (i + 1));
                redoState = history.redo();
                if (redoState != null) {
                    editor.restore(redoState);
                    editor.display();
                }
            }
        }
    }
    
  6. 观察者模式(Observer):为组件向相关接收方广播消息提供了灵活的方法

    点击展开代码
    import java.util.*;
    import java.util.concurrent.*;
    
    // 1. 主题接口 (Subject)
    interface StockMarket {
        void registerObserver(StockObserver observer);
        void removeObserver(StockObserver observer);
        void notifyObservers();
        void setStockPrice(String symbol, double price);
        Stock getStock(String symbol);
    }
    
    // 2. 观察者接口 (Observer)
    interface StockObserver {
        void update(Stock stock);
        String getName();
    }
    
    // 3. 具体主题:股票交易系统
    class StockExchange implements StockMarket {
        private final Map<String, Stock> stocks = new ConcurrentHashMap<>();
        private final List<StockObserver> observers = new CopyOnWriteArrayList<>();
        private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
        public StockExchange() {
            // 初始化一些股票
            addStock("AAPL", "Apple Inc.", 150.0);
            addStock("GOOGL", "Alphabet Inc.", 120.0);
            addStock("MSFT", "Microsoft Corp.", 250.0);
            addStock("AMZN", "Amazon.com Inc.", 130.0);
            
            // 启动模拟股票价格变化
            startSimulation();
        }
        
        private void addStock(String symbol, String name, double initialPrice) {
            stocks.put(symbol, new Stock(symbol, name, initialPrice));
        }
    
        @Override
        public void registerObserver(StockObserver observer) {
            observers.add(observer);
            System.out.println(observer.getName() + " 已注册");
        }
    
        @Override
        public void removeObserver(StockObserver observer) {
            observers.remove(observer);
            System.out.println(observer.getName() + " 已取消注册");
        }
    
        @Override
        public void notifyObservers() {
            for (StockObserver observer : observers) {
                // 只通知订阅了特定股票的观察者
                if (observer instanceof Investor) {
                    Investor investor = (Investor) observer;
                    for (String symbol : investor.getSubscriptions()) {
                        Stock stock = getStock(symbol);
                        if (stock != null) {
                            observer.update(stock);
                        }
                    }
                } else {
                    // 其他观察者接收所有股票更新
                    for (Stock stock : stocks.values()) {
                        observer.update(stock);
                    }
                }
            }
        }
    
        @Override
        public void setStockPrice(String symbol, double price) {
            Stock stock = stocks.get(symbol);
            if (stock != null) {
                double oldPrice = stock.getPrice();
                stock.setPrice(price);
                System.out.printf("\n📈 %s 价格变化: $%.2f → $%.2f (%.2f%%)%n", 
                                 symbol, oldPrice, price, ((price - oldPrice) / oldPrice * 100));
                notifyObservers();
            }
        }
        
        @Override
        public Stock getStock(String symbol) {
            return stocks.get(symbol);
        }
        
        // 模拟股票价格波动
        private void startSimulation() {
            Random random = new Random();
            scheduler.scheduleAtFixedRate(() -> {
                for (String symbol : stocks.keySet()) {
                    Stock stock = stocks.get(symbol);
                    double currentPrice = stock.getPrice();
                    double change = (random.nextDouble() - 0.5) * 10; // -5到+5之间的随机变化
                    double newPrice = Math.max(1.0, currentPrice + change); // 确保价格不低于1美元
                    setStockPrice(symbol, newPrice);
                    
                    // 随机间隔
                    try {
                        Thread.sleep(500 + random.nextInt(1000));
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }, 1, 1, TimeUnit.SECONDS);
        }
        
        public void shutdown() {
            scheduler.shutdown();
        }
    }
    
    // 4. 股票数据类
    class Stock {
        private final String symbol;
        private final String name;
        private double price;
        private double previousPrice;
        
        public Stock(String symbol, String name, double price) {
            this.symbol = symbol;
            this.name = name;
            this.price = price;
            this.previousPrice = price;
        }
        
        public String getSymbol() {
            return symbol;
        }
        
        public String getName() {
            return name;
        }
        
        public double getPrice() {
            return price;
        }
        
        public void setPrice(double price) {
            this.previousPrice = this.price;
            this.price = price;
        }
        
        public double getPreviousPrice() {
            return previousPrice;
        }
        
        public double getPriceChange() {
            return price - previousPrice;
        }
        
        public double getPriceChangePercent() {
            return (price - previousPrice) / previousPrice * 100;
        }
        
        @Override
        public String toString() {
            return String.format("%s (%s): $%.2f (%.2f%%)", 
                               name, symbol, price, getPriceChangePercent());
        }
    }
    
    // 5. 具体观察者:投资者
    class Investor implements StockObserver {
        private final String name;
        private final double buyThreshold;
        private final double sellThreshold;
        private final Set<String> subscriptions = new HashSet<>();
        
        public Investor(String name, double buyThreshold, double sellThreshold) {
            this.name = name;
            this.buyThreshold = buyThreshold;
            this.sellThreshold = sellThreshold;
        }
        
        public void subscribeTo(String... symbols) {
            Collections.addAll(subscriptions, symbols);
            System.out.println(name + " 订阅了: " + Arrays.toString(symbols));
        }
        
        public void unsubscribeFrom(String symbol) {
            subscriptions.remove(symbol);
            System.out.println(name + " 取消订阅: " + symbol);
        }
        
        public Set<String> getSubscriptions() {
            return Collections.unmodifiableSet(subscriptions);
        }
        
        @Override
        public void update(Stock stock) {
            double changePercent = stock.getPriceChangePercent();
            
            if (changePercent <= buyThreshold) {
                System.out.printf("👨‍💼 %s 买入 %s: 价格下跌 %.2f%% (当前 $%.2f)%n", 
                                 name, stock.getSymbol(), -changePercent, stock.getPrice());
            } else if (changePercent >= sellThreshold) {
                System.out.printf("👨‍💼 %s 卖出 %s: 价格上涨 %.2f%% (当前 $%.2f)%n", 
                                 name, stock.getSymbol(), changePercent, stock.getPrice());
            }
        }
        
        @Override
        public String getName() {
            return "投资者: " + name;
        }
    }
    
    // 6. 具体观察者:交易机器人
    class TradingBot implements StockObserver {
        private final String id;
        private final Map<String, Double> lastPrices = new HashMap<>();
        private final double volatilityThreshold;
        
        public TradingBot(String id, double volatilityThreshold) {
            this.id = id;
            this.volatilityThreshold = volatilityThreshold;
        }
        
        @Override
        public void update(Stock stock) {
            String symbol = stock.getSymbol();
            double currentPrice = stock.getPrice();
            Double lastPrice = lastPrices.get(symbol);
            
            if (lastPrice == null) {
                lastPrices.put(symbol, currentPrice);
                return;
            }
            
            double changePercent = Math.abs((currentPrice - lastPrice) / lastPrice * 100);
            
            if (changePercent > volatilityThreshold) {
                System.out.printf("🤖 %s 检测到 %s 波动: %.2f%% (当前 $%.2f)%n", 
                                 id, symbol, changePercent, currentPrice);
            }
            
            lastPrices.put(symbol, currentPrice);
        }
        
        @Override
        public String getName() {
            return "交易机器人: " + id;
        }
    }
    
    // 7. 具体观察者:新闻机构
    class NewsAgency implements StockObserver {
        private final String name;
        private final Map<String, Double> allTimeHighs = new HashMap<>();
        private final Map<String, Double> allTimeLows = new HashMap<>();
        
        public NewsAgency(String name) {
            this.name = name;
        }
        
        @Override
        public void update(Stock stock) {
            String symbol = stock.getSymbol();
            double price = stock.getPrice();
            
            // 更新历史最高价
            double currentHigh = allTimeHighs.getOrDefault(symbol, Double.MIN_VALUE);
            if (price > currentHigh) {
                allTimeHighs.put(symbol, price);
                System.out.printf("📰 %s 报道: %s 创历史新高 $%.2f%n", 
                                 name, symbol, price);
            }
            
            // 更新历史最低价
            double currentLow = allTimeLows.getOrDefault(symbol, Double.MAX_VALUE);
            if (price < currentLow) {
                allTimeLows.put(symbol, price);
                System.out.printf("📰 %s 报道: %s 创历史新低 $%.2f%n", 
                                 name, symbol, price);
            }
        }
        
        @Override
        public String getName() {
            return "新闻机构: " + name;
        }
    }
    
    // 8. 具体观察者:移动应用通知
    class MobileApp implements StockObserver {
        private final String userName;
        private final Map<String, Double> targetPrices = new HashMap<>();
        
        public MobileApp(String userName) {
            this.userName = userName;
        }
        
        public void setTargetPrice(String symbol, double targetPrice) {
            targetPrices.put(symbol, targetPrice);
            System.out.printf("📱 %s 设置 %s 目标价: $%.2f%n", userName, symbol, targetPrice);
        }
        
        @Override
        public void update(Stock stock) {
            String symbol = stock.getSymbol();
            Double targetPrice = targetPrices.get(symbol);
            
            if (targetPrice != null) {
                double currentPrice = stock.getPrice();
                double difference = Math.abs(currentPrice - targetPrice);
                double threshold = targetPrice * 0.01; // 1% 阈值
                
                if (difference <= threshold) {
                    System.out.printf("📱 %s 收到通知: %s 接近目标价 $%.2f (当前 $%.2f)%n", 
                                     userName, symbol, targetPrice, currentPrice);
                    targetPrices.remove(symbol); // 触发后移除目标
                }
            }
        }
        
        @Override
        public String getName() {
            return "移动应用: " + userName;
        }
    }
    
    // 9. 客户端代码
    public class ObserverPatternDemo {
        public static void main(String[] args) throws InterruptedException {
            // 创建股票交易所
            StockExchange exchange = new StockExchange();
            
            // 创建观察者
            Investor investor1 = new Investor("张三", -2.0, 3.0); // 下跌2%买入,上涨3%卖出
            Investor investor2 = new Investor("李四", -1.5, 2.5);
            
            TradingBot bot1 = new TradingBot("波动监测器", 3.0); // 检测超过3%的波动
            TradingBot bot2 = new TradingBot("高频交易器", 1.5);
            
            NewsAgency agency = new NewsAgency("金融时报");
            
            MobileApp app = new MobileApp("王五");
            
            // 注册观察者
            exchange.registerObserver(investor1);
            exchange.registerObserver(investor2);
            exchange.registerObserver(bot1);
            exchange.registerObserver(bot2);
            exchange.registerObserver(agency);
            exchange.registerObserver(app);
            
            // 投资者订阅股票
            investor1.subscribeTo("AAPL", "MSFT");
            investor2.subscribeTo("GOOGL", "AMZN");
            
            // 设置移动应用目标价
            app.setTargetPrice("AAPL", 155.0);
            app.setTargetPrice("MSFT", 245.0);
            
            // 模拟运行一段时间
            System.out.println("\n===== 模拟开始 =====");
            Thread.sleep(10000); // 运行10秒
            
            // 投资者调整订阅
            System.out.println("\n===== 调整订阅 =====");
            investor1.unsubscribeFrom("MSFT");
            investor1.subscribeTo("AMZN");
            investor2.unsubscribeFrom("AMZN");
            
            // 添加新股票
            System.out.println("\n===== 添加新股票 =====");
            exchange.setStockPrice("TSLA", 300.0); // 添加特斯拉股票
            investor1.subscribeTo("TSLA");
            app.setTargetPrice("TSLA", 310.0);
            
            // 再运行一段时间
            Thread.sleep(10000);
            
            // 移除部分观察者
            System.out.println("\n===== 移除观察者 =====");
            exchange.removeObserver(investor2);
            exchange.removeObserver(bot1);
            
            // 最终运行一段时间
            Thread.sleep(5000);
            
            // 关闭交易所
            exchange.shutdown();
            System.out.println("\n===== 模拟结束 =====");
        }
    }
    
  7. 状态模式(State):允许对象在内部状态变化时变更其行为,并修改其类

    • 优点:定位指定状态的行为,并根据不同状态来划分行为
    • 适用场景:① 对象行文依赖其状态,且对象必须在运行时更具其状态修改行为; ② 操作具有大量以及多部组成的取决于对象状态的条件语句
    点击展开代码
    import java.util.Scanner;
    
    // 1. 状态接口
    interface CoffeeMachineState {
        void insertCoin(CoffeeMachine machine, int amount);
        void selectCoffee(CoffeeMachine machine, String coffeeType);
        void dispenseCoffee(CoffeeMachine machine);
        void refillBeans(CoffeeMachine machine, int beans);
        void refillWater(CoffeeMachine machine, int water);
        void powerOn(CoffeeMachine machine);
        void powerOff(CoffeeMachine machine);
        void cleanMachine(CoffeeMachine machine);
        void displayStatus(CoffeeMachine machine);
        String getStateName();
    }
    
    // 2. 具体状态:关机状态
    class PoweredOffState implements CoffeeMachineState {
        @Override
        public void insertCoin(CoffeeMachine machine, int amount) {
            System.out.println("❌ 请先开机才能投币");
        }
    
        @Override
        public void selectCoffee(CoffeeMachine machine, String coffeeType) {
            System.out.println("❌ 请先开机才能选择咖啡");
        }
    
        @Override
        public void dispenseCoffee(CoffeeMachine machine) {
            System.out.println("❌ 请先开机才能制作咖啡");
        }
    
        @Override
        public void refillBeans(CoffeeMachine machine, int beans) {
            machine.addCoffeeBeans(beans);
            System.out.println("✅ 添加了 " + beans + " 克咖啡豆");
        }
    
        @Override
        public void refillWater(CoffeeMachine machine, int water) {
            machine.addWater(water);
            System.out.println("✅ 添加了 " + water + " 毫升水");
        }
    
        @Override
        public void powerOn(CoffeeMachine machine) {
            System.out.println("🔌 咖啡机已开机");
            machine.setState(new ReadyState());
        }
    
        @Override
        public void powerOff(CoffeeMachine machine) {
            System.out.println("❌ 咖啡机已经关机");
        }
    
        @Override
        public void cleanMachine(CoffeeMachine machine) {
            System.out.println("🧼 深度清洁咖啡机");
            machine.setCleaningCounter(0);
        }
    
        @Override
        public void displayStatus(CoffeeMachine machine) {
            System.out.println("=== 当前状态: 关机 ===");
            System.out.println("咖啡豆: " + machine.getCoffeeBeans() + "g");
            System.out.println("水: " + machine.getWater() + "ml");
            System.out.println("清洁状态: " + (machine.getCleaningCounter() > 5 ? "需要清洁" : "良好"));
        }
    
        @Override
        public String getStateName() {
            return "关机";
        }
    }
    
    // 3. 具体状态:待机状态
    class ReadyState implements CoffeeMachineState {
        @Override
        public void insertCoin(CoffeeMachine machine, int amount) {
            machine.addCredit(amount);
            System.out.println("🪙 已投币: " + amount + " 元,当前余额: " + machine.getCredit() + " 元");
        }
    
        @Override
        public void selectCoffee(CoffeeMachine machine, String coffeeType) {
            Coffee coffee = Coffee.getCoffee(coffeeType);
            if (coffee == null) {
                System.out.println("❌ 无效的咖啡类型: " + coffeeType);
                return;
            }
            
            if (machine.getCredit() < coffee.getPrice()) {
                System.out.println("❌ 余额不足,需要 " + coffee.getPrice() + " 元,当前余额: " + machine.getCredit() + " 元");
                return;
            }
            
            if (machine.getCoffeeBeans() < coffee.getBeansRequired()) {
                System.out.println("❌ 咖啡豆不足,需要 " + coffee.getBeansRequired() + "g,当前: " + machine.getCoffeeBeans() + "g");
                return;
            }
            
            if (machine.getWater() < coffee.getWaterRequired()) {
                System.out.println("❌ 水不足,需要 " + coffee.getWaterRequired() + "ml,当前: " + machine.getWater() + "ml");
                return;
            }
            
            machine.setSelectedCoffee(coffee);
            machine.setState(new BrewingState());
            System.out.println("☕ 已选择 " + coffee.getName() + ",准备制作...");
        }
    
        @Override
        public void dispenseCoffee(CoffeeMachine machine) {
            System.out.println("❌ 请先选择咖啡");
        }
    
        @Override
        public void refillBeans(CoffeeMachine machine, int beans) {
            System.out.println("❌ 请在关机状态下添加咖啡豆");
        }
    
        @Override
        public void refillWater(CoffeeMachine machine, int water) {
            System.out.println("❌ 请在关机状态下添加水");
        }
    
        @Override
        public void powerOn(CoffeeMachine machine) {
            System.out.println("❌ 咖啡机已经开机");
        }
    
        @Override
        public void powerOff(CoffeeMachine machine) {
            System.out.println("🔌 咖啡机已关机");
            machine.setState(new PoweredOffState());
        }
    
        @Override
        public void cleanMachine(CoffeeMachine machine) {
            System.out.println("🧼 快速清洁咖啡机");
            machine.setCleaningCounter(0);
        }
    
        @Override
        public void displayStatus(CoffeeMachine machine) {
            System.out.println("=== 当前状态: 待机 ===");
            System.out.println("余额: " + machine.getCredit() + " 元");
            System.out.println("咖啡豆: " + machine.getCoffeeBeans() + "g");
            System.out.println("水: " + machine.getWater() + "ml");
            System.out.println("清洁状态: " + (machine.getCleaningCounter() > 5 ? "需要清洁" : "良好"));
        }
    
        @Override
        public String getStateName() {
            return "待机";
        }
    }
    
    // 4. 具体状态:制作咖啡状态
    class BrewingState implements CoffeeMachineState {
        @Override
        public void insertCoin(CoffeeMachine machine, int amount) {
            System.out.println("❌ 正在制作咖啡,请稍候...");
        }
    
        @Override
        public void selectCoffee(CoffeeMachine machine, String coffeeType) {
            System.out.println("❌ 正在制作咖啡,请稍候...");
        }
    
        @Override
        public void dispenseCoffee(CoffeeMachine machine) {
            Coffee coffee = machine.getSelectedCoffee();
            if (coffee == null) {
                System.out.println("❌ 未选择咖啡");
                machine.setState(new ReadyState());
                return;
            }
            
            // 扣款
            machine.deductCredit(coffee.getPrice());
            
            // 消耗材料
            machine.useCoffeeBeans(coffee.getBeansRequired());
            machine.useWater(coffee.getWaterRequired());
            
            // 增加清洁计数
            machine.incrementCleaningCounter();
            
            System.out.println("☕ 正在制作 " + coffee.getName() + "...");
            System.out.println("🔧 磨豆中...");
            System.out.println("💧 加热水中...");
            System.out.println("☕ 萃取咖啡中...");
            System.out.println("✅ 您的 " + coffee.getName() + " 已准备好!");
            System.out.println("💰 扣款 " + coffee.getPrice() + " 元,余额: " + machine.getCredit() + " 元");
            
            machine.setSelectedCoffee(null);
            machine.setState(new ReadyState());
        }
    
        @Override
        public void refillBeans(CoffeeMachine machine, int beans) {
            System.out.println("❌ 正在制作咖啡,请稍候...");
        }
    
        @Override
        public void refillWater(CoffeeMachine machine, int water) {
            System.out.println("❌ 正在制作咖啡,请稍候...");
        }
    
        @Override
        public void powerOn(CoffeeMachine machine) {
            System.out.println("❌ 咖啡机已经开机");
        }
    
        @Override
        public void powerOff(CoffeeMachine machine) {
            System.out.println("❌ 正在制作咖啡,无法关机");
        }
    
        @Override
        public void cleanMachine(CoffeeMachine machine) {
            System.out.println("❌ 正在制作咖啡,请稍候...");
        }
    
        @Override
        public void displayStatus(CoffeeMachine machine) {
            System.out.println("=== 当前状态: 制作咖啡 ===");
            Coffee coffee = machine.getSelectedCoffee();
            if (coffee != null) {
                System.out.println("正在制作: " + coffee.getName());
            }
        }
    
        @Override
        public String getStateName() {
            return "制作中";
        }
    }
    
    // 5. 具体状态:维护状态
    class MaintenanceState implements CoffeeMachineState {
        @Override
        public void insertCoin(CoffeeMachine machine, int amount) {
            System.out.println("❌ 维护中,请稍候...");
        }
    
        @Override
        public void selectCoffee(CoffeeMachine machine, String coffeeType) {
            System.out.println("❌ 维护中,请稍候...");
        }
    
        @Override
        public void dispenseCoffee(CoffeeMachine machine) {
            System.out.println("❌ 维护中,请稍候...");
        }
    
        @Override
        public void refillBeans(CoffeeMachine machine, int beans) {
            machine.addCoffeeBeans(beans);
            System.out.println("✅ 添加了 " + beans + " 克咖啡豆");
        }
    
        @Override
        public void refillWater(CoffeeMachine machine, int water) {
            machine.addWater(water);
            System.out.println("✅ 添加了 " + water + " 毫升水");
        }
    
        @Override
        public void powerOn(CoffeeMachine machine) {
            System.out.println("❌ 咖啡机已经开机");
        }
    
        @Override
        public void powerOff(CoffeeMachine machine) {
            System.out.println("🔌 咖啡机已关机");
            machine.setState(new PoweredOffState());
        }
    
        @Override
        public void cleanMachine(CoffeeMachine machine) {
            System.out.println("🧼 深度清洁咖啡机");
            machine.setCleaningCounter(0);
            System.out.println("✅ 清洁完成,咖啡机已恢复待机状态");
            machine.setState(new ReadyState());
        }
    
        @Override
        public void displayStatus(CoffeeMachine machine) {
            System.out.println("=== 当前状态: 维护模式 ===");
            System.out.println("咖啡豆: " + machine.getCoffeeBeans() + "g");
            System.out.println("水: " + machine.getWater() + "ml");
            System.out.println("清洁状态: " + (machine.getCleaningCounter() > 5 ? "需要清洁" : "良好"));
        }
    
        @Override
        public String getStateName() {
            return "维护";
        }
    }
    
    // 6. 咖啡类
    class Coffee {
        private final String name;
        private final int price; // 元
        private final int beansRequired; // 克
        private final int waterRequired; // 毫升
        
        private Coffee(String name, int price, int beansRequired, int waterRequired) {
            this.name = name;
            this.price = price;
            this.beansRequired = beansRequired;
            this.waterRequired = waterRequired;
        }
        
        public String getName() {
            return name;
        }
        
        public int getPrice() {
            return price;
        }
        
        public int getBeansRequired() {
            return beansRequired;
        }
        
        public int getWaterRequired() {
            return waterRequired;
        }
        
        // 咖啡类型枚举
        public static Coffee getCoffee(String type) {
            return switch (type.toLowerCase()) {
                case "espresso" -> new Coffee("浓缩咖啡", 10, 10, 30);
                case "americano" -> new Coffee("美式咖啡", 12, 12, 180);
                case "latte" -> new Coffee("拿铁咖啡", 15, 15, 200);
                case "cappuccino" -> new Coffee("卡布奇诺", 16, 15, 180);
                case "mocha" -> new Coffee("摩卡咖啡", 18, 18, 200);
                default -> null;
            };
        }
    }
    
    // 7. 上下文类:咖啡机
    class CoffeeMachine {
        private CoffeeMachineState state;
        private int credit;
        private int coffeeBeans;
        private int water;
        private Coffee selectedCoffee;
        private int cleaningCounter;
        
        public CoffeeMachine() {
            this.state = new PoweredOffState();
            this.credit = 0;
            this.coffeeBeans = 0;
            this.water = 0;
            this.cleaningCounter = 0;
        }
        
        // 委托方法
        public void insertCoin(int amount) {
            state.insertCoin(this, amount);
        }
        
        public void selectCoffee(String coffeeType) {
            state.selectCoffee(this, coffeeType);
        }
        
        public void dispenseCoffee() {
            state.dispenseCoffee(this);
        }
        
        public void refillBeans(int beans) {
            state.refillBeans(this, beans);
        }
        
        public void refillWater(int water) {
            state.refillWater(this, water);
        }
        
        public void powerOn() {
            state.powerOn(this);
        }
        
        public void powerOff() {
            state.powerOff(this);
        }
        
        public void cleanMachine() {
            state.cleanMachine(this);
        }
        
        public void displayStatus() {
            state.displayStatus(this);
        }
        
        public void enterMaintenance() {
            System.out.println("⚙️ 进入维护模式");
            this.state = new MaintenanceState();
        }
        
        // 状态管理
        public void setState(CoffeeMachineState state) {
            this.state = state;
        }
        
        public CoffeeMachineState getState() {
            return state;
        }
        
        // 余额管理
        public void addCredit(int amount) {
            credit += amount;
        }
        
        public void deductCredit(int amount) {
            credit -= amount;
        }
        
        public int getCredit() {
            return credit;
        }
        
        // 材料管理
        public void addCoffeeBeans(int beans) {
            coffeeBeans += beans;
        }
        
        public void useCoffeeBeans(int beans) {
            coffeeBeans -= beans;
        }
        
        public int getCoffeeBeans() {
            return coffeeBeans;
        }
        
        public void addWater(int water) {
            this.water += water;
        }
        
        public void useWater(int water) {
            this.water -= water;
        }
        
        public int getWater() {
            return water;
        }
        
        // 咖啡选择
        public void setSelectedCoffee(Coffee coffee) {
            selectedCoffee = coffee;
        }
        
        public Coffee getSelectedCoffee() {
            return selectedCoffee;
        }
        
        // 清洁管理
        public void incrementCleaningCounter() {
            cleaningCounter++;
            if (cleaningCounter > 10) {
                System.out.println("⚠️ 咖啡机需要清洁!");
                enterMaintenance();
            }
        }
        
        public void setCleaningCounter(int count) {
            cleaningCounter = count;
        }
        
        public int getCleaningCounter() {
            return cleaningCounter;
        }
    }
    
    // 8. 客户端代码
    public class StatePatternDemo {
        public static void main(String[] args) {
            CoffeeMachine machine = new CoffeeMachine();
            Scanner scanner = new Scanner(System.in);
            
            System.out.println("===== 智能咖啡机控制系统 =====");
            System.out.println("可用命令:");
            System.out.println("on          - 开机");
            System.out.println("off         - 关机");
            System.out.println("coin <金额> - 投币");
            System.out.println("select <类型> - 选择咖啡 (espresso, americano, latte, cappuccino, mocha)");
            System.out.println("make        - 制作咖啡");
            System.out.println("beans <克数> - 添加咖啡豆 (需关机状态)");
            System.out.println("water <毫升> - 添加水 (需关机状态)");
            System.out.println("clean       - 清洁咖啡机");
            System.out.println("status      - 显示状态");
            System.out.println("maintenance - 进入维护模式");
            System.out.println("exit        - 退出系统");
            
            while (true) {
                System.out.print("\n> ");
                String command = scanner.nextLine();
                
                if (command.equalsIgnoreCase("exit")) {
                    break;
                }
                
                String[] parts = command.split(" ", 2);
                String action = parts[0].toLowerCase();
                String param = parts.length > 1 ? parts[1] : "";
                
                try {
                    switch (action) {
                        case "on":
                            machine.powerOn();
                            break;
                        case "off":
                            machine.powerOff();
                            break;
                        case "coin":
                            int amount = Integer.parseInt(param);
                            machine.insertCoin(amount);
                            break;
                        case "select":
                            machine.selectCoffee(param);
                            break;
                        case "make":
                            machine.dispenseCoffee();
                            break;
                        case "beans":
                            int beans = Integer.parseInt(param);
                            machine.refillBeans(beans);
                            break;
                        case "water":
                            int water = Integer.parseInt(param);
                            machine.refillWater(water);
                            break;
                        case "clean":
                            machine.cleanMachine();
                            break;
                        case "status":
                            machine.displayStatus();
                            System.out.println("当前模式: " + machine.getState().getStateName());
                            break;
                        case "maintenance":
                            machine.enterMaintenance();
                            break;
                        default:
                            System.out.println("未知命令: " + command);
                            System.out.println("可用命令: on, off, coin, select, make, beans, water, clean, status, maintenance, exit");
                    }
                } catch (Exception e) {
                    System.out.println("错误: " + e.getMessage());
                }
            }
            
            scanner.close();
            System.out.println("系统已退出");
        }
    }
    
  8. 策略模式(Strategy):定义了一组用来表示可能行为集合的类

    • 优点:① 另一种子类的方法; ② 在类自身中定义行为,减少条件语句; ③ 更容易扩展模型
    • 适用场景:① 许多相关类只是在行为方面有所区别; ② 需要算法的不同变体; ③ 算法适用客户端未知数据
    点击展开代码
    import java.util.*;
    import java.text.SimpleDateFormat;
    
    // 1. 策略接口:支付策略
    interface PaymentStrategy {
        boolean processPayment(double amount);
        String getPaymentMethod();
        String getPaymentDetails();
    }
    
    // 2. 具体策略:信用卡支付
    class CreditCardPayment implements PaymentStrategy {
        private String cardNumber;
        private String cardHolder;
        private String expirationDate;
        private String cvv;
        
        public CreditCardPayment(String cardNumber, String cardHolder, String expirationDate, String cvv) {
            this.cardNumber = cardNumber;
            this.cardHolder = cardHolder;
            this.expirationDate = expirationDate;
            this.cvv = cvv;
        }
        
        @Override
        public boolean processPayment(double amount) {
            // 模拟信用卡处理逻辑
            System.out.println("💳 处理信用卡支付: $" + amount);
            System.out.println("卡号: " + maskCardNumber(cardNumber));
            System.out.println("持卡人: " + cardHolder);
            
            // 简单的验证逻辑
            if (cardNumber.length() != 16 || cvv.length() != 3 || isCardExpired(expirationDate)) {
                System.out.println("❌ 信用卡支付失败: 无效的卡信息");
                return false;
            }
            
            System.out.println("✅ 信用卡支付成功: $" + amount);
            return true;
        }
        
        @Override
        public String getPaymentMethod() {
            return "信用卡";
        }
        
        @Override
        public String getPaymentDetails() {
            return "信用卡尾号: " + cardNumber.substring(12) + ", 持卡人: " + cardHolder;
        }
        
        private String maskCardNumber(String cardNumber) {
            return "****-****-****-" + cardNumber.substring(12);
        }
        
        private boolean isCardExpired(String expirationDate) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("MM/yy");
                Date expDate = sdf.parse(expirationDate);
                return expDate.before(new Date());
            } catch (Exception e) {
                return true;
            }
        }
    }
    
    // 3. 具体策略:PayPal支付
    class PayPalPayment implements PaymentStrategy {
        private String email;
        private String password;
        
        public PayPalPayment(String email, String password) {
            this.email = email;
            this.password = password;
        }
        
        @Override
        public boolean processPayment(double amount) {
            // 模拟PayPal处理逻辑
            System.out.println("📧 处理PayPal支付: $" + amount);
            System.out.println("账户: " + email);
            
            // 简单的验证逻辑
            if (!email.contains("@") || password.length() < 6) {
                System.out.println("❌ PayPal支付失败: 无效的账户信息");
                return false;
            }
            
            System.out.println("✅ PayPal支付成功: $" + amount);
            return true;
        }
        
        @Override
        public String getPaymentMethod() {
            return "PayPal";
        }
        
        @Override
        public String getPaymentDetails() {
            return "PayPal账户: " + email;
        }
    }
    
    // 4. 具体策略:加密货币支付
    class CryptoPayment implements PaymentStrategy {
        private String walletAddress;
        private String currency; // BTC, ETH, etc.
        
        public CryptoPayment(String walletAddress, String currency) {
            this.walletAddress = walletAddress;
            this.currency = currency;
        }
        
        @Override
        public boolean processPayment(double amount) {
            // 模拟加密货币处理逻辑
            System.out.println("🪙 处理加密货币支付: $" + amount + " (" + currency + ")");
            System.out.println("钱包地址: " + walletAddress);
            
            // 简单的验证逻辑
            if (walletAddress.length() < 26 || walletAddress.length() > 35) {
                System.out.println("❌ 加密货币支付失败: 无效的钱包地址");
                return false;
            }
            
            System.out.println("✅ 加密货币支付成功: $" + amount + " (" + currency + ")");
            return true;
        }
        
        @Override
        public String getPaymentMethod() {
            return currency + " 加密货币";
        }
        
        @Override
        public String getPaymentDetails() {
            return currency + " 钱包: " + walletAddress.substring(0, 6) + "..." + walletAddress.substring(walletAddress.length() - 4);
        }
    }
    
    // 5. 具体策略:银行转账
    class BankTransferPayment implements PaymentStrategy {
        private String accountNumber;
        private String routingNumber;
        private String accountHolder;
        
        public BankTransferPayment(String accountNumber, String routingNumber, String accountHolder) {
            this.accountNumber = accountNumber;
            this.routingNumber = routingNumber;
            this.accountHolder = accountHolder;
        }
        
        @Override
        public boolean processPayment(double amount) {
            // 模拟银行转账处理逻辑
            System.out.println("🏦 处理银行转账: $" + amount);
            System.out.println("账户: " + maskAccountNumber(accountNumber));
            System.out.println("账户持有人: " + accountHolder);
            
            // 简单的验证逻辑
            if (accountNumber.length() != 12 || routingNumber.length() != 9) {
                System.out.println("❌ 银行转账失败: 无效的账户信息");
                return false;
            }
            
            System.out.println("✅ 银行转账成功: $" + amount);
            return true;
        }
        
        @Override
        public String getPaymentMethod() {
            return "银行转账";
        }
        
        @Override
        public String getPaymentDetails() {
            return "银行账户尾号: " + accountNumber.substring(8) + ", 持有人: " + accountHolder;
        }
        
        private String maskAccountNumber(String accountNumber) {
            return "****" + accountNumber.substring(4, 8) + "****";
        }
    }
    
    // 6. 具体策略:货到付款
    class CashOnDeliveryPayment implements PaymentStrategy {
        @Override
        public boolean processPayment(double amount) {
            System.out.println("📦 货到付款订单: $" + amount);
            System.out.println("✅ 订单已创建,将在交货时收取现金");
            return true;
        }
        
        @Override
        public String getPaymentMethod() {
            return "货到付款";
        }
        
        @Override
        public String getPaymentDetails() {
            return "支付方式: 货到付款";
        }
    }
    
    // 7. 上下文类:订单处理
    class OrderProcessor {
        private PaymentStrategy paymentStrategy;
        private List<String> items = new ArrayList<>();
        private double totalAmount;
        private String customerName;
        
        public OrderProcessor(String customerName) {
            this.customerName = customerName;
        }
        
        public void addItem(String item, double price) {
            items.add(item);
            totalAmount += price;
            System.out.println("🛒 添加商品: " + item + " - $" + price);
        }
        
        public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
            this.paymentStrategy = paymentStrategy;
            System.out.println("💳 设置支付方式: " + paymentStrategy.getPaymentMethod());
        }
        
        public boolean processOrder() {
            if (paymentStrategy == null) {
                System.out.println("❌ 处理订单失败: 未设置支付方式");
                return false;
            }
            
            if (items.isEmpty()) {
                System.out.println("❌ 处理订单失败: 购物车为空");
                return false;
            }
            
            System.out.println("\n===== 处理订单 =====");
            System.out.println("客户: " + customerName);
            System.out.println("商品数量: " + items.size());
            System.out.println("总金额: $" + totalAmount);
            System.out.println("支付方式: " + paymentStrategy.getPaymentMethod());
            System.out.println("支付详情: " + paymentStrategy.getPaymentDetails());
            
            boolean paymentResult = paymentStrategy.processPayment(totalAmount);
            
            if (paymentResult) {
                System.out.println("🎉 订单处理成功!");
                return true;
            } else {
                System.out.println("❌ 订单处理失败: 支付未完成");
                return false;
            }
        }
        
        public void displayOrderSummary() {
            System.out.println("\n===== 订单摘要 =====");
            System.out.println("客户: " + customerName);
            System.out.println("商品:");
            for (String item : items) {
                System.out.println(" - " + item);
            }
            System.out.println("总金额: $" + totalAmount);
            if (paymentStrategy != null) {
                System.out.println("支付方式: " + paymentStrategy.getPaymentMethod());
            }
            System.out.println("==================");
        }
    }
    
    // 8. 支付策略工厂
    class PaymentStrategyFactory {
        private static final Scanner scanner = new Scanner(System.in);
        
        public static PaymentStrategy createPaymentStrategy(String type) {
            switch (type.toLowerCase()) {
                case "credit":
                    System.out.print("输入信用卡号: ");
                    String cardNumber = scanner.nextLine();
                    System.out.print("输入持卡人姓名: ");
                    String cardHolder = scanner.nextLine();
                    System.out.print("输入有效期 (MM/YY): ");
                    String expDate = scanner.nextLine();
                    System.out.print("输入CVV: ");
                    String cvv = scanner.nextLine();
                    return new CreditCardPayment(cardNumber, cardHolder, expDate, cvv);
                    
                case "paypal":
                    System.out.print("输入PayPal邮箱: ");
                    String email = scanner.nextLine();
                    System.out.print("输入PayPal密码: ");
                    String password = scanner.nextLine();
                    return new PayPalPayment(email, password);
                    
                case "crypto":
                    System.out.print("输入加密货币类型 (BTC, ETH等): ");
                    String currency = scanner.nextLine();
                    System.out.print("输入钱包地址: ");
                    String wallet = scanner.nextLine();
                    return new CryptoPayment(wallet, currency);
                    
                case "bank":
                    System.out.print("输入银行账号: ");
                    String account = scanner.nextLine();
                    System.out.print("输入路由号: ");
                    String routing = scanner.nextLine();
                    System.out.print("输入账户持有人姓名: ");
                    String holder = scanner.nextLine();
                    return new BankTransferPayment(account, routing, holder);
                    
                case "cash":
                    return new CashOnDeliveryPayment();
                    
                default:
                    System.out.println("未知支付方式,默认使用货到付款");
                    return new CashOnDeliveryPayment();
            }
        }
    }
    
    // 9. 客户端代码
    public class StrategyPatternDemo {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            
            System.out.println("===== 欢迎来到电商系统 =====");
            System.out.print("请输入您的姓名: ");
            String customerName = scanner.nextLine();
            
            OrderProcessor order = new OrderProcessor(customerName);
            
            // 添加商品
            order.addItem("iPhone 15 Pro", 999.99);
            order.addItem("Apple Watch Series 9", 399.99);
            order.addItem("AirPods Pro", 249.99);
            
            // 显示订单摘要
            order.displayOrderSummary();
            
            // 支付方式选择
            System.out.println("\n请选择支付方式:");
            System.out.println("1. 信用卡");
            System.out.println("2. PayPal");
            System.out.println("3. 加密货币");
            System.out.println("4. 银行转账");
            System.out.println("5. 货到付款");
            System.out.print("请选择 (1-5): ");
            
            int choice = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符
            
            PaymentStrategy paymentStrategy = null;
            switch (choice) {
                case 1:
                    paymentStrategy = PaymentStrategyFactory.createPaymentStrategy("credit");
                    break;
                case 2:
                    paymentStrategy = PaymentStrategyFactory.createPaymentStrategy("paypal");
                    break;
                case 3:
                    paymentStrategy = PaymentStrategyFactory.createPaymentStrategy("crypto");
                    break;
                case 4:
                    paymentStrategy = PaymentStrategyFactory.createPaymentStrategy("bank");
                    break;
                case 5:
                    paymentStrategy = PaymentStrategyFactory.createPaymentStrategy("cash");
                    break;
                default:
                    System.out.println("无效选择,默认使用货到付款");
                    paymentStrategy = new CashOnDeliveryPayment();
            }
            
            // 设置支付策略
            order.setPaymentStrategy(paymentStrategy);
            
            // 处理订单
            boolean success = order.processOrder();
            
            if (success) {
                System.out.println("感谢您的购物!");
            } else {
                System.out.println("订单处理失败,请重试或选择其他支付方式");
            }
            
            scanner.close();
        }
    }
    
  9. 策略模式 vs. 状态模式

特性 策略模式 状态模式
目的 封装可互换的算法 管理对象状态和状态转换
状态感知 策略类通常无状态 状态类通常有状态
状态转换 客户端控制策略切换 状态类可触发状态转换
关注点 算法实现 状态行为管理
典型应用 支付方式、压缩算法、验证策略 订单状态、工作流、UI状态管理
状态数量 策略数量相对固定 状态通常有多个且相互关联
  1. 模板方法模式(Template Method):提供了在不重写方法的前提写允许子类重载部分方法的方法
    image

    点击展开代码
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    // 1. 抽象类:应用框架基类
    abstract class ApplicationFramework {
        // 模板方法:定义应用生命周期
        public final void runApplication() {
            initialize();
            loadConfiguration();
            authenticateUser();
            if (shouldLoadData()) {
                loadInitialData();
            }
            mainLoop();
            cleanupResources();
            generateReport();
        }
        
        // 具体步骤:初始化框架 - 所有平台通用
        private void initialize() {
            System.out.println("🚀 初始化应用框架...");
            System.out.println("✅ 加载核心库");
            System.out.println("✅ 初始化内存管理器");
            System.out.println("✅ 建立日志系统");
        }
        
        // 抽象步骤:加载配置 - 必须由子类实现
        protected abstract void loadConfiguration();
        
        // 具体步骤:用户认证 - 有默认实现
        protected void authenticateUser() {
            System.out.println("👤 使用默认认证系统");
            System.out.println("✅ 用户认证成功 (访客模式)");
        }
        
        // 钩子方法:是否加载初始数据 - 子类可覆盖
        protected boolean shouldLoadData() {
            return true;
        }
        
        // 抽象步骤:加载初始数据 - 必须由子类实现
        protected abstract void loadInitialData();
        
        // 抽象步骤:主循环 - 必须由子类实现
        protected abstract void mainLoop();
        
        // 具体步骤:清理资源 - 所有平台通用
        private void cleanupResources() {
            System.out.println("🧹 清理资源...");
            System.out.println("✅ 释放内存");
            System.out.println("✅ 关闭文件句柄");
            System.out.println("✅ 断开网络连接");
        }
        
        // 具体步骤:生成报告 - 有默认实现
        protected void generateReport() {
            System.out.println("📊 生成默认报告...");
            System.out.println("✅ 应用运行时间统计");
            System.out.println("✅ 资源使用摘要");
        }
        
        // 工具方法:显示菜单
        protected final void displayMenu(String title, List<String> options) {
            System.out.println("\n=== " + title + " ===");
            for (int i = 0; i < options.size(); i++) {
                System.out.println((i + 1) + ". " + options.get(i));
            }
            System.out.print("请选择: ");
        }
    }
    
    // 2. 具体子类:桌面应用
    class DesktopApplication extends ApplicationFramework {
        private String configPath;
        private boolean userAuthenticated;
        private List<String> data = new ArrayList<>();
        
        public DesktopApplication() {
            this.configPath = "C:/AppConfig/settings.ini";
        }
        
        @Override
        protected void loadConfiguration() {
            System.out.println("🖥️ 加载桌面应用配置...");
            System.out.println("✅ 读取配置文件: " + configPath);
            System.out.println("✅ 初始化桌面UI组件");
            System.out.println("✅ 设置窗口管理器");
        }
        
        @Override
        protected void authenticateUser() {
            System.out.println("👤 桌面用户认证...");
            System.out.println("✅ 使用系统凭证存储");
            System.out.println("✅ 用户认证成功 (管理员权限)");
            userAuthenticated = true;
        }
        
        @Override
        protected void loadInitialData() {
            System.out.println("💾 加载桌面应用数据...");
            System.out.println("✅ 从本地数据库加载数据");
            data.add("文档1.docx");
            data.add("电子表格.xlsx");
            data.add("演示文稿.pptx");
            System.out.println("✅ 已加载 " + data.size() + " 个数据项");
        }
        
        @Override
        protected void mainLoop() {
            Scanner scanner = new Scanner(System.in);
            boolean running = true;
            
            System.out.println("\n=== 桌面应用主菜单 ===");
            
            while (running) {
                List<String> menuOptions = new ArrayList<>();
                menuOptions.add("打开文件");
                menuOptions.add("保存文件");
                menuOptions.add("编辑设置");
                menuOptions.add("打印文档");
                menuOptions.add("退出应用");
                
                displayMenu("桌面应用菜单", menuOptions);
                
                int choice = scanner.nextInt();
                scanner.nextLine(); // 消耗换行符
                
                switch (choice) {
                    case 1:
                        openFile();
                        break;
                    case 2:
                        saveFile();
                        break;
                    case 3:
                        editSettings();
                        break;
                    case 4:
                        printDocument();
                        break;
                    case 5:
                        running = false;
                        break;
                    default:
                        System.out.println("无效选择");
                }
            }
        }
        
        private void openFile() {
            System.out.println("📂 打开文件对话框...");
            System.out.println("✅ 文件已打开");
        }
        
        private void saveFile() {
            System.out.println("💾 保存文件...");
            System.out.println("✅ 文件已保存");
        }
        
        private void editSettings() {
            System.out.println("⚙️ 编辑设置...");
            System.out.println("✅ 设置已更新");
        }
        
        private void printDocument() {
            System.out.println("🖨️ 打印文档...");
            System.out.println("✅ 文档已发送到打印机");
        }
        
        @Override
        protected void generateReport() {
            super.generateReport();
            System.out.println("✅ 桌面特定性能指标");
            System.out.println("✅ 用户界面事件日志");
        }
    }
    
    // 3. 具体子类:移动应用
    class MobileApplication extends ApplicationFramework {
        private boolean offlineMode;
        
        @Override
        protected void loadConfiguration() {
            System.out.println("📱 加载移动应用配置...");
            System.out.println("✅ 读取设备设置");
            System.out.println("✅ 检测屏幕尺寸: 1080x1920");
            System.out.println("✅ 初始化触摸输入系统");
        }
        
        @Override
        protected void authenticateUser() {
            System.out.println("👤 移动用户认证...");
            System.out.println("✅ 使用生物识别认证");
            System.out.println("✅ 用户认证成功 (指纹验证)");
        }
        
        @Override
        protected boolean shouldLoadData() {
            // 在离线模式下不加载数据
            return !offlineMode;
        }
        
        @Override
        protected void loadInitialData() {
            System.out.println("📡 加载移动应用数据...");
            System.out.println("✅ 从云服务同步数据");
            System.out.println("✅ 缓存数据以供离线使用");
            System.out.println("✅ 已加载最新数据");
        }
        
        @Override
        protected void mainLoop() {
            Scanner scanner = new Scanner(System.in);
            boolean running = true;
            
            System.out.println("\n=== 移动应用主界面 ===");
            
            while (running) {
                List<String> menuOptions = new ArrayList<>();
                menuOptions.add("浏览内容");
                menuOptions.add("搜索");
                menuOptions.add("用户资料");
                menuOptions.add("切换离线模式");
                menuOptions.add("退出应用");
                
                displayMenu("移动应用菜单", menuOptions);
                
                int choice = scanner.nextInt();
                scanner.nextLine(); // 消耗换行符
                
                switch (choice) {
                    case 1:
                        browseContent();
                        break;
                    case 2:
                        search();
                        break;
                    case 3:
                        userProfile();
                        break;
                    case 4:
                        toggleOfflineMode();
                        break;
                    case 5:
                        running = false;
                        break;
                    default:
                        System.out.println("无效选择");
                }
            }
        }
        
        private void browseContent() {
            System.out.println("🌐 浏览内容...");
            System.out.println("✅ 显示内容列表");
        }
        
        private void search() {
            System.out.println("🔍 搜索内容...");
            System.out.println("✅ 显示搜索结果");
        }
        
        private void userProfile() {
            System.out.println("👤 显示用户资料...");
            System.out.println("✅ 资料页面已打开");
        }
        
        private void toggleOfflineMode() {
            offlineMode = !offlineMode;
            System.out.println("📶 离线模式: " + (offlineMode ? "启用" : "禁用"));
        }
        
        @Override
        protected void generateReport() {
            System.out.println("📊 生成移动应用报告...");
            System.out.println("✅ 电池使用情况");
            System.out.println("✅ 网络数据统计");
            System.out.println("✅ 用户交互分析");
        }
    }
    
    // 4. 具体子类:Web应用
    class WebApplication extends ApplicationFramework {
        private boolean useCDN;
        
        @Override
        protected void loadConfiguration() {
            System.out.println("🌐 加载Web应用配置...");
            System.out.println("✅ 解析URL参数");
            System.out.println("✅ 检测浏览器: Chrome/最新版");
            System.out.println("✅ 加载前端框架");
        }
        
        @Override
        protected void authenticateUser() {
            System.out.println("👤 Web用户认证...");
            System.out.println("✅ 使用OAuth 2.0认证");
            System.out.println("✅ 用户认证成功 (通过Google账户)");
        }
        
        @Override
        protected void loadInitialData() {
            System.out.println("🔄 加载Web应用数据...");
            System.out.println("✅ 从API端点获取数据");
            System.out.println("✅ 使用" + (useCDN ? "CDN加速" : "直接连接"));
            System.out.println("✅ 数据加载完成");
        }
        
        @Override
        protected void mainLoop() {
            Scanner scanner = new Scanner(System.in);
            boolean running = true;
            
            System.out.println("\n=== Web应用主界面 ===");
            
            while (running) {
                List<String> menuOptions = new ArrayList<>();
                menuOptions.add("导航到页面");
                menuOptions.add("提交表单");
                menuOptions.add("与API交互");
                menuOptions.add("切换CDN");
                menuOptions.add("关闭应用");
                
                displayMenu("Web应用菜单", menuOptions);
                
                int choice = scanner.nextInt();
                scanner.nextLine(); // 消耗换行符
                
                switch (choice) {
                    case 1:
                        navigate();
                        break;
                    case 2:
                        submitForm();
                        break;
                    case 3:
                        apiInteraction();
                        break;
                    case 4:
                        toggleCDN();
                        break;
                    case 5:
                        running = false;
                        break;
                    default:
                        System.out.println("无效选择");
                }
            }
        }
        
        private void navigate() {
            System.out.println("🧭 导航到页面...");
            System.out.println("✅ 页面已加载");
        }
        
        private void submitForm() {
            System.out.println("📝 提交表单...");
            System.out.println("✅ 表单数据已发送");
        }
        
        private void apiInteraction() {
            System.out.println("🔌 与API交互...");
            System.out.println("✅ API请求完成");
        }
        
        private void toggleCDN() {
            useCDN = !useCDN;
            System.out.println("📶 CDN加速: " + (useCDN ? "启用" : "禁用"));
        }
        
        @Override
        protected void cleanupResources() {
            super.cleanupResources();
            System.out.println("✅ 清理浏览器缓存");
            System.out.println("✅ 关闭WebSocket连接");
        }
        
        @Override
        protected void generateReport() {
            System.out.println("📊 生成Web应用报告...");
            System.out.println("✅ 页面加载时间分析");
            System.out.println("✅ HTTP请求统计");
            System.out.println("✅ 用户会话分析");
        }
    }
    
    // 5. 客户端代码
    public class TemplateMethodPatternDemo {
        public static void main(String[] args) {
            System.out.println("===== 桌面应用演示 =====");
            ApplicationFramework desktopApp = new DesktopApplication();
            desktopApp.runApplication();
            
            System.out.println("\n===== 移动应用演示 =====");
            ApplicationFramework mobileApp = new MobileApplication();
            mobileApp.runApplication();
            
            System.out.println("\n===== Web应用演示 =====");
            ApplicationFramework webApp = new WebApplication();
            webApp.runApplication();
            
            System.out.println("\n===== 所有应用运行完成 =====");
        }
    }
    
  2. 访问者模式(Visitor):提供了一种方便的、可维护的方法来表示在对象结构元素上进行的操作。该模式允许在不改变操作元素的类的前提下定义一个操作(结构稳定,但是算法变化频繁的场景)。

    • 优点:① 容易添加新操作; ② 集中相关操作并排除不相关操作
    • 适用场景:① 定义对象结构的类很少被修改,但想要在此结构上定义新的操作; ② 对象结构包含许多具有不同接口的对象类,并且想要对这些依赖于具体类的对象进行操作。
    点击展开代码
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Stack;
    
    // 1. 元素接口:AST节点
    interface ASTNode {
        void accept(ASTVisitor visitor);
        String getNodeType();
    }
    
    // 2. 具体元素:变量声明节点
    class VariableDeclarationNode implements ASTNode {
        private String type;
        private String name;
        private Object initialValue;
        
        public VariableDeclarationNode(String type, String name, Object initialValue) {
            this.type = type;
            this.name = name;
            this.initialValue = initialValue;
        }
        
        public String getType() {
            return type;
        }
        
        public String getName() {
            return name;
        }
        
        public Object getInitialValue() {
            return initialValue;
        }
        
        @Override
        public void accept(ASTVisitor visitor) {
            visitor.visit(this);
        }
        
        @Override
        public String getNodeType() {
            return "VariableDeclaration";
        }
    }
    
    // 3. 具体元素:函数调用节点
    class FunctionCallNode implements ASTNode {
        private String functionName;
        private List<ASTNode> arguments;
        
        public FunctionCallNode(String functionName) {
            this.functionName = functionName;
            this.arguments = new ArrayList<>();
        }
        
        public void addArgument(ASTNode argument) {
            arguments.add(argument);
        }
        
        public String getFunctionName() {
            return functionName;
        }
        
        public List<ASTNode> getArguments() {
            return arguments;
        }
        
        @Override
        public void accept(ASTVisitor visitor) {
            visitor.visit(this);
        }
        
        @Override
        public String getNodeType() {
            return "FunctionCall";
        }
    }
    
    // 4. 具体元素:二元操作节点
    class BinaryOperationNode implements ASTNode {
        private String operator;
        private ASTNode leftOperand;
        private ASTNode rightOperand;
        
        public BinaryOperationNode(String operator, ASTNode leftOperand, ASTNode rightOperand) {
            this.operator = operator;
            this.leftOperand = leftOperand;
            this.rightOperand = rightOperand;
        }
        
        public String getOperator() {
            return operator;
        }
        
        public ASTNode getLeftOperand() {
            return leftOperand;
        }
        
        public ASTNode getRightOperand() {
            return rightOperand;
        }
        
        @Override
        public void accept(ASTVisitor visitor) {
            visitor.visit(this);
        }
        
        @Override
        public String getNodeType() {
            return "BinaryOperation";
        }
    }
    
    // 5. 具体元素:条件语句节点
    class IfStatementNode implements ASTNode {
        private ASTNode condition;
        private List<ASTNode> thenBlock;
        private List<ASTNode> elseBlock;
        
        public IfStatementNode(ASTNode condition) {
            this.condition = condition;
            this.thenBlock = new ArrayList<>();
            this.elseBlock = new ArrayList<>();
        }
        
        public void addThenStatement(ASTNode statement) {
            thenBlock.add(statement);
        }
        
        public void addElseStatement(ASTNode statement) {
            elseBlock.add(statement);
        }
        
        public ASTNode getCondition() {
            return condition;
        }
        
        public List<ASTNode> getThenBlock() {
            return thenBlock;
        }
        
        public List<ASTNode> getElseBlock() {
            return elseBlock;
        }
        
        @Override
        public void accept(ASTVisitor visitor) {
            visitor.visit(this);
        }
        
        @Override
        public String getNodeType() {
            return "IfStatement";
        }
    }
    
    // 6. 具体元素:循环语句节点
    class WhileLoopNode implements ASTNode {
        private ASTNode condition;
        private List<ASTNode> body;
        
        public WhileLoopNode(ASTNode condition) {
            this.condition = condition;
            this.body = new ArrayList<>();
        }
        
        public void addBodyStatement(ASTNode statement) {
            body.add(statement);
        }
        
        public ASTNode getCondition() {
            return condition;
        }
        
        public List<ASTNode> getBody() {
            return body;
        }
        
        @Override
        public void accept(ASTVisitor visitor) {
            visitor.visit(this);
        }
        
        @Override
        public String getNodeType() {
            return "WhileLoop";
        }
    }
    
    // 7. 访问者接口
    interface ASTVisitor {
        void visit(VariableDeclarationNode node);
        void visit(FunctionCallNode node);
        void visit(BinaryOperationNode node);
        void visit(IfStatementNode node);
        void visit(WhileLoopNode node);
    }
    
    // 8. 具体访问者:类型检查器
    class TypeCheckerVisitor implements ASTVisitor {
        private SymbolTable symbolTable = new SymbolTable();
        private int errorCount = 0;
        
        @Override
        public void visit(VariableDeclarationNode node) {
            String varName = node.getName();
            String varType = node.getType();
            Object initValue = node.getInitialValue();
            
            // 检查变量是否已声明
            if (symbolTable.isDeclared(varName)) {
                System.out.println("❌ 类型错误: 变量 '" + varName + "' 已声明");
                errorCount++;
                return;
            }
            
            // 检查初始值类型
            if (initValue != null) {
                String initType = getValueType(initValue);
                if (!isCompatible(varType, initType)) {
                    System.out.println("❌ 类型错误: 变量 '" + varName + "' 类型为 " + varType + 
                                      ",但初始值类型为 " + initType);
                    errorCount++;
                }
            }
            
            // 添加到符号表
            symbolTable.declareVariable(varName, varType);
            System.out.println("✅ 类型检查: 声明变量 '" + varName + "' 类型为 " + varType);
        }
        
        @Override
        public void visit(FunctionCallNode node) {
            String funcName = node.getFunctionName();
            List<ASTNode> args = node.getArguments();
            
            // 检查函数是否定义
            if (!symbolTable.isFunctionDefined(funcName)) {
                System.out.println("❌ 类型错误: 未定义的函数 '" + funcName + "'");
                errorCount++;
                return;
            }
            
            // 检查参数数量和类型
            FunctionInfo funcInfo = symbolTable.getFunctionInfo(funcName);
            if (funcInfo.paramTypes.size() != args.size()) {
                System.out.println("❌ 类型错误: 函数 '" + funcName + "' 期望 " + funcInfo.paramTypes.size() + 
                                  " 个参数,但提供了 " + args.size());
                errorCount++;
                return;
            }
            
            // 检查每个参数类型
            for (int i = 0; i < args.size(); i++) {
                ASTNode arg = args.get(i);
                // 实际参数类型需要从表达式推断,这里简化处理
                String expectedType = funcInfo.paramTypes.get(i);
                String actualType = inferType(arg);
                
                if (!isCompatible(expectedType, actualType)) {
                    System.out.println("❌ 类型错误: 函数 '" + funcName + "' 参数 " + (i+1) + 
                                      " 期望类型 " + expectedType + ",但实际类型为 " + actualType);
                    errorCount++;
                }
            }
            
            System.out.println("✅ 类型检查: 函数调用 '" + funcName + "' 参数匹配");
        }
        
        @Override
        public void visit(BinaryOperationNode node) {
            String operator = node.getOperator();
            ASTNode left = node.getLeftOperand();
            ASTNode right = node.getRightOperand();
            
            String leftType = inferType(left);
            String rightType = inferType(right);
            
            // 检查操作数类型兼容性
            if (!isCompatible(leftType, rightType)) {
                System.out.println("❌ 类型错误: 操作数类型不兼容: " + leftType + " 和 " + rightType);
                errorCount++;
                return;
            }
            
            // 检查操作符对类型的支持
            if (!isOperatorSupported(operator, leftType)) {
                System.out.println("❌ 类型错误: 操作符 '" + operator + "' 不支持类型 " + leftType);
                errorCount++;
                return;
            }
            
            System.out.println("✅ 类型检查: 二元操作 '" + operator + "' 类型兼容");
        }
        
        @Override
        public void visit(IfStatementNode node) {
            // 检查条件表达式类型
            String condType = inferType(node.getCondition());
            if (!"boolean".equals(condType)) {
                System.out.println("❌ 类型错误: if语句条件必须是boolean类型,实际为 " + condType);
                errorCount++;
            }
            
            // 检查then块
            enterScope();
            for (ASTNode stmt : node.getThenBlock()) {
                stmt.accept(this);
            }
            exitScope();
            
            // 检查else块
            if (!node.getElseBlock().isEmpty()) {
                enterScope();
                for (ASTNode stmt : node.getElseBlock()) {
                    stmt.accept(this);
                }
                exitScope();
            }
        }
        
        @Override
        public void visit(WhileLoopNode node) {
            // 检查条件表达式类型
            String condType = inferType(node.getCondition());
            if (!"boolean".equals(condType)) {
                System.out.println("❌ 类型错误: while循环条件必须是boolean类型,实际为 " + condType);
                errorCount++;
            }
            
            // 检查循环体
            enterScope();
            for (ASTNode stmt : node.getBody()) {
                stmt.accept(this);
            }
            exitScope();
        }
        
        // 辅助方法
        private String inferType(ASTNode node) {
            // 简化实现:实际编译器需要更复杂的类型推断
            if (node instanceof VariableDeclarationNode) {
                return ((VariableDeclarationNode) node).getType();
            }
            if (node instanceof BinaryOperationNode) {
                return "int"; // 假设二元操作总是返回int
            }
            return "unknown";
        }
        
        private boolean isCompatible(String type1, String type2) {
            // 简化实现
            return type1.equals(type2);
        }
        
        private boolean isOperatorSupported(String operator, String type) {
            // 简化实现
            return true;
        }
        
        private String getValueType(Object value) {
            if (value instanceof Integer) return "int";
            if (value instanceof Double) return "double";
            if (value instanceof Boolean) return "boolean";
            if (value instanceof String) return "string";
            return "unknown";
        }
        
        private void enterScope() {
            symbolTable.enterScope();
        }
        
        private void exitScope() {
            symbolTable.exitScope();
        }
        
        public int getErrorCount() {
            return errorCount;
        }
    }
    
    // 9. 具体访问者:代码生成器
    class CodeGeneratorVisitor implements ASTVisitor {
        private StringBuilder code = new StringBuilder();
        private int indentLevel = 0;
        
        @Override
        public void visit(VariableDeclarationNode node) {
            String type = node.getType();
            String name = node.getName();
            Object initValue = node.getInitialValue();
            
            appendIndent();
            code.append(type).append(" ").append(name);
            
            if (initValue != null) {
                code.append(" = ");
                if ("string".equals(type)) {
                    code.append("\"").append(initValue).append("\"");
                } else {
                    code.append(initValue);
                }
            }
            
            code.append(";");
            code.append("\n");
        }
        
        @Override
        public void visit(FunctionCallNode node) {
            appendIndent();
            code.append(node.getFunctionName()).append("(");
            
            List<ASTNode> args = node.getArguments();
            for (int i = 0; i < args.size(); i++) {
                // 简化处理:实际需要递归生成参数代码
                if (args.get(i) instanceof VariableDeclarationNode) {
                    code.append(((VariableDeclarationNode) args.get(i)).getName());
                } else {
                    code.append("expr");
                }
                
                if (i < args.size() - 1) {
                    code.append(", ");
                }
            }
            
            code.append(");\n");
        }
        
        @Override
        public void visit(BinaryOperationNode node) {
            // 简化处理:实际需要递归生成操作数代码
            appendIndent();
            code.append("expr = expr ")
                .append(node.getOperator())
                .append(" expr;\n");
        }
        
        @Override
        public void visit(IfStatementNode node) {
            appendIndent();
            code.append("if (");
            
            // 生成条件表达式代码
            if (node.getCondition() instanceof VariableDeclarationNode) {
                code.append(((VariableDeclarationNode) node.getCondition()).getName());
            } else {
                code.append("condition");
            }
            
            code.append(") {\n");
            
            // 生成then块
            indentLevel++;
            for (ASTNode stmt : node.getThenBlock()) {
                stmt.accept(this);
            }
            indentLevel--;
            
            // 生成else块
            if (!node.getElseBlock().isEmpty()) {
                appendIndent();
                code.append("} else {\n");
                indentLevel++;
                for (ASTNode stmt : node.getElseBlock()) {
                    stmt.accept(this);
                }
                indentLevel--;
            }
            
            appendIndent();
            code.append("}\n");
        }
        
        @Override
        public void visit(WhileLoopNode node) {
            appendIndent();
            code.append("while (");
            
            // 生成条件表达式代码
            if (node.getCondition() instanceof VariableDeclarationNode) {
                code.append(((VariableDeclarationNode) node.getCondition()).getName());
            } else {
                code.append("condition");
            }
            
            code.append(") {\n");
            
            // 生成循环体
            indentLevel++;
            for (ASTNode stmt : node.getBody()) {
                stmt.accept(this);
            }
            indentLevel--;
            
            appendIndent();
            code.append("}\n");
        }
        
        private void appendIndent() {
            for (int i = 0; i < indentLevel; i++) {
                code.append("    ");
            }
        }
        
        public String getGeneratedCode() {
            return code.toString();
        }
    }
    
    // 10. 具体访问者:代码优化器
    class CodeOptimizerVisitor implements ASTVisitor {
        private int optimizations = 0;
        
        @Override
        public void visit(VariableDeclarationNode node) {
            // 优化: 移除未使用的变量 (简化实现)
            System.out.println("🔧 检查变量声明优化: " + node.getName());
        }
        
        @Override
        public void visit(FunctionCallNode node) {
            // 优化: 内联小函数 (简化实现)
            System.out.println("🔧 检查函数调用优化: " + node.getFunctionName());
        }
        
        @Override
        public void visit(BinaryOperationNode node) {
            // 优化: 常量折叠
            if (isConstant(node.getLeftOperand()) && isConstant(node.getRightOperand())) {
                System.out.println("✨ 优化: 常量表达式折叠");
                optimizations++;
            }
        }
        
        @Override
        public void visit(IfStatementNode node) {
            // 优化: 死代码消除
            if (isConstantCondition(node.getCondition())) {
                System.out.println("✨ 优化: 条件语句优化");
                optimizations++;
            }
            
            // 检查then块
            for (ASTNode stmt : node.getThenBlock()) {
                stmt.accept(this);
            }
            
            // 检查else块
            for (ASTNode stmt : node.getElseBlock()) {
                stmt.accept(this);
            }
        }
        
        @Override
        public void visit(WhileLoopNode node) {
            // 优化: 循环展开
            if (isSmallLoop(node)) {
                System.out.println("✨ 优化: 小循环展开");
                optimizations++;
            }
            
            // 检查循环体
            for (ASTNode stmt : node.getBody()) {
                stmt.accept(this);
            }
        }
        
        private boolean isConstant(ASTNode node) {
            // 简化实现
            return node instanceof VariableDeclarationNode && 
                   ((VariableDeclarationNode) node).getInitialValue() != null;
        }
        
        private boolean isConstantCondition(ASTNode node) {
            // 简化实现
            return false;
        }
        
        private boolean isSmallLoop(WhileLoopNode node) {
            // 简化实现
            return node.getBody().size() < 3;
        }
        
        public int getOptimizationCount() {
            return optimizations;
        }
    }
    
    // 11. 符号表(支持作用域)
    class SymbolTable {
        private Stack<Scope> scopeStack = new Stack<>();
        
        public SymbolTable() {
            enterScope(); // 全局作用域
            
            // 预定义一些函数
            declareFunction("print", "void", List.of("string"));
            declareFunction("max", "int", List.of("int", "int"));
        }
        
        public void enterScope() {
            scopeStack.push(new Scope());
        }
        
        public void exitScope() {
            if (scopeStack.size() > 1) {
                scopeStack.pop();
            }
        }
        
        public void declareVariable(String name, String type) {
            scopeStack.peek().variables.put(name, type);
        }
        
        public boolean isDeclared(String name) {
            for (int i = scopeStack.size() - 1; i >= 0; i--) {
                if (scopeStack.get(i).variables.containsKey(name)) {
                    return true;
                }
            }
            return false;
        }
        
        public void declareFunction(String name, String returnType, List<String> paramTypes) {
            FunctionInfo info = new FunctionInfo(returnType, paramTypes);
            scopeStack.get(0).functions.put(name, info);
        }
        
        public boolean isFunctionDefined(String name) {
            return scopeStack.get(0).functions.containsKey(name);
        }
        
        public FunctionInfo getFunctionInfo(String name) {
            return scopeStack.get(0).functions.get(name);
        }
        
        private static class Scope {
            public java.util.Map<String, String> variables = new java.util.HashMap<>();
            public java.util.Map<String, FunctionInfo> functions = new java.util.HashMap<>();
        }
        
        public static class FunctionInfo {
            public String returnType;
            public List<String> paramTypes;
            
            public FunctionInfo(String returnType, List<String> paramTypes) {
                this.returnType = returnType;
                this.paramTypes = paramTypes;
            }
        }
    }
    
    // 12. AST遍历工具
    class ASTTraverser {
        public static void traverse(List<ASTNode> nodes, ASTVisitor visitor) {
            for (ASTNode node : nodes) {
                node.accept(visitor);
            }
        }
    }
    
    // 13. 客户端代码
    public class VisitorPatternDemo {
        public static void main(String[] args) {
            // 创建AST(抽象语法树)
            List<ASTNode> ast = new ArrayList<>();
            
            // 添加变量声明
            ast.add(new VariableDeclarationNode("int", "counter", 0));
            ast.add(new VariableDeclarationNode("string", "message", "Hello, Visitor Pattern!"));
            
            // 添加函数调用
            FunctionCallNode printCall = new FunctionCallNode("print");
            printCall.addArgument(new VariableDeclarationNode("string", "dummy", null));
            ast.add(printCall);
            
            // 添加二元操作
            BinaryOperationNode addOp = new BinaryOperationNode(
                "+", 
                new VariableDeclarationNode("int", "a", 5),
                new VariableDeclarationNode("int", "b", 10)
            );
            ast.add(addOp);
            
            // 添加条件语句
            IfStatementNode ifStmt = new IfStatementNode(
                new BinaryOperationNode(
                    ">", 
                    new VariableDeclarationNode("int", "x", 10),
                    new VariableDeclarationNode("int", "y", 5)
                )
            );
            ifStmt.addThenStatement(new VariableDeclarationNode("int", "result", 1));
            ifStmt.addElseStatement(new VariableDeclarationNode("int", "result", 0));
            ast.add(ifStmt);
            
            // 添加循环
            WhileLoopNode whileLoop = new WhileLoopNode(
                new BinaryOperationNode(
                    "<", 
                    new VariableDeclarationNode("int", "i", 0),
                    new VariableDeclarationNode("int", "max", 10)
                )
            );
            whileLoop.addBodyStatement(new FunctionCallNode("print"));
            ast.add(whileLoop);
            
            // 创建访问者
            TypeCheckerVisitor typeChecker = new TypeCheckerVisitor();
            CodeGeneratorVisitor codeGenerator = new CodeGeneratorVisitor();
            CodeOptimizerVisitor optimizer = new CodeOptimizerVisitor();
            
            System.out.println("===== 开始类型检查 =====");
            ASTTraverser.traverse(ast, typeChecker);
            System.out.println("类型检查完成,发现 " + typeChecker.getErrorCount() + " 个错误\n");
            
            System.out.println("===== 生成目标代码 =====");
            ASTTraverser.traverse(ast, codeGenerator);
            System.out.println("生成的代码:\n");
            System.out.println(codeGenerator.getGeneratedCode());
            
            System.out.println("===== 代码优化 =====");
            ASTTraverser.traverse(ast, optimizer);
            System.out.println("优化完成,应用了 " + optimizer.getOptimizationCount() + " 个优化\n");
        }
    }
    
  3. 中介者模式(Mediater):通过引入一个能够管理对象间消息分布的对象,简化了系统对象的通信

    • 优点:① 去除对象间的影响; ② 简化对象间的协议; ③ 集中化了控制。
    • 适用场景:① 对象集合需要以一个定义规范但负责的方式进行通信; ② 想要在不使用子类的情况下自定义分布在几个对象之间的行为。
    点击展开代码
    import java.util.ArrayList;
    import java.util.List;
    
    // 1. 中介者接口 (定义通信协议)
    interface ChatMediator {
        void sendMessage(String message, User user);
        void addUser(User user);
    }
    
    // 2. 具体中介者 (聊天服务器实现)
    class ChatServer implements ChatMediator {
        private List<User> users;
        
        public ChatServer() {
            this.users = new ArrayList<>();
        }
        
        @Override
        public void sendMessage(String message, User sender) {
            // 广播消息给所有其他用户
            for (User user : users) {
                if (user != sender) {
                    user.receive(message);
                }
            }
        }
        
        @Override
        public void addUser(User user) {
            this.users.add(user);
        }
    }
    
    // 3. 同事类抽象 (用户接口)
    abstract class User {
        protected ChatMediator mediator;
        protected String name;
        
        public User(ChatMediator mediator, String name) {
            this.mediator = mediator;
            this.name = name;
        }
        
        public abstract void send(String message);
        public abstract void receive(String message);
    }
    
    // 4. 具体同事类 (聊天用户)
    class ChatUser extends User {
        public ChatUser(ChatMediator mediator, String name) {
            super(mediator, name);
        }
        
        @Override
        public void send(String message) {
            System.out.println(this.name + " 发送: " + message);
            mediator.sendMessage(message, this);
        }
        
        @Override
        public void receive(String message) {
            System.out.println(this.name + " 收到: " + message);
        }
    }
    
    // 5. 客户端使用
    public class MediatorPatternDemo {
        public static void main(String[] args) {
            // 创建中介者 (聊天服务器)
            ChatMediator server = new ChatServer();
            
            // 创建用户并注册到中介者
            User alice = new ChatUser(server, "Alice");
            User bob = new ChatUser(server, "Bob");
            User charlie = new ChatUser(server, "Charlie");
            
            server.addUser(alice);
            server.addUser(bob);
            server.addUser(charlie);
            
            // 用户间通过中介者通信
        alice.send("大家好!");
        System.out.println();
        
        bob.send("今天天气不错!");
        System.out.println();
        
        charlie.send("有人想打游戏吗?");
    }
    

可扩展标记语言

2~8分

XML概述

  1. 定义:可扩展标记语言(XML)是标准通用标记语言(SGML)的一个子集;可以用XML来开发一种标记语言,它的元素和属性多是为专门行业和产业而定义的。
  2. 特点和功能
    image
  3. 概述
    image

XML命名空间

  1. 命名空间
    1. XML命名空间是解决读个义性和名义冲突问题的方案
    2. 命名空间是一组具有结构的名称的集合
  2. 定义和声明命名空间
    1. 命名空间推荐标准为我们提供了xmlns属性,属性值为URI
    2. 命名空间前缀经常被提及为前缀,而名称本身是基本名。
    3. 默认的命名空间(没有声明别名的,形式为xmlns="..."):在声明作用域里,所有没有经命名空间前缀修饰的名称被假定属于默认的命名空间

DTD

  1. DTD:文档类型定义

  2. 内容:① 元素声明; ② 实体声明;③ 属性的种类

  3. 引入DTD原因:① 提供一种验证的手段; ② 实现了文件格式的统一化,提高文件的重用性; ③ 使用DTD进行验证,增加了操作时间。

  4. DTD声明:内部外部
    内部DTD

    <?xml version="1.0"?>
    <!DOCTYPE note [
     <!ELEMENT note (to, from, heading, body)>
     <!ELEMENT to (#PCDATA)>
     <!ELEMENT from (#PCDATA)>
     <!ELEMENT heading (#PCDATA)>
     <!ELEMENT body (#PCDATA)>
    ]>
    <note>
     <to>Tove</to>
     <from>Jani</from>
     <heading>Reminder</heading>
     <body>Don't forget me this weekend!</body>
    </note>
    

    外部DTD

    创建DTD文件
    <!ELEMENT note (to, from, heading, body)>
    <!ELEMENT to (#PCDATA)>
    <!ELEMENT from (#PCDATA)>
    <!ELEMENT heading (#PCDATA)>
    <!ELEMENT body (#PCDATA)>
    引用外部DTD
    <?xml version="1.0"?>
    <!DOCTYPE note SYSTEM "note.dtd">
    <note>
      <to>George</to>
      <from>John</from>
      <heading>Meeting</heading>
      <body>Don't forget the 2 PM meeting!</body>
    </note>
    

    混合使用

    <?xml version="1.0"?>
    <!DOCTYPE note SYSTEM "note.dtd" [
      <!ATTLIST note id ID #IMPLIED>
    ]>
    <note id="n1">
      <to>Alice</to>
      <from>Bob</from>
      <heading>Birthday</heading>
      <body>Happy birthday!</body>
    </note>
    
  5. 属性声明:

    <!ATTLIST 元素名称 属性名称 属性默认值>
    
  6. 实体声明:

    <!Entity 实体名称 实体内容>
    
  7. 元素声明:

    <!ELEMENT 元素名称 元素定义>
    

XML Schema

  1. Schema文档是一种特殊的XML文档,容易学习和使用。一个XML文档只能使用一个DTD文档,Schema则采用名域空间机制,使一个XML文档可调用多种Schema文档

  2. 实例:

    点击展开代码
    <?xml version="1.0" ?>
    <books xmins="x-schema:2.xml">
      <book>hello word</book>
    </books>
    

可扩展样式表语言

  1. XSL是描述XML文档样式信息的一种语言,由W3C制定
  2. XSL组成: ① 描述了如何将XML文档转化为可浏览或可输出的格式; ② 定义格式对象(Fomatted Object, FO),源树转换为可以显示的结果树(树转换),按照FO分析结果树,产生一个输出结果(过程称为格式化)
  3. XSL模式:
    image

其他相关规范

  1. XPath:采用简洁的非XML语法,基于XML文档的逻辑结构,在该结构中导航
  2. XPath表达式出现在URL和XML属性值里
  3. XPath定义了:① 表达式语法, ② 名为XPath核心库的基本函数
  4. Xlink:指定一个文档如何连接另一个文档
  5. XPointer: 指定文档内部未知

面向构件的软件设计

构件的概念

  • 定义:构件是可以实现特定的功能,符合一套接口标准并实现一组接口,在系统中实际存在的可更换部分
    image

构件的布线标准

  • 布线标准
    image

构件框架

  1. 体系结构核心:① 由一组平台决策、一组构建框架和构件框架之间的互操作设计组成。平台是允许在其上安装构件和构件框架的一个基础设施; ② 是一种专用的体系结构,常常实现一些协议已连接构件; ③ 多数原子构件永远不会被单独部署,尽管可以单独部署。
    image
  2. 语境相关组合构件框架
    image
  3. 构件开发
    1. 获取构件的方法
      • 现有构件获取得到可复用构件
      • 遗留工程获取可复用构件
      • 购买
      • 开发新构件
    2. 开发构件的3种方法
      • 分区:将问题情景的空间分割成多个可以独立的部分
      • 抽象:对给定实践内执行计算的软/硬件单元的一种抽象
      • 分割:将结构引入构件的行为,支持对行为性质进行时序推理
    3. 构件使用问题:① 异步问题; ② 多线程问题; ③ 无继承状态; ④ 坚壳类;⑤ 语言支持; ⑥ 调用者封装
  4. 构件标准
    1. CORBA:OMG(对象管理集团)制定
    2. COM/DCOM:Microsoft
    3. EJB:sun的Java企业Bean制定

构件平台与典型架构

2~8分

OMG方式

  1. 对象管理组(OMG)通过规范化对象开放市场的所有层次上的互操作性
  2. CORBA目标:使不同语言、不同实现和不同平台间能进行交互。
  3. OMG跨越ORG(对象请求代理)协议——互操作协议(Internet Inter-ORB Protocol, IIOP),明确了基于CORBA系统与基于微软COM系统之间的互操作细节
  4. CORBA包含:一套条用接口、一套对象适配器、对象请求代理
  5. CORBA Service包含两大类:① 应用于企业计算系统(支持大规模操作); ② 应用于细粒度的对象操作(小范围操作、实用价值较差、细分领域);
  6. CORBA服务包括:① 命名服务,交易器服务; ② 事件服务,通告服务; ③ 对象事务服务; ④ 安全服务; ⑤ 支持细粒度对象互操作服务; ⑥ 并发控制服务;⑦ 许可服务; ⑧ 生命周期服务;⑨ 关系服务; ⑩ 持久状态服务;外部化服务; 属性服务;对象查询服务; 对象集合服务; 时间服务
  7. CORBA构件模型:可移植对象适配器、CCM构件、CCM容器
  8. CORBA设施:分为水平支持(普遍共性)和垂直支持(领域特殊性)

SUN公司方式

  1. Java构件技术概述
    1. Java&Java2:Java规范受Applet思想影响,Java2这个基础上做出突破
    2. Java运行环境(Java Runtime Environment, JRE)是J2SE平台的一部分,J2SE又是J2EE平台的一个子集。JRE包括运行时刻、核心库和浏览器插件。
  2. JavaBean:Java构件。
  3. 基本Java服务
    • 反射:包括原始Java语言的特性、一套支持类,以及支持类文字的语言特性
    • 对象序列化:通过定义一个标准的连续编码方案来遍历和序列化对象本身
    • Java本地接口:规定了这些外部代码如何按照传递过去的应用访问Java对象
    • Java AWT和JFC/Swing
  4. Java各种构件:
    1. Applet:用于轻量级的可下载的构件,增强网站在浏览器中的视觉效果
    2. JavaBean: 支持基于连接的程序,比如同时用于客户端和服务器端的程序
    3. EJB: 使用容集成服务,用以支持EJB构件使用声明属性和部署描述符的方式来请求服务
    4. Servlet:服务器端构件模型,由web服务器进行进行实例化的轻量级构件
    5. 应用客户端构件
  5. 高级Java服务:
    1. 分布式对象和RMI
    2. Java和CORBA
    3. 企业级服务接口:Java命名和目录接口(JNDI); Java消息服务(JMS); Java数据库连接(JDBC); Java事物AOI和服务(JTA, JTS)
    4. J2EE连接容器架构
    5. Java和XML
  6. Java和Web服务——SunONE:SunONE是J2EE的扩展。

Microsoft的方式

  1. 基础关联模型——COM
    1. COM是微软平台上所有构件的基石
    2. COM定义的一个基础实体是接口。在二进制层面上,一个接口被表示为指向一个接口节点的指针
    3. 表示COM对象的通常方法是将其画成带有插口的盒子,通常把IUnknow接口置于COM对象图的顶端。
  2. COM对象重用
    1. COM不支持继承
    2. COM支持两种对象组装:包含和聚集
  3. 接口和多态
    1. COM接口单继承
    2. COM皆苦继承与多态无关
    3. 接口和版本化
  4. COM对象的创建和COM库
    1. 创建COM类的实例对象时,COM需要把给定的CLSID映射为包含所请求类的实际构件。
    2. COM支持系统注射器,类似于CORBA存储器
    3. 注册器指明服务可用支持等情况
  5. COM到分布式COM(DCOM)
    1. DCOM中用于支持进程间通信的对象:客户端代理(Proxy)对象和服务器端桩(Stub)对象
  6. 复合文档和OLE对象
    1. OLE可被概括为一组预定义的COM接口
    2. OLE符合文档的方法对文档容器(接受后者内容)和文档服务器(提供某种内容模型和显示、操作内容的能力)进行区分。
  7. .NET框架:对语言组件开发和执行环境,提供跨语言的统一编程环境。公共语言运行时(Common Language Runtime, CLR)、服务框架(Service Framework)和上层的两类应用模板(传统Windows应用模板和基于ASP.NET的面向web的网络应用程序模板)

战略比较

相同点 不同点
一种构件传输格式——Java JAR文件、COM cab文件、CCM、CLI配件 每个平台的二进制接口标准不同
统一方式的数据传输 兼容性和可移植性的源代码级的标准
事件和事件连接或者信道、单播和多播 逐渐形成的和仓促造就的标准
元信息——反省、反射 内存管理、生命周期和垃圾回收
某种形式的持久化、序列化或者外部化 容器管理的持久性和关系
基于属性的便哼或部署描述 开发环境、服务、部署、传输、网络服务构件
适合于应用服务器的特定构件模型 产业相关组件支持和应用状况
适合于Web服务器的特定构件模型 分类的概念

信息安全技术

6~15分

信息安全关键技术

image

  1. 对称密钥密码体制及典型算法:传统密码算法,优点:效率高、速度快; 缺点 :密钥管理复杂
    1. DES算法:分组加密算法,以64位分组对数据加密。密钥长度56位(每第8位用作奇偶校验)
    2. IDEA算法:国际数据加密算法,分组长度64B,密钥长度128B,运行简单,只需要异或,速度快
  2. 非对称密码加密算法:RSA、双密钥、公钥密码。安全依赖于素数分解
    • 常见用途:常用于数据加密和数字签名。
    • 缺点:速度慢
  3. 安全协议
    1. IPSec协议:在IP层上对数据包进行高强度的安全处理提供数据源验证、无连接数据完整性、数据机密性、抗重播、有限通信流机密性等安全服务。
      • 工作原理:通过使用两种信息安全协议来为数据报提供高质量的安全性(AH(认证头协议,Authentication Header)、ESP(封装安全载荷协议,Encapsulating Security Payload))。允许系统或网络用户控制安全服务提供的粒度,由通信双方建立的安全关联来提供。
      • 安全性分析:① 可以应用于所有跨越网络边界的通信; ② 如果所有来自外部的通信必须使用IP,且防火墙是Internet与组织的唯一入口,则IPSec不能被绕过; ③ IPSec位于传输层之下,因此对应用程序时透明的,实现时,没有必要在用户或服务器上更改软件;④ IPSec对最终用户透明
    2. SSL协议:Natscape推出的网络安全协议,在传输过程通信协议(TCP/IP)基础上实现
      • 主要用途:对计算机之间会话进行加密,位于TCP和应用层之间,可为应用层提供安全服务。
      • 工作原理:SSL连接和SSL会话。连接是提供恰当类型服务的传输,会话是客户和服务器之间的关联,会话通过握手协议来创建
      • 工作过程:建立安全能力;服务器身份验证和密钥交换;客户机验证和密钥交换;完成
    3. PGP协议:PGP协议是正对电子邮件在Internet上通信的一种混合加密系统。
      • 优点:速度快、效率高、可移植性好
      • 加密过程:IDEA算法对明文加密,再用接收者的RSA公钥对IDEA密钥进行加密
    4. L2TP:二层协议,对传统拨号协议PPP的扩展,通过定义多协议跨越第二层点对点连接的一个封装协议,来整合多协议拨号服务至现有的Internet服务提供商点,保证分散的远程客户端通过隧道方式经由Internet等网络访问企业内部网络,VPN协议
    5. PAP:二层协议PPP的握手协议,保证PPP链接安全性
  4. 防火墙
    • 作用:
      • 控制访问:防火墙主要基于预设的安全规则,对进出网络的数据包进行过滤和检查,允许或拒绝数据包的传输。
      • 网络地址转换(NAT):防火墙可以隐藏内部网络的真实IP地址,增强网络的安全性。
      • 虚拟专用网络(VPN)支持:防火墙可以支持VPN,为远程用户提供安全的网络访问。
      • 日志和审计:防火墙可以记录网络流量和安全事件,为安全审计和故障排查提供依据。
    • 工作原理:防火墙的工作原理基于网络层的访问控制,通过检查数据包的源地址、目的地址、端口号等信息,决定是否允许数据包通过。
    • 意义:注重于网络层的访问控制和安全防护
  5. 网闸:
    • 作用:
      • 安全隔离:网闸通过物理或逻辑隔离技术,在两个或多个网络之间建立一道屏障,防止直接的网络连接,从而避免潜在的安全威胁在不同网络之间传播。
      • 信息交换:在受控条件下,网闸允许必要的信息交换,通常通过特定的协议或应用层代理来实现,确保数据在传输过程中的安全性和完整性。
      • 数据摆渡:网闸采用数据“摆渡”的方式实现两个网络之间的数据交换,即先读取并验证源网络的数据,再将这些数据写入目标网络,确保数据在传输过程中不直接穿透网络隔离。
    • 工作原理:网闸的工作原理基于安全隔离和信息交换的需求,通过物理或逻辑隔离技术实现网络之间的隔离,并通过特定的协议或应用层代理实现信息交换
    • 意义:注重于实现不同安全级别网络之间的安全隔离和信息交换
      • 当用户的网络需要保证高强度的安全,同时又与其他不信任网络进行信息交换的情况下,如果采用物理隔离卡,用户必须使用开关在内外网之间来回切换,不仅管理起来非常麻烦,使用起来也非常不方便。如果采用防火墙,由于防火墙自身的安全很难保证,所以防火墙也无法防止内部信息泄漏和外部病毒、黑客程序的渗入,安全性无法保证。在这种情况下,安全隔离网闸能够同时满足这两个要求,弥补了物理隔离卡和防火墙的不足之处,是最好的选择。
      • 对网络地隔离是通过网闸隔离硬件实现两个网络在链路层断开,但是为了交换数据,通过设计的隔离硬件在两个网络间进行切换,通过对硬件上的存储芯片的读写,完成数据的交换。
      • 安装了相应的应用模块之后,安全隔离网闸可以在保证安全的前提下,使用户可以浏览网页、收发电子邮件、在不同网络上的数据库之间交换数据,并可以在网络之间交换定制的文件。

信息安全管理和评估

安全管理技术就是监督、组织、控制网络通信服务以及信息处理所必需的各种技术手段和措施的总称。
image

信息安全保障体系

* 建立统一的身份认证体系
* 建立统一的信息安全管理体系
* 建立规范的信息安全保密体系
* 建立完善的网络边界防护体系

系统安全架构设计

信息系统安全架构描述

  1. 信息安全的特征时保证信息的机密性、完整性、可用性、可控性、不可抵赖性
  2. 常见的安全威胁
    1. 系统故障:硬件故障、软件故障、链路故障、供电故障
    2. 人员无意识行为:编程错误、操作错误、无意泄密
    3. 人为蓄意破坏:被动型攻击(网络监听、非法登录、信息截取)、主动型攻击(数据篡改、假冒身份、拒绝服务DOS、重放攻击、散播病毒、主观抵赖)
    4. 灾难性攻击:水灾、火灾、地震、雷击、战争
  3. 安全技术的五个方面:认证鉴别、访问控制、内容安全、冗余恢复、审计响应
  4. 相关组织:国际标准化组织(ISO)、信息技术安全分技术委员会

系统安全体系架构规划框架及其方法

安全技术体系架构的目标时建立可持续改进的安全技术体系架构的能力

  • 五个层次实体对象:应用、存储、主机、网络、物理
  • 信息系统安全体系
    image
  • 信息系统安全规划的具体环节以及关系:
    • 信息系统安全规划依托于企业信息化战略规划
    • 信息系统安全规划依需要围绕技术安全、管理安全、组织安全考虑
    • 信息系统安全规划依以信息系统与信息资源的安全保护为核心

网络安全体系架构设计

  1. OSI的安全体系架构
    • 在OSI七层协议中,除会话层外,每一层均能提供相应的安全服务。最适合配置安全服务的是物理层、网络层、运输层、应用层。
    • ISO开放系统互联安全体系的五类安全服务:鉴别、访问控制、数据机密性、数据完整性、抗抵赖性
  2. 网络安全体系框架
    • 鉴别框架:防止其他实体占用和独立操作被鉴别实体的身份。认证服务提供了实体声称其身份的保证,只有在主题和验证者的关系背景下,认证才有意义。认证服务的主要实现方式包括以下五种:①已有的信息,如认证口令。②拥有的信息,如 IC卡、令牌等。③不可改变的特性,如指纹、虹膜等生物特征。④相信可靠的第三方建立的认证。⑤环境,如主机地址等。
    • 访问控制框架:决定允许使用哪些资源、在什么地方适合阻止未授权的访问的过程。访问控制实例中,访问可以对一个系统或对系统内部进行。常见的访问控制服务的实现方式包括以下三种方式:①自主访问控制(DAC)。自主访问控制是一种接入控制服务,通过执行基于系统实体身份及其到系统资源的接入授权。包括在文件、文件夹和共享资源中设置许可。用户有权对自身所创建的文件、数据表等访问对象进行访问,并可将其访问权授予其他用户或收回其访问权限。允许访问对象制定针对该对象访问的控制策略,通常可通过访问控制列表来限定针对客体可执行的操作。②强制访问控制(MAC)。强制访问控制是系统强制主体服从访问控制策略,是由系统对用户所创建的对象,按照规定的规则控制用户权限及操作对象的访问。其主要特征是对所有主体及其所控制的进程、文件、段、设备等客体实施强制访问控制。③基于角色访问控制(RBAC)。基于角色访问控制主要通过对角色的访问进行控制,使权限与角色相关联,用户通过成为适当角色的成员而得到其角色的权限。用户可依其责任和资格分派相应的角色,角色可依新需求和系统合并赋予新权限,而权限也可根据需要从某角色中收回。
    • 机密性框架:确保信息仅对被授权者可用,信息的保护可以通过确保数据被限制于授权者获得,或通过特定方式表示数据来获得。信息的机密性主要通过以下三种方式实现:①通过禁止访问提供机密性,即可以通过访问控制,以及通过物理媒体保护和路由选择控制保证机密性。
      ②通过加密提供机密性,即防止数据泄漏在传输或存储中。加密机制包括基于对称的加密机制和基于非对称的加密机制。③还可以通过数据填充、虚假事件(例如隐藏在不可信链路上交换的信息流总量)、保护 PDU 头和时间可变域提供机密性。
    • 完整性框架:通过组织威胁或探测威胁,保护可遭到不同方式危害的数据完整性和数据相关属性完整性,即保证数据不以未经授权方式进行改变或损毁。数据完整性的常见实现方式包括: ① 阻止对数据传输媒介访问的机制。包括物理隔离、不受干扰的信道、路由控制、访问控制等 ② 探测对数据非授权修改的机制。包括密封、数字签名、数据重复、与密码变换相结合的数字指纹和消息序列号等。
    • 抗抵赖性框架:包括证据的生成、验证、记录,以及在解决纠纷时随机进行的证据恢复和再验证。抗抵赖服务是提供有关特定事件或行为的证据,包括证据的生成、验证和记录,以及在解决纠纷时随即进行的证据恢复和再次验证。抗抵赖性服务的实现方式主要包括数字签名、用户认证、操作日志等技术。

数据库系统的安全设计

  1. 数据库安全设计标准
    1985 年,美国国防部颁布“可信计算机系统评估标准(TrustedComputerSystem EvaluationCriteria,TCSEC/DoD85 )”橘皮书。
    1991年,美国国家计算机安全中心(The National Computer Seaurity Center,NCSC)颁布了“可信计算机评估标准关于可信数据库管理系统的解释(Trusted Database Interpretation,TDI)”。
  2. 数据库完整性设计:是指数据库中数据的正确性和相容性,就是数据库完整性约束的设计,通过DBMS或应用程序来实现
    1. 数据库完整性设计原则
      • 确定其实现的系统层次和方式,并提前考虑对系统性能的影响
      • 实体完整性约束、参照完整性约束是关系数据库最重要的完整性约束,尽量应用
      • 要慎用触发器
      • 在需求分析阶段就必须制定完整性约束的命名规范
      • 要根据业务规则对数据库完整性进行细致的测试
      • 要有专职的数据库设计小组
      • 应采用合适的CASE工具来减少数据库设计各阶段的工作量
    2. 数据库完整性的作用
      1. 能够防止合法用户使用数据库时向数据库中添加不合语义的数据
      2. 实现业务规则,易于定义、易于理解,而且可以降低应用程序的复杂性,提高应用程序的运行效率,更容易实现数据库的完整性。
      3. 能够同时兼顾数据库的完整性和系统效能。
      4. 有助于尽早发现应用软件的错误
      5. 六类数据库完整性约束:列级静态约束、元组级静态约束、关系级静态约束、列级动态约束、元组级动态约束、关系级动态约束。
  3. 数据库完整性设计示例
    1. 需求分析阶段。确定系统模型中应该包含的对象以及各种业务规则。
    2. 概念结构设计阶段。将依据需求分析的结果转换成一个独立于具体 DBMS 的概念模型,即实体关系图。
    3. 逻辑结构设计阶段。就是将概念结构转换为某个DBMS所支持的数据模型,并对其进行优化,包括对关系型的规范化。
  4. 数据库系统安全设计原理(AAA)
    RADIUS 服务器负责接收用户的连接请求,完成验证,并把用户所需的配置信息返回给BAS建立连接,在可以获得访问其他网络的权限时,BAS就起到了认证用户的作用。BAS负责通过密钥完成用户之间的验证信息传递。
    • 验证(Authentication):是否可以获得授权
    • 授权(Authorization):可以使用哪些服务
    • 审计(Accounting):记录用户使用情况
  5. 数据库系统安全软件架构设计
    1. RADIUS软件主要应用于宽带业务运营的支撑管理,是一个需要可靠运行且高安全级别的软件支撑系统。
    2. RADIUS 软件架构分为三个层面:协议逻辑层、业务逻辑层和数据逻辑层。协议逻辑层主要实现 RFC框架中的内容,处理网络通信协议的建立、通信和停止方面的工作。业务逻辑层的设计是RADIUS软件架构设计的核心部分,协议处理进程主要对转发引擎发来的包进行初步分析,并根据包的内容进一步分发到不同的业务逻辑处理进程。
    3. RADIUS软件分层架构的实现:一是对软件风险进行了深入的分析;二是可以构建一个或多个重用的构件单元,也可以继承原来的成果。
    4. RADIUS的功能:一是实际处理大量用户并发的能力;二是软件架构的可扩展性
    5. 负载均衡是提高RADIUS软件性能的有效方法,主要完成以下任务:
      1. 解决网络拥塞问题,就近提供服务。
      2. 为用户提供更好的访问质量。
      3. 提高服务器响应速度。
      4. 提高服务器及其他资源的利用效率。
      5. 避免了网络关键部位出现单点失效。

系统的可靠性分析

软件的可靠性

  1. 软件可靠性(Reliability)定义:在规定的条件下,在规定的时间内,软件不引起系统失效的概率,该概率是系统输入和系统使用的函数,也是软件中存在的缺陷函数;系统输入将确定是否会遇到已存在的缺陷。
  2. 软件可靠性的定量描述:软件的可靠性是在软件使用条件、在规定时间内、系统的输入输出、系统使用等变量构成的数学表达式
    image
  3. 软件可靠性的目标:软件的可靠性是指用户对所使用软件性能满意程度期望。可以用可靠度、平均失效时间和故障强度等来描述。
  4. 可靠性测试的目的
    • 发现软件系统缺陷 -> 需求分析、软件设计、系统编码、测试实施
    • 为软件的使用和维护提供可靠性依据
    • 确认软件是否达到可靠性的定量要求

软件可靠性建模

  1. 影像软件可靠性的因素:运行环境、软件规模、软件的内部结构、软件 的开发方法和开发环境、软件的可靠性投入
  2. 软件可靠性模型的组成和特性
    image
  3. 软件可靠性建模方法分类:软件可靠性建模方法有种子法、失效率类、曲线拟合类、可靠性增长、程序结构分析、输入域分类、执行路径分析方法、非齐次泊松过程、马乐可夫过程、贝叶斯分析十类。
  4. 软件可靠性测试用例设计:测试用例要能够反映实际的使用情况,优先测试最重要和最频繁使用的功能。设计测试用例,针对组合功能或特定功能,编写成相关文档。
    image
  5. 软件可靠性测试的实施:用时间定义的软件可靠性数据分为四类:失效时间数据、失效间隔时间数据、分组时间内的失效数、分组时间的累积失效数。
    image

软件可靠性评价

  1. 选择可靠性模型
    • 模型假设的适用性。
    • 预测的能力与质量。
    • 模型输出值能否满足可靠性的评价需求
    • 模型使用的简便性。
  2. 可靠性数据的收集
    • 尽可能早地确定可靠性模型。
    • 数据收集计划要有较强的可操作性。
    • 重视测试数据的分析和整理。
    • 充分利用技术手段(数据库技术)来完成分析和统计。

软件的可靠性设计与管理

  1. 软件可靠性设计

    • 容错设计技术:恢复块设计、N版本程序设计、冗余设计。
    • 检错技术:考虑检测对象、检测延时、实现方式、处理方式四个要素。
    • 降低复杂度设计。
  2. 软件可靠性管理的各个阶段

    • 需求分析阶段
    • 概要设计阶段
    • 详细设计阶段
    • 编码阶段
    • 测试阶段
    • 实施阶段
  3. 软件测试VS软件调试
    软件确认测试包括:内部确认测试、Alpha、Beta 和验收测试。

    对比维度 软件测试 软件调试
    核心目标 发现软件缺陷,验证功能是否符合需求规格 定位并修复已发现的缺陷,确保软件按预期运行
    执行阶段 贯穿软件开发全周期(需求分析→维护) 通常在测试阶段后,针对已发现的缺陷进行
    主要方法 - 黑盒测试(输入/输出验证)
    - 白盒测试(代码逻辑覆盖)
    - 自动化测试
    - 静态调试(代码审查、日志分析)
    - 动态调试(单步执行、断点调试)
    关键工具 JIRA(缺陷管理)、Selenium(自动化)、Postman(API测试)、LoadRunner(性能) IDE调试器(GDB、Visual Studio)、日志分析工具(ELK Stack)、堆栈跟踪工具
    人员角色 测试工程师、自动化测试工程师、QA团队 开发工程师、技术支持团队
    输出结果 缺陷报告(含复现步骤、严重程度)、测试覆盖率报告 修复后的代码版本、调试日志(记录问题原因及修复过程)
    思维模式 破坏性思维:尝试触发异常场景,暴露潜在问题 建设性思维:分析问题根源,优化代码逻辑,确保稳定性
    依赖关系 独立执行,但需调试修复后重新验证 依赖测试提供的缺陷报告,修复后需测试确认效果
    典型场景 测试用户登录功能时发现特定网络环境下失败,记录缺陷并提交报告 开发人员通过日志分析定位到网络超时设置过短,修改代码后重新部署
    侧重点 验证正确性:软件是否“做对了事” 修复正确性:软件是否“把事做对”

    补充说明

    1. 互补性:测试是“找问题”,调试是“解决问题”,两者形成闭环,共同提升软件质量。
    2. 自动化差异:测试可高度自动化(如UI测试、接口测试),而调试通常需人工干预(如分析堆栈、设置断点)。
    3. 范围差异:测试覆盖功能、性能、安全等多维度,调试仅聚焦于已暴露的缺陷修复。
posted @ 2025-07-03 10:32  AI大火腿  阅读(110)  评论(0)    收藏  举报
跟随粒子特效