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

044_设计模式入门(创建型 / 结构型 / 行为型)

设计模式(Design Pattern)是面向对象编程中对重复出现的问题的标准化解决方案,由 GoF(Gang of Four)总结为 23 种经典模式。这些模式基于封装、继承、多态三大特性,旨在提高代码的可复用性、可维护性和灵活性。根据解决问题的类型,设计模式可分为三大类:创建型模式(对象创建)结构型模式(类 / 对象组合)行为型模式(对象交互)

一、设计模式概述

1.1 设计模式的核心价值

设计模式不是现成代码,而是通用设计思路,主要解决:

  • 代码复用:避免重复编写相似逻辑。
  • 解耦:降低类与类之间的依赖(高内聚、低耦合)。
  • 扩展性:新增功能时无需修改原有代码(符合开闭原则)。
  • 可读性:使用公认的模式使代码更易理解(如 “单例” 一看就知道是唯一实例)。

1.2 三大类模式的划分标准

  • 创建型模式:聚焦 “对象如何创建”,隐藏创建细节(如实例化逻辑)。
  • 结构型模式:聚焦 “类或对象如何组合”,实现更灵活的结构(如适配接口、动态扩展功能)。
  • 行为型模式:聚焦 “对象如何交互”,规范职责分配与通信方式(如通知机制、算法切换)。

在这里插入图片描述

二、创建型模式(Creational Patterns)

创建型模式专注于对象的创建过程,通过封装创建逻辑,使代码不依赖具体类,从而应对需求变化(如更换产品类型)。常见的 5 种创建型模式如下:

2.1 单例模式(Singleton Pattern)

核心意图
确保一个类只有一个实例,并提供全局唯一访问点。

解决的问题
避免重复创建资源密集型对象(如数据库连接池、配置管理器),节省资源。

关键实现

  • 私有构造器(禁止外部new实例)。
  • 静态私有实例(存储唯一实例)。
  • 静态公有方法(返回实例,控制创建逻辑)。

简单示例(懒汉式)

public class ConfigManager {// 静态私有实例(懒加载:使用时才创建)private static ConfigManager instance;// 私有构造器:禁止外部创建private ConfigManager() {}// 全局访问点public static ConfigManager getInstance() {if (instance == null) {instance = new ConfigManager(); // 首次调用时初始化}return instance;}
}

适用场景

  • 全局配置、线程池、日志工厂等 “单一资源” 场景。

2.2 工厂方法模式(Factory Method Pattern)

核心意图
定义创建对象的接口,但由子类决定实例化哪个类(将创建逻辑延迟到子类)。

解决的问题
避免代码中直接new具体类(如new MySQLDao()),减少对具体实现的依赖(如更换数据库时无需修改调用代码)。

关键实现

  • 抽象工厂接口(定义创建方法)。
  • 具体工厂类(实现创建方法,返回具体产品)。
  • 产品接口(约束产品功能)。

简单示例

// 产品接口
public interface Logger {void log(String message);
}// 具体产品:文件日志
public class FileLogger implements Logger {@Overridepublic void log(String message) {System.out.println("文件日志:" + message);}
}// 工厂接口
public interface LoggerFactory {Logger createLogger();
}// 具体工厂:创建文件日志
public class FileLoggerFactory implements LoggerFactory {@Overridepublic Logger createLogger() {return new FileLogger(); // 实例化具体产品}
}// 使用:依赖工厂接口,不依赖具体产品
public class Client {public static void main(String[] args) {LoggerFactory factory = new FileLoggerFactory();Logger logger = factory.createLogger(); // 无需直接new FileLoggerlogger.log("系统启动");}
}

适用场景
产品种类较多且可能扩展(如日志系统支持文件日志、数据库日志)。

2.3 建造者模式(Builder Pattern)

核心意图
复杂对象的构建过程与表示分离,使同一构建过程可创建不同产品(如 “电脑” 可由不同 CPU、内存组合而成)。

解决的问题
复杂对象的创建步骤繁琐(如 “用户” 对象需设置姓名、年龄、地址等多个属性,参数多且可选)。

关键实现

  • 产品类(复杂对象,如Computer)。
  • 建造者类(封装构建步骤,提供链式设置方法)。
  • director(可选,负责控制构建流程)。

简单示例

// 产品:电脑(复杂对象)
public class Computer {private String cpu;private String memory;private String disk;// 私有构造器:仅允许Builder创建private Computer(Builder builder) {this.cpu = builder.cpu;this.memory = builder.memory;this.disk = builder.disk;}// 建造者类:负责构建Computerpublic static class Builder {private String cpu;private String memory;private String disk;// 链式设置属性(返回Builder自身)public Builder cpu(String cpu) {this.cpu = cpu;return this;}public Builder memory(String memory) {this.memory = memory;return this;}public Builder disk(String disk) {this.disk = disk;return this;}// 构建产品public Computer build() {return new Computer(this);}}
}// 使用:链式调用,清晰可控
Computer pc = new Computer.Builder().cpu("Intel i9").memory("32GB").disk("1TB SSD").build();

适用场景

  • 复杂对象创建(如订单、用户信息、配置对象等包含多个可选属性)。

2.4 其他创建型模式简介

  • 抽象工厂模式:创建 “产品族”(如 Windows 系统的按钮 + 文本框,Mac 系统的按钮 + 文本框),支持多套产品组合。
  • 原型模式:通过复制现有对象创建新对象(如大对象复制比重新初始化更高效),实现Cloneable接口。

在这里插入图片描述

三、结构型模式(Structural Patterns)

结构型模式专注于类或对象的组合方式,通过灵活组合实现功能扩展或接口适配,使系统结构更稳定。常见的 7 种结构型模式如下:

3.1 适配器模式(Adapter Pattern)

核心意图
将一个类的接口转换为客户端期望的另一个接口,使接口不兼容的类可协同工作(类似 “转接头”)。

解决的问题
旧系统接口与新系统不匹配(如旧接口有getOldData(),新系统需要getData())。

关键实现

  • 目标接口(客户端需要的接口)。
  • 适配器类(实现目标接口,内部调用被适配者的方法)。

简单示例(类适配器)

// 目标接口(新系统需要的接口)
public interface NewInterface {void newMethod();
}// 被适配者(旧系统接口)
public class OldClass {public void oldMethod() {System.out.println("调用旧系统方法");}
}// 适配器:连接新接口与旧类
public class Adapter extends OldClass implements NewInterface {@Overridepublic void newMethod() {super.oldMethod(); // 适配:调用旧方法实现新接口}
}// 使用:客户端调用新接口,适配旧实现
NewInterface adapter = new Adapter();
adapter.newMethod(); // 输出“调用旧系统方法”

适用场景

  • 系统升级时兼容旧模块、集成第三方组件(接口不符)。

3.2 装饰器模式(Decorator Pattern)

核心意图
动态地给对象添加额外功能,且不改变其原有结构(如给咖啡加奶、加糖)。

解决的问题
避免通过继承扩展功能导致的类爆炸(如咖啡 + 奶、咖啡 + 糖、咖啡 + 奶 + 糖,继承需 3 个子类,装饰器只需 2 个装饰类)。

关键实现

  • 抽象组件(如Coffee)。
  • 具体组件(如BlackCoffee)。
  • 装饰器类(实现组件接口,持有组件实例,添加新功能)。

简单示例

// 抽象组件:咖啡
public interface Coffee {String getDesc(); // 描述double cost();    // 价格
}// 具体组件:黑咖啡
public class BlackCoffee implements Coffee {@Overridepublic String getDesc() { return "黑咖啡"; }@Overridepublic double cost() { return 15; }
}// 装饰器抽象类
public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee; // 持有被装饰的咖啡public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; }
}// 具体装饰器:加奶
public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) { super(coffee); }@Overridepublic String getDesc() { return coffee.getDesc() + "+牛奶"; }@Overridepublic double cost() { return coffee.cost() + 5; } // 加价5元
}// 使用:动态叠加功能
Coffee drink = new BlackCoffee();
drink = new MilkDecorator(drink); // 加奶
drink = new SugarDecorator(drink); // 加糖
System.out.println(drink.getDesc()); // 黑咖啡+牛奶+糖
System.out.println(drink.cost());    // 15+5+3=23

适用场景
动态扩展功能(如 IO 流中的BufferedInputStream给FileInputStream添加缓冲功能)。

3.3 代理模式(Proxy Pattern)

核心意图
为对象提供代理对象,控制对原对象的访问(如权限校验、日志记录、延迟加载)。

解决的问题
需在访问对象前后添加额外操作(如调用方法前检查权限,调用后记录日志)。

关键实现

  • 目标接口(代理与原对象实现同一接口)。
  • 代理类(持有目标对象,在调用目标方法前后添加逻辑)。

简单示例(静态代理)

// 目标接口
public interface Image {void display();
}// 真实对象(高清图片,加载耗时)
public class RealImage implements Image {private String path;public RealImage(String path) {this.path = path;loadFromDisk(); // 初始化耗时}private void loadFromDisk() {System.out.println("加载图片:" + path);}@Overridepublic void display() {System.out.println("显示图片:" + path);}
}// 代理对象(控制访问,实现延迟加载)
public class ImageProxy implements Image {private RealImage realImage;private String path;public ImageProxy(String path) { this.path = path; }@Overridepublic void display() {// 延迟加载:仅在需要时创建真实对象if (realImage == null) {realImage = new RealImage(path);}realImage.display(); // 调用真实对象方法}
}// 使用:通过代理访问,优化性能
Image img = new ImageProxy("photo.png");
// 此时未加载图片,直到调用display()才触发加载
img.display();

适用场景

  • 延迟加载(大对象)、权限控制、日志记录、远程服务代理(如 RPC 框架)。

3.4 其他结构型模式简介

  • 装饰器模式:动态给对象添加功能(功能叠加,如咖啡加奶加糖)。
  • 外观模式:为复杂子系统提供统一入口(如电脑启动:简化 CPU、内存、硬盘的启动步骤)。
  • 桥接模式:分离抽象与实现(如形状与颜色:圆形 + 红色、方形 + 蓝色,两者可独立扩展)。

四、行为型模式(Behavioral Patterns)

行为型模式专注于对象间的交互与职责分配,使对象协作更清晰、可扩展。常见的 11 种行为型模式如下:

4.1 策略模式(Strategy Pattern)

核心意图
定义一系列算法,封装每个算法,并使它们可互换(如不同支付方式、排序算法)。

解决的问题
避免用if-else硬编码多种算法(如支付系统:微信 / 支付宝 / 银行卡支付,新增支付方式需改原有代码)。

关键实现

  • 策略接口(定义算法统一方法)。
  • 具体策略类(实现接口,封装不同算法)。
  • 上下文类(持有策略对象,调用策略方法)。

简单示例

// 策略接口(支付算法)
public interface PaymentStrategy {void pay(double amount);
}// 具体策略1:微信支付
public class WechatPay implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("微信支付:" + amount + "元");}
}// 具体策略2:支付宝支付
public class Alipay implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("支付宝支付:" + amount + "元");}
}// 上下文类(使用策略)
public class Order {private PaymentStrategy payment;// 设置策略(动态切换)public void setPayment(PaymentStrategy payment) {this.payment = payment;}public void checkout(double amount) {payment.pay(amount); // 调用策略方法}
}// 使用:动态切换算法,无需修改Order类
Order order = new Order();
order.setPayment(new WechatPay()); // 微信支付
order.checkout(200);order.setPayment(new Alipay());    // 切换为支付宝
order.checkout(300);

适用场景

  • 多种算法可选且需动态切换(如排序算法、支付方式、折扣策略)。

4.2 观察者模式(Observer Pattern)

核心意图
定义对象间的一对多依赖,当一个对象状态变化时,所有依赖它的对象自动收到通知(如公众号与订阅者)。

解决的问题
对象间联动通信(如订单状态更新后,需通知库存系统、日志系统、消息推送系统)。

关键实现

  • 主题接口(被观察者,提供注册、移除、通知观察者的方法)。
  • 观察者接口(定义接收通知的方法)。
  • 具体主题(维护观察者列表,状态变化时通知所有观察者)。

简单示例

// 观察者接口
public interface Observer {void update(String message); // 接收通知
}// 主题接口(被观察者)
public interface Subject {void register(Observer observer);   // 注册观察者void remove(Observer observer);     // 移除观察者void notifyObservers(String msg);   // 通知所有观察者
}// 具体主题:公众号
public class WechatSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void register(Observer observer) {observers.add(observer);}@Overridepublic void remove(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(String msg) {// 通知所有订阅者for (Observer o : observers) {o.update(msg);}}// 发布文章(状态变化)public void publish(String article) {notifyObservers("新文章:" + article);}
}// 具体观察者:用户
public class User implements Observer {private String name;public User(String name) { this.name = name; }@Overridepublic void update(String message) {System.out.println(name + "收到:" + message);}
}// 使用:订阅与通知
WechatSubject subject = new WechatSubject();
Observer user1 = new User("张三");
Observer user2 = new User("李四");subject.register(user1);
subject.register(user2);
subject.publish("《设计模式入门》"); // 所有用户收到通知

适用场景

  • 事件监听(如 GUI 按钮点击)、消息通知(订单状态、库存变更)、实时数据更新(股票行情)。

4.3 其他行为型模式简介

  • 模板方法模式:定义算法骨架(如做菜步骤:备菜→烹饪→装盘),子类实现具体步骤。
  • 责任链模式:请求沿处理者链条传递(如请假审批:组长→经理→总监),直到被处理。
  • 迭代器模式:统一遍历聚合对象(如List的iterator()),隐藏内部结构。

在这里插入图片描述

五、设计模式的选择与实践建议

  1. 不盲目套用:模式是工具,需根据场景选择(如简单对象无需用建造者模式)。
  2. 优先掌握核心模式:创建型(单例、工厂方法)、结构型(适配器、代理)、行为型(策略、观察者)是高频使用模式。
  3. 理解而非记代码:掌握模式的 “意图” 和 “解决的问题”,而非死记代码实现(同一模式可有多种写法)。
  4. 从小处实践:在日常开发中尝试用模式重构代码(如用单例管理配置,用策略模式处理多规则逻辑)。

六、总结

设计模式是面向对象编程的 “成熟经验”,三大类模式各有侧重:

  • 创建型:控制对象创建,解耦创建与使用。
  • 结构型:优化类 / 对象组合,实现灵活扩展。
  • 行为型:规范对象交互,使协作更清晰。

入门阶段无需掌握所有 23 种模式,重点理解核心模式的意图和适用场景,逐步在实践中体会其价值。记住:好的模式是 “自然而然” 解决问题的,而非刻意套用

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

相关文章:

  • 【解决方案】鸿蒙 / 矿鸿系统 Shell 无故退出问题(息屏导致)详解
  • Spatial Frequency Modulation for Semantic Segmentation。针对图像下采样造成信息丢失问题的解决思路
  • 深入理解 Spring Boot Starter 的生成机制
  • tcp/udp调试工具
  • Linux内核网络栈深度剖析:inet_connection_sock.c的服务器端套接字管理
  • LINUX例行性工作(计划任务)实验操作 ---at和crontab以及系统级别的计划任务
  • springboot跨域问题 和 401
  • 当下主流摄像头及其核心参数详解
  • 不同场景下git指令的搭配
  • pycharm回车、删除、方向键和快捷键等不能使用原因
  • TRAE Agent 在 SWE-bench Verified 上得分 75.2%,并已开源
  • opencv、torch、torchvision、tensorflow的区别
  • Linux717 SWAP扩容;逻辑卷条带化
  • 前端-HTML
  • 杰理AC70NN项目用脚本自定义添加.mk文件,直接链接进主Makefile脚本编译
  • 开通腾讯位置复位
  • 深入理解Collections.addAll方法
  • 【华为】交换机vlan互访实验
  • 【人工智能99问】梯度消失、梯度爆炸的定义、后果及规避手段?(7/99)
  • JAVA面试宝典 -《Kafka 高吞吐量架构实战:原理解析与性能优化全攻略》
  • UE5多人MOBA+GAS 25、创建数据表初始化属性,使用MMC计算伤害
  • 模块化社交新范式:Moments用极简设计重构数字表达
  • 麒麟信安参编的三项软件供应链安全团体标准发布
  • 运维工程师面试题174道
  • 单片机最小系统硬件调试踩的一些坑
  • lesson16:Python函数的认识
  • Linux手动安装Nginx(基于Centos 7)
  • ESLint 完整功能介绍和完整使用示例演示
  • 01项目管理概论
  • Shell变量