设计模式7大原则与UML类图详解

设计模式7大原则与UML类图详解

引言 🌟

在这里插入图片描述

在软件工程领域,设计模式和UML(统一建模语言)是提高代码质量、增强系统可维护性的重要工具。设计模式提供了解决软件设计中常见问题的通用方案,而UML则为我们提供了一种可视化的建模语言,帮助我们清晰地表达系统结构和行为。本文将深入探讨设计模式的七大原则,并结合UML类图进行详细解析。

一、设计模式七大原则 💡

设计模式的七大原则是软件设计的基础准则,遵循这些原则可以使我们的代码更加灵活、可维护和可扩展。下面我们将逐一介绍这七大原则,并通过实例和类图进行说明。

1. 单一职责原则(Single Responsibility Principle) 🎯

定义:一个类应该只有一个引起它变化的原因。

解释:如果一个类承担了过多的职责,那么在一个职责发生变化时,可能会影响其他职责的实现,导致代码难以维护和扩展。遵循单一职责原则,可以使类更加专注,降低耦合度。

示例:假设我们有一个Book类,它既负责管理书籍的信息,又负责打印书籍的信息。

违反单一职责原则的类图

@startuml
class Book {- title: String- author: String+ setTitle(title: String): void+ setAuthor(author: String): void+ printBook(): void
}
@enduml

在这里插入图片描述

重构后遵循单一职责原则的类图

@startuml
class Book {- title: String- author: String+ setTitle(title: String): void+ setAuthor(author: String): void
}class BookPrinter {+ printBook(book: Book): void
}
@enduml

在这里插入图片描述

在这个重构中,我们将打印功能从Book类中分离出来,创建了一个新的BookPrinter类,专门负责打印书籍的信息。

2. 开放封闭原则(Open/Closed Principle) 🚪

定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。

解释:当我们需要为系统添加新的功能时,应该通过扩展已有模块来实现,而不是修改已有模块。这样可以避免对现有代码的修改,减少引入新错误的风险。

示例:假设我们有一个图表绘制系统,最初只支持绘制圆形。

违反开放封闭原则的类图

@startuml
class Shape {+ draw(): void
}class Circle {+ draw(): void
}
@enduml

在这里插入图片描述

每次添加新形状时,都需要修改Shape类或Circle类,这违反了开闭原则。

遵循开放封闭原则的类图

@startuml
interface Shape {+ draw(): void
}class Circle implements Shape {+ draw(): void
}class Square implements Shape {+ draw(): void
}
@enduml

在这里插入图片描述

通过定义一个Shape接口,我们可以轻松地添加新的形状类,而无需修改现有代码。

3. 里氏替换原则(Liskov Substitution Principle) 🔄

定义:所有引用基类的地方必须能透明地使用其子类的对象。

解释:子类应该能够替换父类并且不会影响程序的正确性。这意味着子类在继承父类时,不应修改父类的行为。

示例:假设我们有一个Rectangle类,然后创建了一个Square类继承自Rectangle

违反里氏替换原则的类图

@startuml
class Rectangle {- width: int- height: int+ setWidth(width: int): void+ setHeight(height: int): void+ area(): int
}class Square extends Rectangle {+ setWidth(width: int): void {super.setWidth(width)super.setHeight(width)}+ setHeight(height: int): void {super.setWidth(height)super.setHeight(height)}
}
@enduml

在这个例子中,Square类重写了setWidthsetHeight方法,导致无法正确计算面积,破坏了继承关系。

遵循里氏替换原则的类图

@startuml
interface Shape {+ area(): int
}class Rectangle implements Shape {- width: int- height: int+ setWidth(width: int): void+ setHeight(height: int): void+ area(): int
}class Square implements Shape {- side: int+ setSide(side: int): void+ area(): int
}
@enduml

RectangleSquare都作为Shape的实现类,各自实现自己的行为,避免了继承带来的问题。

4. 接口隔离原则(Interface Segregation Principle) 🔍

定义:客户端不应该依赖它不需要的接口。

解释:一个类对另一个类的依赖应该建立在最小的接口上。避免创建过大的接口,导致客户端依赖于它们不需要的部分。

示例:假设我们有一个Animal接口,包含了飞行和游泳的方法。

违反接口隔离原则的类图

@startuml
interface Animal {+ fly(): void+ swim(): void
}class Bird implements Animal {+ fly(): void+ swim(): void { throw UnsupportedOperationException() }
}class Fish implements Animal {+ fly(): void { throw UnsupportedOperationException() }+ swim(): void
}
@enduml

在这里插入图片描述

BirdFish都实现了flyswim方法,但实际上Fish不需要飞行功能,Bird不需要游泳功能。

遵循接口隔离原则的类图

@startuml
interface Flyable {+ fly(): void
}interface Swimmable {+ swim(): void
}class Bird implements Flyable {+ fly(): void
}class Fish implements Swimmable {+ swim(): void
}
@enduml

在这里插入图片描述

通过将接口拆分为FlyableSwimmable,让不同的类只实现它们需要的接口。

5. 依赖倒置原则(Dependency Inversion Principle) ⬇️⬆️

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象。

解释:抽象不应该依赖于细节,细节应该依赖于抽象。这样可以降低模块之间的耦合度,提高系统的灵活性。

示例:假设我们有一个OrderService类,它直接依赖于Database类。

违反依赖倒置原则的类图

@startuml
class OrderService {- database: Database+ saveOrder(order: Order): void {database.save(order)}
}class Database {+ save(order: Order): void
}
@enduml

在这里插入图片描述
1)

OrderService直接依赖于Database,如果需要更换数据库,可能需要修改OrderService的代码。

遵循依赖倒置原则的类图

@startuml
interface DataStorage {+ save(order: Order): void
}class OrderService {- storage: DataStorage+ saveOrder(order: Order): void {storage.save(order)}
}class Database implements DataStorage {+ save(order: Order): void
}class CloudStorage implements DataStorage {+ save(order: Order): void
}
@enduml

在这里插入图片描述

通过引入DataStorage接口,OrderService依赖于抽象,而不是具体实现。

6. 迪米特法则(Law of Demeter) 👥

定义:一个对象应该对其他对象有最少的了解。

解释:一个类应该只与它的直接朋友通信,而不应该与陌生人通信。这有助于降低系统的耦合度。

示例:假设我们有一个University类,它直接调用了Department类的getProfessors方法,而Department类又调用了Professor类的getName方法。

违反迪米特法则的类图

@startuml
class University {- departments: List<Department>+ getProfessorNames(): List<String> {for (department in departments) {for (professor in department.getProfessors()) {print(professor.getName())}}}
}class Department {- professors: List<Professor>+ getProfessors(): List<Professor> {return professors}
}class Professor {- name: String+ getName(): String {return name}
}
@enduml

University类直接依赖于DepartmentProfessor类的内部实现。

遵循迪米特法则的类图

@startuml
class University {- departments: List<Department>+ getProfessorNames(): List<String> {for (department in departments) {for (name in department.getProfessorNames()) {print(name)}}}
}class Department {- professors: List<Professor>+ getProfessorNames(): List<String> {return [professor.getName() for professor in professors]}
}class Professor {- name: String+ getName(): String {return name}
}
@enduml

University类只与Department类交互,Department类负责内部细节,降低了耦合度。

7. 组合/聚合复用原则(Composition/Aggregation Reuse Principle) 🧩

定义:尽量使用组合/聚合关系,而不是继承关系来复用代码。

解释:组合/聚合关系比继承关系更加灵活,可以减少类之间的强耦合,提高系统的可维护性。

示例:假设我们有一个Engine类和一个Car类。

违反组合/聚合复用原则的类图

@startuml
class Engine {+ start(): void
}class Car extends Engine {+ drive(): void
}
@enduml

在这里插入图片描述

Car继承了Engine,如果Engine类发生变化,Car类也会受到影响。

遵循组合/聚合复用原则的类图

@startuml
class Engine {+ start(): void
}class Car {- engine: Engine+ drive(): void {engine.start()}
}
@enduml

在这里插入图片描述

Car类通过组合Engine类来实现功能,这样Car类与Engine类之间的耦合度更低,更容易扩展和维护。

二、UML类图详解 📊

UML(Unified Modeling Language)是一种用于软件系统可视化建模的标准语言。UML类图是UML中最常用的图之一,用于描述系统中的类及其之间的关系。接下来,我们将结合设计模式的七大原则,进一步了解UML类图的构成和用途。

1. UML类图的基本构成

类(Class)
UML中的类表示系统中的一个对象类型。一个类通常由三部分组成:

  • 类名(Class Name):位于类的顶部,用于标识类的名称。
  • 类的属性(Attributes):位于类的中间部分,用于描述类的特性或数据成员。格式为可见性 名称: 类型 [多重性],其中可见性包括+(公有)、-(私有)和#(保护)。
  • 类的方法(Methods):位于类的底部,用于描述类的行为或操作。格式为可见性 名称(参数列表): 返回类型 [多重性]

示例类图

@startuml
class Book {- title: String- author: String+ setTitle(title: String): void+ getTitle(): String+ setAuthor(author: String): void+ getAuthor(): String
}
@enduml

在这里插入图片描述

2. 类之间的关系

UML类图中的关系主要包括以下几种:

  • 继承(Inheritance/Generalization):表示子类继承父类的属性和方法。用带空心三角箭头的实线表示,箭头指向父类。

    @startuml
    class Animal
    class Bird
    Bird --|> Animal
    @enduml
    

    在这里插入图片描述

  • 实现(Implementation/Realization):表示类实现接口中的方法。用带空心三角箭头的虚线表示,箭头指向接口。

    @startuml
    interface Flyable
    class Bird
    Bird ..|> Flyable
    @enduml
    

    在这里插入图片描述

  • 关联(Association):表示类之间的一种长期关系。用实线表示,可以带箭头表示方向。关联可以是单向或双向的。

    @startuml
    class Student
    class Course
    Student "1" -- "many" Course : registers
    @enduml
    

在这里插入图片描述

  • 聚合(Aggregation):表示整体与部分的关系,其中部分可以独立于整体存在。用带空心菱形箭头的实线表示,菱形指向整体。

    @startuml
    class Car
    class Engine
    Car o-- Engine : has
    @enduml
    

    在这里插入图片描述

  • 组合(Composition):表示整体与部分的关系,其中部分不能独立于整体存在。用带实心菱形箭头的实线表示,菱形指向整体。

    @startuml
    class House
    class Room
    House *-- Room : contains
    @enduml
    

    在这里插入图片描述

  • 依赖(Dependency):表示一个类的变化可能会影响另一个类。用带虚线的箭头表示,箭头指向被依赖的类。

    @startuml
    class Order
    class Database
    Order ..> Database : uses
    @enduml
    

    在这里插入图片描述

3. 类图的绘制工具

目前,有许多工具可以帮助我们绘制UML类图,以下是一些常用的工具:

  • PlantUML:一种开源的、基于文本的UML绘图工具,支持多种格式输出。
  • StarUML:一款功能强大、界面友好的UML建模工具,支持多种UML图。
  • Visual Paradigm:一款综合性的建模工具,涵盖从需求分析到部署的各个环节。
  • Lucidchart:在线UML绘图工具,支持协作和多种格式导出。

在本博客中,我们将使用PlantUML进行类图的绘制和展示。

4. 类图在软件设计中的应用

UML类图在软件设计中有以下几个主要应用:

  • 系统分析:在设计初期,通过类图描述系统的基本结构和类之间的关系,有助于明确系统的架构。
  • 代码生成:一些工具可以根据类图自动生成相应的代码框架,提高开发效率。
  • 文档生成:类图作为系统设计的可视化文档,便于团队成员之间的沟通和理解。
  • 系统维护:通过查看类图,可以快速理解系统的结构和类之间的关系,便于后期的维护和扩展。

三、设计模式与UML类图结合实例 🛠️

为了更深入地理解设计模式的七大原则和UML类图,我们通过具体的实例来展示如何在设计中使用这些原则,并通过类图进行表达。

1. 单一职责原则与类图

场景:在电商系统中,订单管理模块需要处理订单的创建、更新和状态跟踪。

问题:如果订单类既负责订单的管理,又负责订单状态的跟踪,会增加类的复杂性,违反单一职责原则。

解决方案:将订单管理和状态跟踪分离到不同的类中。

类图

@startuml
class Order {- id: String- items: List<Item>+ add_item(item: Item): void+ remove_item(itemId: String): void+ calculate_total(): float
}class OrderStatus {- status: String+ update_status(newStatus: String): void+ get_status(): String
}
@enduml

在这里插入图片描述

通过这样的设计,Order类专注于订单的管理,OrderStatus类专注于订单状态的管理,符合单一职责原则。

2. 开放封闭原则与类图

场景:在一个图形绘制系统中,需要支持多种图形的绘制,如圆形、矩形和三角形。

问题:如果每次新增图形都需要修改现有的绘图类,违反了开放封闭原则。

解决方案:通过定义一个绘制接口,让不同的图形类实现该接口。

类图

@startuml
interface Drawable {+ draw(): void
}class Circle implements Drawable {+ draw(): void
}class Rectangle implements Drawable {+ draw(): void
}class Triangle implements Drawable {+ draw(): void
}class DrawingTool {+ drawShape(shape: Drawable): void {shape.draw()}
}
@enduml

在这里插入图片描述

通过引入Drawable接口,DrawingTool无需修改即可支持新的图形类型,符合开放封闭原则。

四、类图在实际项目中的应用 🏗️

在设计模式和七大原则的应用中,UML类图不仅仅是一种理论工具,它在实际项目中有着广泛的应用。下面,我们将通过一个具体的案例来展示类图的实际应用,并进行深度优化和扩展。

案例:在线图书管理系统📚

背景:设计一个功能完善的在线图书管理系统,支持用户管理、图书管理、借阅管理、权限控制和系统配置等功能。

系统功能

  1. 用户角色管理(普通用户、管理员、VIP用户)
  2. 图书分类与标签管理
  3. 图书借阅与归还流程
  4. 借阅历史记录与统计
  5. 系统配置与权限控制
  6. 图书搜索与推荐

分析
根据系统功能,可以将系统划分为以下几个主要模块:

  • 用户管理模块(用户注册、登录、角色管理)
  • 图书管理模块(图书CRUD、分类、标签)
  • 借阅管理模块(借阅流程、归还、逾期处理)
  • 权限管理模块(角色权限控制)
  • 系统配置模块(全局配置管理)

类图设计

@startuml
' 用户相关类
interface User {+ register(): void+ login(username: String, password: String): boolean+ logout(): void+ updateProfile(profile: UserProfile): void
}class RegularUser implements User {- username: String- password: String- email: String- profile: UserProfile+ register(): void+ login(username: String, password: String): boolean+ logout(): void+ updateProfile(profile: UserProfile): void
}class AdminUser implements User {- username: String- password: String- permissions: List<Permission>+ register(): void+ login(username: String, password: String): boolean+ logout(): void+ updateProfile(profile: UserProfile): void+ managePermissions(): void
}class VIPUser implements User {- username: String- password: String- vipLevel: int- expiryDate: Date+ register(): void+ login(username: String, password: String): boolean+ logout(): void+ updateProfile(profile: UserProfile): void+ getVipBenefits(): List<String>
}class UserProfile {- firstName: String- lastName: String- phone: String- address: String- joinDate: Date
}' 图书相关类
class Book {- id: String- title: String- author: String- isbn: String- publisher: String- publishDate: Date- price: float- stock: int- category: BookCategory- tags: List<BookTag>- status: BookStatus
}class BookCategory {- id: String- name: String- parentCategory: BookCategory+ subCategories: List<BookCategory>
}class BookTag {- id: String- name: String+ relatedTags: List<BookTag>
}enum BookStatus {AVAILABLEBORROWEDRESERVEDLOSTMAINTENANCE
}' 借阅相关类
class BorrowRecord {- id: String- userId: String- bookId: String- borrowDate: Date- dueDate: Date- returnDate: Date- status: BorrowStatus- fineAmount: float
}enum BorrowStatus {ACTIVERETURNEDOVERDUELOST
}class Fine {- id: String- recordId: String- amount: float- dueDate: Date- paid: boolean
}' 系统管理相关类
class UserManager {+ registerUser(user: User): void+ loginUser(username: String, password: String): User+ logoutUser(userId: String): void+ updateUserProfile(userId: String, profile: UserProfile): void+ resetPassword(userId: String): void
}class BookManager {+ addBook(book: Book): void+ removeBook(bookId: String): void+ updateBook(book: Book): void+ searchBooks(keyword: String, filters: Map<String, String>): List<Book>+ getBookDetails(bookId: String): Book+ manageCategories(): void+ manageTags(): void
}class BorrowManager {+ borrowBook(userId: String, bookId: String): void+ returnBook(bookId: String): void+ renewBook(recordId: String): void+ getBorrowRecords(userId: String): List<BorrowRecord>+ calculateFine(recordId: String): float+ payFine(fineId: String): void
}class SystemConfig {- id: String- configKey: String- configValue: String- valueType: ConfigValueType+ updateConfig(key: String, value: String): void
}enum ConfigValueType {STRINGINTEGERBOOLEANFLOAT
}' 关系类
class Notification {- id: String- userId: String- message: String- type: NotificationType- isRead: boolean- createdAt: Date
}enum NotificationType {SYSTEMBORROWRETURNFINEPROMOTION
}' 类图关系
UserManager "1" --> "many" User
BookManager "1" --> "many" Book
BorrowManager "1" --> "many" BorrowRecord
BorrowManager "1" --> "many" Fine
User "1" --> "many" BorrowRecord
Book "1" --> "many" BorrowRecord
Book "1" --> "1" BookCategory
BookCategory "0..*" <-- "0..*" BookCategory : has subcategories
Book "0..*" --> "0..*" BookTag
BookTag "0..*" --> "0..*" BookTag : related to
SystemConfig "1" --> "many" ConfigValueType
User "1" --> "many" Notification
BorrowRecord "1" --> "1" Notification : generates
Fine "1" --> "1" Notification : generatesnote for User "用户基类接口\n定义所有用户类型\n的公共方法"
note right for RegularUser "普通用户\n具备基本借阅功能"
note right for AdminUser "管理员\n具备管理权限"
note right for VIPUser "VIP用户\n享受特殊权益"
note for Book "包含图书基本信息\n和状态管理"
note for BookCategory "支持多级分类\n树形结构"
note for BorrowRecord "记录借阅详情\n和状态变更"
note for Fine "逾期罚款管理"
note for Notification "系统通知\n多种类型"@enduml

完整类图:

在这里插入图片描述

增强说明

  1. 用户角色扩展
    • 新增VIP用户角色,支持不同等级的会员权益
    • 用户档案类UserProfile分离,便于扩展用户信息
  2. 图书管理增强
    • 图书分类支持多级树形结构
    • 添加图书标签系统,支持多对多关联
    • 图书状态枚举,更精确管理图书状态
  3. 借阅流程完善
    • 借阅记录状态机设计,支持ACTIVE/RETURNED/OVERDUE/LOST
    • 罚款系统设计,关联借阅记录
    • 续借功能支持
  4. 系统管理扩展
    • 配置管理系统,支持不同类型的配置值
    • 通知系统,关联多种事件类型
  5. 设计模式应用
    • 用户角色采用策略模式,便于扩展新角色
    • 图书分类采用组合模式,支持多级结构
    • 配置管理采用状态模式,灵活处理不同类型配置
  6. UML增强细节
    • 添加类注释note,说明设计意图
    • 使用枚举类型明确状态和类型
    • 关系标注更清晰,如"has subcategories"
    • 接口与实现分离更明确

系统架构优势

  1. 可扩展性
    • 新增用户角色只需实现User接口
    • 新增图书分类无需修改现有代码
    • 新增通知类型只需扩展NotificationType枚举
  2. 灵活性
    • 图书状态机设计支持复杂业务场景
    • 配置管理系统支持运行时修改
    • 多级分类支持灵活的图书组织方式
  3. 可维护性
    • 职责分离清晰,各模块独立演化
    • 接口隔离原则应用,降低耦合度
    • 类型安全设计,减少运行时错误
  4. 业务支持
    • 完整的借阅生命周期管理
    • 灵活的权限控制体系
    • 全面的系统监控能力

这个增强版的类图设计更加贴近实际项目的复杂需求,展示了如何通过UML类图表达复杂的业务逻辑和系统架构。通过合理的类设计和关系定义,可以构建出既满足当前需求又具备良好扩展性的系统架构。

五、总结与展望 🌟

设计模式的七大原则为我们的软件设计提供了宝贵的指导,帮助我们构建灵活、可维护和可扩展的系统。而UML类图作为一种可视化的建模工具,能够有效地表达系统的结构和类之间的关系,是实现良好设计的重要辅助工具。

核心价值回顾

  1. 设计模式七大原则
    • 单一职责原则:确保每个类只负责一项明确的职责
    • 开放封闭原则:对扩展开放,对修改关闭
    • 里氏替换原则:子类必须能够替换父类
    • 接口隔离原则:客户端不应依赖不需要的接口
    • 依赖倒置原则:依赖抽象而非具体实现
    • 迪米特法则:最小化类之间的耦合
    • 组合/聚合复用原则:优先使用组合而非继承
  2. UML类图价值
    • 可视化系统架构
    • 明确类间关系
    • 支持团队沟通
    • 辅助代码生成
    • 文档化系统设计

实际应用建议 📋

  1. 设计阶段
    • 先绘制UML类图规划架构
    • 应用七大原则指导类设计
    • 标注关键类和接口
  2. 开发阶段
    • 参考类图实现代码
    • 定期回顾设计是否符合原则
    • 使用工具自动生成部分代码
  3. 维护阶段
    • 通过类图快速理解系统
    • 基于类图进行重构
    • 使用类图记录变更历史

进阶实践 🚀

  1. 模式组合应用
    • 结合工厂模式+策略模式实现灵活算法
    • 使用观察者模式+模板方法实现事件驱动
    • 组合装饰器模式+代理模式增强功能
  2. 工具链集成
    • PlantUML + Maven插件实现自动化文档
    • StarUML + Git版本控制设计变更
    • ArchiMate + UML进行企业架构设计
  3. 质量保障
    • 设计评审时检查原则符合度
    • 单元测试验证接口契约
    • 静态分析工具检查耦合度

未来趋势 🔮

  1. AI辅助设计
    • 自动生成类图建议
    • 智能模式推荐
    • 设计缺陷检测
  2. 云原生适配
    • 微服务架构下的设计原则演变
    • 云原生模式库
    • 容器化设计模式
  3. 领域驱动设计(DDD)融合
    • 六边形架构与七大原则结合
    • 聚合根设计实践
    • 限界上下文划分

希望本文能够帮助你更好地理解和应用设计模式的七大原则,以及使用UML类图进行系统设计。在后续的项目中,不妨尝试将这些原则和工具融入到你的开发流程中,享受它们带来的益处。记住,优秀的设计不是一蹴而就的,而是在实践中不断迭代和完善的结果。


图标注释

  • 类名使用class关键字定义
  • 属性和方法在类内部以可见性 名称: 类型表示
  • 关系使用不同的箭头和线型表示
  • 多重性可以在连接线上使用数字或符号表示

关键词:设计模式、七大原则、单一职责原则、开放封闭原则、里氏替换原则、接口隔离原则、依赖倒置原则、组合/聚合复用原则、UML类图、系统设计、软件工程

ML类图规划架构

  • 应用七大原则指导类设计
  • 标注关键类和接口
  1. 开发阶段
    • 参考类图实现代码
    • 定期回顾设计是否符合原则
    • 使用工具自动生成部分代码
  2. 维护阶段
    • 通过类图快速理解系统
    • 基于类图进行重构
    • 使用类图记录变更历史

进阶实践 🚀

  1. 模式组合应用
    • 结合工厂模式+策略模式实现灵活算法
    • 使用观察者模式+模板方法实现事件驱动
    • 组合装饰器模式+代理模式增强功能
  2. 工具链集成
    • PlantUML + Maven插件实现自动化文档
    • StarUML + Git版本控制设计变更
    • ArchiMate + UML进行企业架构设计
  3. 质量保障
    • 设计评审时检查原则符合度
    • 单元测试验证接口契约
    • 静态分析工具检查耦合度

未来趋势 🔮

  1. AI辅助设计
    • 自动生成类图建议
    • 智能模式推荐
    • 设计缺陷检测
  2. 云原生适配
    • 微服务架构下的设计原则演变
    • 云原生模式库
    • 容器化设计模式
  3. 领域驱动设计(DDD)融合
    • 六边形架构与七大原则结合
    • 聚合根设计实践
    • 限界上下文划分

希望本文能够帮助你更好地理解和应用设计模式的七大原则,以及使用UML类图进行系统设计。在后续的项目中,不妨尝试将这些原则和工具融入到你的开发流程中,享受它们带来的益处。记住,优秀的设计不是一蹴而就的,而是在实践中不断迭代和完善的结果。


图标注释

  • 类名使用class关键字定义
  • 属性和方法在类内部以可见性 名称: 类型表示
  • 关系使用不同的箭头和线型表示
  • 多重性可以在连接线上使用数字或符号表示

关键词:设计模式、七大原则、单一职责原则、开放封闭原则、里氏替换原则、接口隔离原则、依赖倒置原则、组合/聚合复用原则、UML类图、系统设计、软件工程

版权声明:本文为原创内容,如需转载,请注明出处。

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机视觉与深度学习 | Python实现ARIMA-LSTM时间序列预测(完整源码和数据)

ARIMA-LSTM混合模型 1. 环境准备2. 数据生成(示例数据)3. 数据预处理4. ARIMA建模5. LSTM残差建模6. 混合预测7. 结果可视化完整代码说明1. **数据生成**2. **ARIMA建模**3. **LSTM残差建模**4. **混合预测**5. **性能评估**参数调优建议扩展方向典型输出以下是使用Python实现…

Docker部署单节点Elasticsearch

1.Docker部署单节点ES 1.前置条件 配置内核参数 echo "vm.max_map_count262144" >> /etc/sysctl.conf sysctl -w vm.max_map_count262144准备密码 本文所有涉及密码的配置&#xff0c;均使用通用密码 Zzwl2024。 生产环境&#xff0c;请用密码生成器生成20…

pe文件二进制解析(用c/c++解析一个二进制pe文件)

pe文件二进制解析 c解析pe文件控制台版本 #include<iostream> #include<windows.h> #include<vector>/*RVA&#xff08;相对虚拟地址&#xff09;与FOA&#xff08;文件偏移地址&#xff09;的转换1.得到 的值&#xff1a;内存地址 - ImageBase2.判断是否位…

融智学视域下的系统性认知增强框架——基于文理工三类AI助理赋能HI四阶跃迁路径

融智学视域下的系统性认知增强框架 ——基于文理工三类AI助理赋能HI四阶跃迁路径 一、如何排除50个认知偏差&#xff1a;消除50类偏差的精准矫正系统 1. 技术架构 文科AI&#xff1a; 构建文化语义场&#xff08;Cultural Semantic Field, CSF&#xff09;&#xff0c;通过…

MMDetection环境安装配置

MMDetection 支持在 Linux&#xff0c;Windows 和 macOS 上运行。它需要 Python 3.7 以上&#xff0c;CUDA 9.2 以上和 PyTorch 1.8 及其以上。 MMDetection 至今也一直更新很多个版本了&#xff0c;但是对于最新的pytorch版本仍然不支持&#xff0c;我安装的时候仍然多次遇到m…

如何实现k8s高可用

一、控制平面高可用设计 多主节点部署 • API Server 冗余&#xff1a;部署至少 3 个 Master 节点&#xff0c;每个节点运行独立的 API Server&#xff0c;通过负载均衡器&#xff08;如 Nginx、HAProxy、云厂商 LB&#xff09;对外提供统一入口。 • 选举机制&#xff1a;Sche…

记录心态和工作变化

忙中带闲的工作 其实工作挺忙的, 总是在赶各种功能点. 好巧的是iOS那边因为上架的问题耽搁了一些时间, 从而让Android的进度有了很大的调整空间. 更巧的是后端那边因为对客户端的需求不是很熟悉, 加上Android海外这块的业务他也是第一次接触. 所以需要给他留一些时间把各个环节…

JVM 双亲委派机制

一、从 JDK 到 JVM&#xff1a;Java 运行环境的基石 在 Java 开发领域&#xff0c;JDK&#xff08;Java Development Kit&#xff09;是开发者的核心工具包。它不仅包含了编译 Java 代码的工具&#xff08;如 javac&#xff09;&#xff0c;还内置了 JRE&#xff08;Java Run…

java开发之异常

一 结构 Throwable分为Exception和error Exception分为RuntimeException&#xff08;运行时异常&#xff09;和其他异常 主动抛出运行时异常和非运行时异常的区别 1、throw RuntimeException&#xff08;或运行时异常的子类&#xff09; 编译时不会报错。 2、throw Excepti…

MySQL 中 JOIN 和子查询的区别与使用场景

目录 一、JOIN:表连接1.1 INNER JOIN:内连接1.2 LEFT JOIN:左连接1.3 RIGHT JOIN:右连接1.4 FULL JOIN:全连接二、子查询:嵌套查询2.1 WHERE 子句中的子查询2.2 FROM 子句中的子查询2.3 SELECT 子句中的子查询三、JOIN 和子查询的区别3.1 功能差异3.2 性能差异3.3 使用场…

2025年第三届盘古石杯初赛(智能冰箱,监控部分)

前言 所以去哪里可以取到自己家里的智能家居数据呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; IOT物联网取证 1、分析冰箱&#xff0c;请问智能冰箱的品牌&#xff1f; [答案格式&#xff1a;xiaomi] Panasonic2、请问智能冰箱的型号&#xff1f; [答案格式&#x…

【强化学习】强化学习算法 - 马尔可夫决策过程

文章目录 马尔可夫决策过程 (Markov Decision Process, MDP)1. MDP 原理介绍2. MDP 建模/实现步骤3. MDP 示例&#xff1a;简单网格世界 (Grid World) 马尔可夫决策过程 (Markov Decision Process, MDP) 1. MDP 原理介绍 马尔可夫决策过程 (MDP) 是强化学习 (Reinforcement L…

用户现场不支持路由映射,如何快速将安防监控EasyCVR视频汇聚平台映射到公网?

一、方案背景​ 随着数字化安防与智能交通管理发展&#xff0c;视频监控远程管理需求激增。EasyCVR作为专业视频融合平台&#xff0c;具备多协议接入等核心功能&#xff0c;是智能监控的重要工具。但实际部署中&#xff0c;当EasyCVR处于内网且路由器无法进行端口映射时&#…

MODBUS RTU调试助手使用方法详解

一、软件简介 485调试助手是一款常用的串口通信调试工具&#xff0c;专门用于RS-485总线设备的测试、调试和通信监控。它支持多种串口参数设置&#xff0c;提供数据收发功能&#xff0c;是工业现场调试的必备工具之一。 二、软件安装与启动 1. 系统要求 Windows 7/10/11操作…

ECMAScript 2018(ES2018):异步编程与正则表达式的深度进化

1.版本背景与发布 发布时间&#xff1a;2018年6月&#xff0c;由ECMA International正式发布&#xff0c;标准编号为ECMA-262 9th Edition。历史意义&#xff1a;作为ES6之后的第三次年度更新&#xff0c;ES2018聚焦于异步编程、正则表达式和对象操作的标准化&#xff0c;推动…

【C语言】链接与编译(编译环境 )

前言&#xff1a; 在前面讲解文件操作&#xff0c;了解了文件的类别&#xff0c;文件的打开与关闭&#xff0c;字符读写函数&#xff0c; 字符串读写函数&#xff0c;格式化输入输出函数 在C语言编程中&#xff0c;编译与链接是将源代码转化为可执行程序的关键步骤。为了详细…

Java视频流RTMP/RTSP协议解析与实战代码

在Java中实现视频直播的输入流处理&#xff0c;通常需要结合网络编程、多媒体处理库以及流媒体协议&#xff08;如RTMP、HLS、RTSP等&#xff09;。以下是实现视频直播输入流的关键步骤和技术要点&#xff1a; 1. 视频直播输入流的核心组件 网络输入流&#xff1a;通过Socket或…

系分论文《论系统需求分析方法及应用》

系统分析师论文范文系列 【摘要】 2022年6月&#xff0c;我作为系统分析师参与了某金融机构“智能信贷风控系统”的建设项目。该系统旨在通过对业务流程的数字化重构&#xff0c;优化信贷审批效率并降低风险。项目涉及信贷申请、资质审核、风险评估、额度审批等核心流程&#x…

stack和queue简单模拟实现

stackreverse_iteratorqueuepriority_queue仿函数具体代码 stack Stacks are a type of container adaptor, specifically designed to operate in a LIFO context (last-in first-out), where elements are inserted and extracted only from one end of the container. 上述描…

Linux内核可配置的参数

sysctl -a 命令会列出当前Linux内核所有可配置的参数及其当前值。这些参数允许你在系统运行时动态地调整内核的行为&#xff0c;而无需重新编译内核或重启系统。 内容非常多&#xff0c;因为内核有很多可调的方面。我们可以把它们大致分为几个主要类别&#xff1a; kernel.*: …