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

常见的几种设计模式(详细)——应用场景和实现方式

文章目录

  • 🎯单例模式
    • 应用
    • 实现
  • 🏭工厂模式
    • 应用
    • 实现
  • ❓策略模式
    • 应用
    • 实现
  • 🧑‍⚖️代理模式
    • 应用
    • 实现
  • 🔍观察者模式(发布订阅模式)
    • 应用
    • 实现
  • 🧰装饰器模式
    • 应用
    • 实现
  • 📰模版方法模式
    • 应用
    • 实现
  • ⛓️责任链模式
    • 应用
    • 实现

🎯单例模式

整个程序运行过程中,类只有一个实例,减少内存消耗

应用

  1. 资源管理:需要共享的资源如数据库连接池线程池等,确保只有一个实例管理这些资源
  2. 全局配置:配置类
  3. 日志记录器:在多线程或分布式环境中确保日志记录器唯一性

实现

实现时注意:

  1. 构造器私有化,防止篡改
  2. 只暴露一个公共的获取实例的方法
  3. 是否线程安全
  1. 饿汉式:线程安全,类加载的时候就实例化

    public class Singleton{private static final Singleton instance = new Singleton();private Singleton(){}public static Singleton getInstance(){return instance;}
    }
    
  2. 懒汉式:线程不安全,使用到时再实例化

    public class Singleton{private static Singleton instance ;private Singleton(){}public static Singleton getInstance(){if(instance == null){instance = new Singleton();}return instance;}
    }
    
  3. 双重检查锁:懒汉式的优化,线程安全(使用volatile防止指令重排序)

    public class Singleton{private static volatile Singleton instance; //使用volatile防止指针重排序private Singleton(){}public static Singleton getInstance(){if(instance == null){  //第一次检查synchronized(Singleton.class){if(instance == null){  //第二次检查,保证线程安全instance = new Singleton();}}}}
    }
    
  4. 静态内部类:利用类加载机制实现懒加载和线程安全

    public class Singleton {private Singleton() {}private static class Holder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return Holder.INSTANCE;}
    }
  5. 枚举单例:简单且防止反射和序列化攻击

    public enum Singleton{INSTANCE;
    }Singleton instance = Singleton.INSTANCE;
    

防止反射入侵:在构造器中添加一个判断,如果对象存在,则抛出异常

序列化和反序列化安全:添加一个readResolve()方法,在进行反序列化时会执行readResolve()方法,确保只有一个实例存在

🏭工厂模式

封装对象的创建逻辑,减低耦合

应用

动态创建不同类型的对象

实现

产品接口、产品实现类、工厂类

// 产品接口
public interface Product {void use();
}// 具体产品A
public class ConcreteProductA implements Product {@Overridepublic void use() {System.out.println("Using ConcreteProductA");}
}// 具体产品B
public class ConcreteProductB implements Product {@Overridepublic void use() {System.out.println("Using ConcreteProductB");}
}// 简单工厂类
public class SimpleFactory {public static Product createProduct(String type) {switch (type) {case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new IllegalArgumentException("Unknown product type");}}
}// 客户端代码
public class Client {public static void main(String[] args) {Product productA = SimpleFactory.createProduct("A");productA.use(); // Output: Using ConcreteProductAProduct productB = SimpleFactory.createProduct("B");productB.use(); // Output: Using ConcreteProductB}
}

❓策略模式

封装不同的算法,允许运行时选择不同的策略

应用

同一个业务使用不同的策略

  1. 支付系统
  2. 数据压缩
  3. 日志策略

实现

策略接口、策略实现类(不同策略)、上下文类

// 策略接口
interface Strategy {void execute();
}// 具体策略A
class ConcreteStrategyA implements Strategy {@Overridepublic void execute() {System.out.println("Executing Strategy A");}
}// 具体策略B
class ConcreteStrategyB implements Strategy {@Overridepublic void execute() {System.out.println("Executing Strategy B");}
}// 上下文类
class Context {private Strategy strategy;public void setStrategy(Strategy strategy) {this.strategy = strategy;}public void executeStrategy() {if (strategy != null) {strategy.execute();} else {System.out.println("No strategy set");}}
}// 客户端
public class Main {public static void main(String[] args) {Context context = new Context();Strategy strategyA = new ConcreteStrategyA();Strategy strategyB = new ConcreteStrategyB();context.setStrategy(strategyA);context.executeStrategy(); // Output: Executing Strategy Acontext.setStrategy(strategyB);context.executeStrategy(); // Output: Executing Strategy B}
}

🧑‍⚖️代理模式

代理对象控制对目标对象的访问

应用

在不修改原来代码的基础上,实现对目标对象的控制和管理

  1. 权限验证
  2. 性能优化:通过代理实现缓存或延迟加载以提高系统性能
  3. 远程访问:客户端访问远程对象时,通过代理封装远程调用细节
  4. 日志记录:在方法调用时添加日志记录功能

实现

接口、实现类、代理类(静态代理)

public interface Subject{void request();
}public RealSubject implements Subject{@Overridepublic void request(){System.out.println("RealSubject request");}
}public class Proxy implements Subject{private RealSubject realSubject;@Overridepublic void request(){if(realSubject == null)realSubject = new RealSubject();System.out.println("before");realSubject.request();System.out.println("after");}
}public class Main{public static void main(String[] args){Subject proxy = new Proxy();proxy.request();}
}

🔍观察者模式(发布订阅模式)

一个对象状态变化时,依赖它的对象会收到通知

应用

  1. 事件驱动系统:用户操作界面,通过监听事件触发响应
  2. 系统间通信:某个模块发生变化,通知多个依赖模块
  3. 订阅:数据更新,通知所有订阅者(推送通知)

实现

观察者接口、被观察者接口、观察者类、被观察者类

// 观察者接口
interface Observer {void update(String message);
}// 被观察者接口
interface Subject {void addObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}// 具体被观察者
class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();private String state;@Overridepublic void addObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(state);}}public void setState(String state) {this.state = state;notifyObservers();}
}// 具体观察者
class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " received update: " + message);}
}// 客户端
public class Main {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();Observer observer1 = new ConcreteObserver("Observer1");Observer observer2 = new ConcreteObserver("Observer2");subject.addObserver(observer1);subject.addObserver(observer2);subject.setState("New State 1");subject.setState("New State 2");}
}

🧰装饰器模式

不改变原始类,在其基础上动态扩展功能

应用

  1. 动态扩展功能:对现有对象添加功能,但不希望通过继承方式
  2. 不同功能的组合
  3. 透明扩展:客户端无需了解对象是否被装饰过

实现

组件接口、具体组件实现类、装饰器抽象类、具体装饰器

// 组件接口
interface Component {void operation();
}// 具体组件
class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("ConcreteComponent operation");}
}// 装饰器抽象类
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 具体装饰器A
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation();System.out.println("ConcreteDecoratorA added behavior");}
}// 具体装饰器B
class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {super.operation();System.out.println("ConcreteDecoratorB added behavior");}
}// 客户端
public class Main {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratorA = new ConcreteDecoratorA(component);Component decoratorB = new ConcreteDecoratorB(decoratorA);decoratorB.operation();// Output:// ConcreteComponent operation// ConcreteDecoratorA added behavior// ConcreteDecoratorB added behavior}
}

📰模版方法模式

定义一个逻辑框架,把具体的实现留给子类

应用

  1. 定义算法骨架
  2. 复用公共逻辑

例:抽象类、继承抽象类

​ 不同支付渠道的流程都是一样的,包括:前置的参数检查、核心支付逻辑、后置的检查等,可以抽象成一个模版方法(抽象类),不同支付渠道的实现类继承它,并实现支付逻辑。

实现

抽象类、继承抽象类

// 抽象类
abstract class DataProcessor {// 模板方法public final void process() {readData();processData();writeData();}protected abstract void readData(); // 读取数据protected abstract void processData(); // 处理数据protected void writeData() { // 写入数据System.out.println("Writing data to output.");}
}// 具体实现类A
class CSVDataProcessor extends DataProcessor {@Overrideprotected void readData() {System.out.println("Reading data from CSV file.");}@Overrideprotected void processData() {System.out.println("Processing CSV data.");}
}// 具体实现类B
class JSONDataProcessor extends DataProcessor {@Overrideprotected void readData() {System.out.println("Reading data from JSON file.");}@Overrideprotected void processData() {System.out.println("Processing JSON data.");}
}// 客户端
public class Main {public static void main(String[] args) {DataProcessor csvProcessor = new CSVDataProcessor();csvProcessor.process();DataProcessor jsonProcessor = new JSONDataProcessor();jsonProcessor.process();}
}

⛓️责任链模式

将多个对象连接成一条链,沿着这条链传递请求,让每个对象都有机会处理请求,请求会顺着链传递,直到某个对象可以处理。

应用

不同级别处理

  1. 审批流程
  2. 日志系统(不同级别的日志记录)

实现

抽象类、继承抽象类

// 处理器接口
abstract class Handler {protected Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}public abstract void handleRequest(String request);
}// 具体处理器A
class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if ("A".equals(request)) {System.out.println("ConcreteHandlerA handled request: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);} else {System.out.println("No handler for request: " + request);}}
}// 具体处理器B
class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if ("B".equals(request)) {System.out.println("ConcreteHandlerB handled request: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);} else {System.out.println("No handler for request: " + request);}}
}// 客户端
public class Main {public static void main(String[] args) {Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();handlerA.setNextHandler(handlerB);handlerA.handleRequest("A"); // Output: ConcreteHandlerA handled request: AhandlerA.handleRequest("B"); // Output: ConcreteHandlerB handled request: BhandlerA.handleRequest("C"); // Output: No handler for request: C}
}

相关文章:

常见的几种设计模式(详细)——应用场景和实现方式

文章目录 &#x1f3af;单例模式应用实现 &#x1f3ed;工厂模式应用实现 ❓策略模式应用实现 &#x1f9d1;‍⚖️代理模式应用实现 &#x1f50d;观察者模式&#xff08;发布订阅模式&#xff09;应用实现 &#x1f9f0;装饰器模式应用实现 &#x1f4f0;模版方法模式应用实现…...

SonarQube

不同版本的sonarqube需要不同版本的数据库、jdk环境。这个看文档然后确定要求 &#xff08;有时候文档里标注的系统要求是不行的。比如要求内存2G&#xff0c;但是实际上是不够的&#xff0c;要注意&#xff09; 我安装的&#xff1a; 官方文档 Prerequisites and overview…...

Nginx 之Rewrite 使用详解

文章目录 1. 概述2. Rewrite 指令 2.1 指令语法2.2 Flag 标记说明 3. Rewrite 与 Location 3.1 Location 分类3.2 Rewrite 和 Location 比较 4. Rewrite 实际场景 4.1 基于域名的跳转4.2 基于客户端 IP 访问跳转4.3 基于参数匹配的跳转4.4 基于目录下所有 PHP 文件跳转4.5 基于…...

注册Gmail如何跳过手机验证环节?

很多小伙伴在注册Gmail的时候都会遇到一个难题&#xff1a;手机号码验证&#xff0c;有可能包括了“手机号无法验证” “国内手机号验证失败” “收不到验证码”等等问题&#xff0c;但 根据真实案例&#xff0c;还有部分人则是“幸运地”没有手机号验证环节&#xff0c;那么今…...

WordPress自助建站全攻略

一、基础概念与核心优势 WordPress自助建站是一种无需编程即可搭建网站的平台&#xff0c;基于开源CMS系统&#xff0c;支持高度定制化。其核心优势主要体现在&#xff1a; 易用性&#xff1a;拖拽式编辑器和直观的后台操作&#xff0c;适合零基础用户快速上手。低成本&#x…...

TreeSet(单列集合)

TreeSet 是 Java 集合框架中的一种实现了 Set 接口的类&#xff0c;它通过一个红黑树&#xff08;Red-Black Tree&#xff09;来存储元素。由于使用了树结构&#xff0c;TreeSet 保证了元素的有序性&#xff0c;并且不允许重复元素。 1. TreeSet 的基本特性 有序性&#xff1…...

Elasticsearch:同义词在 RAG 中重要吗?

作者&#xff1a;来自 Elastic Jeffrey Rengifo 及 Toms Mura 探索 RAG 应用程序中 Elasticsearch 同义词的功能。 同义词允许我们使用具有相同含义的不同词语在文档中搜索&#xff0c;以确保用户无论使用什么确切的词语都能找到他们所寻找的内容。你可能会认为&#xff0c;由于…...

Docker安装分布式vLLM

Docker安装分布式vLLM 1 介绍 vLLM是一个快速且易于使用的LLM推理和服务库&#xff0c;适合用于生产环境。单主机部署会遇到显存不足的问题&#xff0c;因此需要分布式部署。 分布式安装方法 https://docs.vllm.ai/en/latest/serving/distributed_serving.html2 安装方法 …...

可视化实操记录(自用)

流程 读取数据 original_data pd.read_csv(“Penguins.csv”) original_data.head() 评估和清理数据 cleaned_data original_data.copy() #备份 结构 original_data.sample(5) 数据符合“每个变量为一列&#xff0c;每个观察值为一行&#xff0c;每种类型的观察单位为一…...

二叉树的遍历方式和子问题思路

目录 二叉树的遍历&#xff1a; 前序遍历&#xff1a; 中序遍历&#xff1a; 后序遍历&#xff1a; 二叉树的基本操作&#xff1a; 求树的结点个数&#xff08;递归遍历思路&#xff09;&#xff1a; 求树的结点个数&#xff08;子问题思路&#xff09;&#xff1a; 求树的…...

运用Deek Seeker协助数据分析

我的数据源有两张表&#xff0c;一个是每日销售表(字段有日期、产品名称、实际销量)&#xff0c;一个是每月目标表(字段有年度月份、产品名称、目标销量);我的需求是&#xff0c;按月、按年来统计每个产品的目标完成情况请问用PowerBl进行分析&#xff0c;应该如何建立数据模型…...

服务器之连接简介(Detailed Explanation of Server Connection)

一台服务器最大能支持多少连接&#xff1f;一台客户端机器最多能发起多少条连接&#xff1f;&#xff1f; 我们知道TCP连接&#xff0c;从根本上看其实就是client和server端在内存中维护的一组【socket内核对象】&#xff08;这里也对应着TCP四元组&#xff1a;源IP、源端口、…...

低空经济:开启未来空中生活的全新蓝海

引言 随着科技的进步&#xff0c;我们不再仅仅依赖地面交通和传统物流。你是否曾幻想过&#xff0c;未来的某一天&#xff0c;快递、外卖可以像魔法一样直接从空中送到你手中&#xff1f;或者&#xff0c;你能乘坐小型飞行器&#xff0c;快速穿梭于城市之间&#xff0c;告别拥堵…...

主动视觉可能就是你所需要的:在双臂机器人操作中探索主动视觉

AV-ALOHA 系统使用用于 AV 的 VR 耳机实现直观的数据收集&#xff0c;并且 用于作的 VR 控制器或引线臂。这有助于捕捉全身和头部 远程作我们的真实和模拟系统的运动&#xff0c;记录来自 6 个的视频 不同的摄像头&#xff0c;并为我们的 AV 仿制学习策略提供训练数据。 加州大…...

洛谷 P6419 COCI2014/2015 #1 Kamp 题解

题意 一颗树 n n n 个点&#xff0c; n − 1 n-1 n−1 条边&#xff0c;经过每条边都要花费一定的时间&#xff0c;任意两个点都是联通的。 有 k k k 个人&#xff08;分布在 k k k 个不同的点&#xff09;要集中到一个点举行聚会。 聚会结束后需要一辆车从举行聚会的这点…...

在 Vue 项目中使用 SQLite 数据库的基础应用

目录 一、环境准备二、数据库连接与操作1. 创建数据库连接2. 创建表3. 插入数据4. 查询数据5. 更新数据6. 删除数据 三、在 Vue 组件中使用 SQLite 一、环境准备 安装 Node.js 和 npm&#xff1a;确保已安装 Node.js 和 npm。 创建 Vue 项目&#xff1a;使用 Vue CLI 创建一个…...

AI会话问答的页面滚动处理(参考deepseek页面效果)

近期在接入deepseekR1的深度思考&#xff0c;研究了下deepseek官网的滚动效果&#xff0c;大概如下&#xff1a;用户发出消息后&#xff0c;自动滚动到页面最底部&#xff0c;让最新消息展示在视野中&#xff0c;这时候&#xff0c;我们先处理一次滚动&#xff1a; const scrol…...

GRN前沿:DGCGRN:基于有向图卷积网络的基因调控网络推理

1.论文原名&#xff1a;Inference of gene regulatory networks based on directed graph convolutional networks 2.发表日期&#xff1a;2024 DGCGRN框架 中心节点和节点的构建 局部增强策略 1. 问题背景 在基因调控网络中&#xff0c;许多节点的连接度较低&#xff08;即…...

MongoDB 入门操作指南

文章目录 MongoDB 入门操作指南1. 连接到 MongoDB 数据库2. 查看当前数据库3. 显示所有数据库4. 切换或创建数据库5. 查看当前数据库中的所有集合6. 创建集合7. 插入文档插入单个文档插入多个文档 8. 查询文档查询所有文档查询匹配条件的文档格式化查询输出 9. 更新文档更新单个…...

共享设备管理难?MDM助力Kiosk模式一键部署

目录 1. 简化设备部署与配置&#xff1a;实现一键式部署 2. 自动化应用更新与内容推送&#xff1a;确保设备始终保持最新状态 3. 权限控制与设备安全&#xff1a;防止滥用与数据泄露 4. 远程管理与故障诊断&#xff1a;保障设备长期稳定运行 5. 数据分析与报告&#xff1a…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...