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

设计模式 概述

设计模式 是在实际开发中,根据特定 解决某种问题抽象出的一套设计方案。
为了提高代码的 复用性、可维护性和扩展性
分类:创建型、结构型和行为型

常见的设计模式

创建型模式:处理对象创建机制

特点:关注如何灵活的创建对象,隐藏细节,使代码更容易扩展。

  1. 单例模式:(Singleton)
    保证一个类仅有一个实例,并且提供全局访问点。
    场景:全局配置管理(如:Config类),日志工具(Logger),数据库连接池等,避免重复创建的资源消耗大的对象。
    实现方式:私有构造函数,通过静态方法返回唯一实例(需要考虑线程安全)。

  2. 工厂模式: (Factory)

    1. 简单工厂:通过一个工厂类根据参数创建不同类型的对象.
    2. 工厂方法: 定义创建对象的接口,由子类决定具体实例化哪个对象.(如:日志工厂的FileLoggerFactory ConsoleLoggerFactory)。Spring中BeanFactory和ApplicationContext都是工厂模式,根据不同条件创建不同对象。
    3. 抽象工厂:创建一系列相关或互相依赖的对象,(如:跨平台UI库.同时创建按钮,文本框等配套组件).

    场景:对创建逻辑复杂,需要屏蔽具体实现.(如:数据库驱动选择)

  3. 建造者模式:(Builder)
    将复杂对象的构建过程与表示分离,分步构建对象(允许构建过程创建不同表示).
    场景:创建多参数,多配置的对象.
    优势:避免"telescoping constructor"(参数过多的构造函数),使代码清晰.

  4. 原型模式:(Prototype)
    通过复制现有对象(原型),创建新对象.避免重复初始化的开销.
    场景:对象创建成本高(包含大量数据的DataModel),需要动态生成相似对象时(比如克隆罗有差异的配置对象),

结构型模式: 处理类或对象的组合.

关注类,对象的组合方式,实现更灵活的结构.

  • 适配器模式:将一个类的接口转为客户端期望的另一种接口(如老系统接口适配新接口)
  • 装饰器模式:动态给对象添加额外功能,不改变原有类(在原先功能上扩展新功能)
  • 代理模式:为对象提供代理类,控制对原对象的访问(如远程代理、权限代理)与动态代理区分
    • SpringAOP使用代理模式,调用方法前校验权限,有权限才能执行。实现对服务的控制。
  • 组合模式:将对象组合成树型结构,统一处理单个对象(如文件系统的文件与文件夹)
  • 外观模式:为复杂系统提供简化接口(如智能家居总控,封装灯光,空调等子系统)

行为模式:处理对象交互

关注对象间的通信与职责分配

  • 观察者模式:定义对象间的一对多依赖,当一个对象变化时,依赖它的对象自动更新(如订阅-发布系统)
  • 策略模式:定义算法家族,封装并动态切换(如购物车根据用户等级切换不同折扣策略)。
  • 模板方法模式:父类定义算法骨架,子类实现具体步骤。
    • Spring 的JdbcTemplate 是模板方法实现。定义来操作数据库的基本流程。具体实现有子类
  • 迭代器模式:提供遍历集合元素的统一接口,不暴漏内部结构(如java中的Iterator)
  • 命令模式:将请求封装为对象,支持参数化、队列i请求(如遥控器按钮对应不同的命令)
  • 状态模式:对象状态改变时,动态切换行为(如订单状态”待支付-已支付-已发货“状态改变)

软件的设计原则

3大原则:接口功能(专一精简)、修改/扩展原则(具体可替换抽象)、类管理(避免跨类依赖)。保证”高内聚、低耦合“

1、掌握”设计原则“,设计模式是设计原则的具体体现。

  1. 单一职责原则:一个类负责单一功能。如:用户类不会应该同时处理支付类
    • 违反:
      • 类/方法臃肿,可读性差
      • 职责耦合,修改时引发连锁Bug。多职责中,修改单一职责时,容易导致其他职责受影响。
      • 复用性差,某职责 多处使用时,需要连同其他职责一同复用。
  2. 接口隔离原则:接口要小而专,避免 定义广泛。
    • 违反:
      • 接口臃肿,客户端被迫实现无关方法。
      • 接口修改影响范围过大。
  3. 开放-封闭原则:对扩展开放,对修改关闭。如:新增功能时加代码,而不是修改原码。
    • 违反:
      • 修改原有代码,引入潜在Bug。
      • 扩展性差,增加扩展成本。
      • 团队协作冲突,同时修改原有代码。
  4. 里氏替换原则:子类可以替换父类,且不破坏原有逻辑。如:正方形不应该继承长方形,因为边长逻辑冲突。
    • 违反:
      • 程序逻辑异常,出现不可预期异常。子类违背父类的语义(比如重写方法时改变输入输出规则、抛出父类未声明的异常),会导致依赖父类的代码出错。
      • 父类与子类耦合过高,难以维护。
  5. 依赖倒置原则:依赖抽象类,而不依赖具体实现。如:依赖支付接口,而不是依赖”微信/支付宝 支付“。
    • 违反:
      • 耦合度极高,扩展性差。
      • 难以单元测试,
      • 代码复用性差
  6. 迪米特法则:一个类只与直接相关类(依赖的类、成员变量的类)通信,减少耦合。如:避免A类中操作B类成员变量的成员变量。
    • 违反:
      • 耦合度高,修改影响范围大。
      • 代码可读性低,逻辑难以追寻
      • 测试难度增加。

2、理解不同设计模式,依据的设计原则。

问题场景对应模式核心作用
如何控制对象创建(单例、灵活创建)单例、工厂方法、简单工厂避免创建逻辑散落在业务代码中
如何灵活扩展对象功能(不修改原代码)装饰器、代理动态添加功能,符合 OCP
如何处理对象间的依赖 / 通信观察者、依赖注入解耦 “被依赖方” 和 “依赖方”
如何封装算法 / 行为(动态切换)策略模式避免用大量 if-else 判断算法
如何处理复杂对象的构建建造者模式分离 “对象构建” 和 “表示”(如复杂表单、对象有多个可选属性)

3、学习方法:搞懂每个模式的3个问题。

  1. 解决什么痛点?(如单例解决 “多个地方创建同一类实例导致资源浪费”);
  2. 核心结构是什么?(不用死记 UML,但要知道 “有哪些角色”,如工厂模式有 “产品接口、具体产品、工厂接口、具体工厂”);
  3. 优缺点是什么?(如单例模式线程安全实现复杂,工厂模式会增加类的数量)。

创建型模式:灵活、可控的创建对象,避免硬编码new对象导致的耦合和资源浪费。

1、单例模式
解决:多处 重复创建无状态/重量级对象(如配置管理、线程池、数据库连接池),导致内存浪费,资源竞争(如多线程下连接池重复初始化)。
确保全局只有一个实例(如全局日志器,避免多实例写日志导致文件错乱)。
核心结构
单例类:私有化构造方法(禁止外部new)、提供全局唯一获取实例的静态方法(如getInstance())、内部维护自身静态实例。
优缺点:减少内存开销,避免资源占用,全局同一访问点,状态易管理。
违背单一职责,线程安全实现复杂(双重检查锁),难以扩展(私有构造器)测试困难。

2、工厂方法
解决:
避免直接new具体对象,导致的耦合。
解决简单工厂模式下的扩展性问题。(简单工厂新增产品需要修改工厂类)
核心结构:4个核心角色
工厂接口:定义创建产品的抽象方法。
具体工厂:实现工厂接口,创建具体的产品。
产品接口:定义所有产品的统一行为。(仅定义单一产品如华为手机)
具体产品:实现产品接口的具体类。
优缺点:
符合开闭原则。代码解耦。
类数量较多,结构复杂,仅适用单一产品族(具体产品实现仅支持单一类)。

3、抽象工厂类
解决:
工厂方法模式只能创建单一产品的问题,指出创建产品族。(如华为手机+华为电脑 同一品牌下的不同产品)
避免产品族中产品不兼容(如华为工厂创建的手机和电脑,天然适配华为)
核心:
抽象产品接口:按产品类别拆分(如phone,computer,包含自身行为)
具体产品:实现抽象产品接口(华为phone、华为Computer、Iphone、IComputer)
抽象工厂接口:定义创建“产品族内所有产品”的方法(如AbstractFactory,含createPhone()、createComputer());
具体工厂:实现抽象工厂,创建对应产品族的所有产品(如HuaweiFactory创建HuaweiPhone+HuaweiComputer,AppleFactory创建IPhone+IComputer)。

优缺点:
保证产品族内产品的兼容性(同一工厂造的产品天然适配)。符合开闭原则。解耦产品。
扩展不易(需要扩展工厂),类数量多。

4、建造者模式
解决:
避免负责对象构造参数过多,导致代码混乱(如创建User对象需要10个参数,导致冗余)
分离“对象构造”和对象表示“
核心:
产品:需要构建的复杂对象
抽象建造者:定义构建产品各组件的抽象方法,
具体建造者:实现抽象建造者,完成具体组件的构建。
指挥者(可选):控制建造流程(如Director,调用建造者的方法按顺序组装,避免调用方关注步骤)。
优缺点:
分步构建复杂对象,参数清晰。统一建造者可生成不同产品。解耦构建过程。
只适用于复杂对象,类数量增多。构造流程变更时,需要修改Builder或指挥者(可能违背开闭)。


文章转载自:

http://UrXKYiAh.hdbyn.cn
http://1wt1gy8L.hdbyn.cn
http://CP3Yi6Cb.hdbyn.cn
http://Bt4Edesf.hdbyn.cn
http://yszqQGw5.hdbyn.cn
http://sgBSuVNh.hdbyn.cn
http://g6nVRW34.hdbyn.cn
http://Fo5V6Muc.hdbyn.cn
http://sA8b3v5W.hdbyn.cn
http://PdQbdO9U.hdbyn.cn
http://I8cgQrRT.hdbyn.cn
http://Q1n7KY2e.hdbyn.cn
http://mznDkeCi.hdbyn.cn
http://tWtUWgVt.hdbyn.cn
http://ZHNAUX3w.hdbyn.cn
http://JB9kLyOF.hdbyn.cn
http://i4fY5d3W.hdbyn.cn
http://9ncaixmk.hdbyn.cn
http://9Hpwbj6q.hdbyn.cn
http://1ymV6pEv.hdbyn.cn
http://JFRocPqa.hdbyn.cn
http://yLjmncdU.hdbyn.cn
http://r4EOpp3l.hdbyn.cn
http://ok9u3Tiq.hdbyn.cn
http://CpNvTBPJ.hdbyn.cn
http://zm2cJ9uY.hdbyn.cn
http://zFIq6Tjm.hdbyn.cn
http://8ttIS4YC.hdbyn.cn
http://HhltKR5g.hdbyn.cn
http://fTuTlrp4.hdbyn.cn
http://www.dtcms.com/a/373997.html

相关文章:

  • SQL 注入与防御-第九章:平台层防御
  • SCADA与DCS深度集成实践:打破工厂“信息孤岛”,让实时控制更智能
  • 小学挫折教育主题班会PPT课件模板下载
  • 深入理解 MyBatis-Plus 的 `BaseMapper`
  • YOLOv8 TensorRT C++部署实战详解:从XMake构建到推理流水线
  • HTML HTML基础(3)
  • 几何动点问题
  • C++从字符串中移除前导零
  • PPP PRIVATE NETWORK™ 2 企业级虚拟以太网接入综合解决方案介绍
  • 《会“偷听”的石头:声流石的震撼发现》
  • 线程的控制(互斥+同步)
  • SpringBoot中添加健康检查服务
  • Android 开发 - 一些画板第三方库(DrawBoard、FingerPaintView、PaletteLib)
  • Skopeo 工具介绍与 CentOS 7 安装指南
  • 面向对象设计原则(未完)
  • Python数据挖掘实战:从理论到工具
  • Highcharts 数据源安全最佳实践:保障数据安全,助力可视化可信部署
  • 网易有道-虚拟人口语教练
  • git config user.name “xxx“命名报错fatal: not in a git directory
  • 【Flask】测试平台开发,工具模块开发 第二十二篇
  • 【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
  • 2025最新超详细FreeRTOS入门教程:第七章 FreeRTOS事件组
  • 【nest.js】创建一个上传api
  • C语言内存精讲系列(八):深化详述 int 3
  • 蓓韵安禧DHA为孕期安全营养补充提供科学支持,呵护母婴健康
  • 什么是状态(State)以及如何在React中管理状态?
  • Anaconda与Jupyter 安装和使用
  • 房屋安全鉴定需要什么条件
  • 全国产压力传感器选型指南/选型手册
  • 时间比较算法(SMART PLC梯形图示例)