【设计模式有哪些】

news2025/3/19 6:25:24

一、创建型模式(Creation Patterns)

1. 单例模式(Singleton)

  • 核心思想:保证一个类仅有一个实例,并提供全局访问点。
  • 实现方式
    public class Singleton {
        // 1. 私有静态实例,volatile 保证多线程可见性
        private static volatile Singleton instance;
        
        // 2. 私有构造方法
        private Singleton() {}
        
        // 3. 双重检查锁定(Double-Checked Locking)
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
  • 场景
    • 数据库连接池(全局唯一,避免重复创建连接)
    • 配置管理类(如读取配置文件)
  • 优点:节省内存,避免重复创建对象。
  • 缺点:需处理多线程安全问题,可能违反单一职责原则。

2. 工厂方法模式(Factory Method)

  • 核心思想:定义一个创建对象的接口,但由子类决定实例化哪个类。
  • 代码示例
    // 抽象产品
    interface Product {
        void use();
    }
    
    // 具体产品A
    class ConcreteProductA implements Product {
        public void use() {
            System.out.println("Using Product A");
        }
    }
    
    // 抽象工厂
    abstract class Creator {
        public abstract Product createProduct();
    }
    
    // 具体工厂A
    class ConcreteCreatorA extends Creator {
        public Product createProduct() {
            return new ConcreteProductA();
        }
    }
    
  • 场景
    • 日志记录器(不同日志类型:文件、数据库)
    • 跨平台UI组件(不同操作系统创建不同按钮)
  • 优点:解耦客户端代码与具体类,扩展性强。
  • 缺点:每新增一个产品,需新增一个工厂类。

3. 抽象工厂模式(Abstract Factory)

  • 核心思想:创建一组相关或依赖的对象族(例如同一主题下的所有UI组件)。
  • 代码示例
    // 抽象产品族:按钮和文本框
    interface Button { void render(); }
    interface TextBox { void input(); }
    
    // Windows 风格产品
    class WindowsButton implements Button {
        public void render() { System.out.println("Windows Button"); }
    }
    class WindowsTextBox implements TextBox {
        public void input() { System.out.println("Windows TextBox"); }
    }
    
    // 抽象工厂接口
    interface GUIFactory {
        Button createButton();
        TextBox createTextBox();
    }
    
    // Windows 工厂
    class WindowsFactory implements GUIFactory {
        public Button createButton() { return new WindowsButton(); }
        public TextBox createTextBox() { return new WindowsTextBox(); }
    }
    
  • 场景
    • 跨平台应用开发(同一套UI在不同操作系统下表现不同)
    • 游戏中的不同风格资源包(如科幻 vs 中世纪)
  • 优点:保证产品族的兼容性。
  • 缺点:新增产品族需要修改所有工厂类。

4. 建造者模式(Builder)

  • 核心思想:分步骤构造复杂对象,允许不同表示形式。
  • 代码示例
    class Computer {
        private String CPU;
        private String RAM;
        // 其他组件...
    
        // 建造者内部类
        public static class Builder {
            private String CPU;
            private String RAM;
    
            public Builder setCPU(String cpu) {
                this.CPU = cpu;
                return this; // 链式调用
            }
            public Builder setRAM(String ram) {
                this.RAM = ram;
                return this;
            }
            public Computer build() {
                Computer computer = new Computer();
                computer.CPU = this.CPU;
                computer.RAM = this.RAM;
                return computer;
            }
        }
    }
    
    // 使用
    Computer computer = new Computer.Builder()
        .setCPU("Intel i7")
        .setRAM("32GB")
        .build();
    
  • 场景
    • 生成复杂对象(如HTML文档、SQL查询)
    • 链式调用配置参数(如Retrofit、OkHttp的配置)
  • 优点:封装对象的构造过程,支持灵活扩展。
  • 缺点:代码量增加,适合构造复杂对象。

5. 原型模式(Prototype)

  • 核心思想:通过克隆现有对象创建新对象,避免重复初始化。
  • 代码示例
    class Prototype implements Cloneable {
        private String data;
    
        public Prototype(String data) {
            this.data = data;
        }
    
        @Override
        public Prototype clone() {
            try {
                return (Prototype) super.clone();
            } catch (CloneNotSupportedException e) {
                return null;
            }
        }
    }
    
    // 使用
    Prototype original = new Prototype("Original Data");
    Prototype copy = original.clone();
    
  • 场景
    • 游戏中的敌人复制(避免重复初始化属性)
    • 对象初始化成本高(如数据库数据克隆)
  • 优点:性能优化,绕过构造方法。
  • 缺点:深拷贝与浅拷贝需谨慎处理。

二、结构型模式(Structural Patterns)

6. 适配器模式(Adapter)

  • 核心思想:将一个接口转换成客户端期望的另一个接口。
  • 代码示例
    // 旧接口(不兼容)
    class LegacyPrinter {
        void printDocument(String text) {
            System.out.println("Legacy Printer: " + text);
        }
    }
    
    // 新接口
    interface ModernPrinter {
        void print(String content);
    }
    
    // 适配器类
    class PrinterAdapter implements ModernPrinter {
        private LegacyPrinter legacyPrinter = new LegacyPrinter();
        
        public void print(String content) {
            legacyPrinter.printDocument(content);
        }
    }
    
  • 场景
    • 旧系统接口适配新系统
    • 第三方库的接口封装
  • 优点:复用旧代码,解决接口不兼容。
  • 缺点:过多适配器会增加代码复杂度。

7. 装饰器模式(Decorator)

  • 核心思想:动态地为对象添加职责(不修改原有类)。
  • 代码示例
    // 基础组件
    interface Coffee {
        double getCost();
        String getDescription();
    }
    
    // 具体组件
    class SimpleCoffee implements Coffee {
        public double getCost() { return 1.0; }
        public String getDescription() { return "Simple Coffee"; }
    }
    
    // 装饰器基类
    abstract class CoffeeDecorator implements Coffee {
        protected Coffee decoratedCoffee;
        public CoffeeDecorator(Coffee coffee) {
            this.decoratedCoffee = coffee;
        }
    }
    
    // 具体装饰器:加牛奶
    class MilkDecorator extends CoffeeDecorator {
        public MilkDecorator(Coffee coffee) { super(coffee); }
        
        public double getCost() { return decoratedCoffee.getCost() + 0.5; }
        public String getDescription() { return decoratedCoffee.getDescription() + ", Milk"; }
    }
    
    // 使用
    Coffee coffee = new MilkDecorator(new SimpleCoffee());
    
  • 场景
    • Java IO流(如 BufferedReader 包装 FileReader
    • Web请求的过滤器链
  • 优点:比继承更灵活,支持运行时扩展。
  • 缺点:多层装饰可能导致代码复杂。

8. 代理模式(Proxy)

  • 核心思想:控制对对象的访问(延迟加载、权限控制等)。
  • 代码示例
    interface Image {
        void display();
    }
    
    // 真实对象(高成本)
    class RealImage implements Image {
        private String filename;
        
        public RealImage(String filename) {
            this.filename = filename;
            loadFromDisk();
        }
        
        private void loadFromDisk() {
            System.out.println("Loading image: " + filename);
        }
        
        public void display() {
            System.out.println("Displaying image: " + filename);
        }
    }
    
    // 代理类(延迟加载)
    class ProxyImage implements Image {
        private RealImage realImage;
        private String filename;
        
        public ProxyImage(String filename) { this.filename = filename; }
        
        public void display() {
            if (realImage == null) {
                realImage = new RealImage(filename);
            }
            realImage.display();
        }
    }
    
  • 场景
    • 虚拟代理(如图片延迟加载)
    • 保护代理(如权限验证)
    • 远程代理(如RPC调用)
  • 优点:解耦客户端与真实对象,增强控制。
  • 缺点:可能引入性能开销。

三、行为型模式(Behavioral Patterns)

9. 观察者模式(Observer)

  • 核心思想:定义对象间的一对多依赖关系,当一个对象状态改变时,自动通知依赖它的对象。
  • 代码示例
    // 主题(被观察者)
    interface Subject {
        void registerObserver(Observer o);
        void removeObserver(Observer o);
        void notifyObservers();
    }
    
    // 具体主题(例如天气数据)
    class WeatherData implements Subject {
        private List<Observer> observers = new ArrayList<>();
        private float temperature;
        
        public void setTemperature(float temp) {
            this.temperature = temp;
            notifyObservers();
        }
        
        public void registerObserver(Observer o) { observers.add(o); }
        public void removeObserver(Observer o) { observers.remove(o); }
        public void notifyObservers() {
            for (Observer o : observers) {
                o.update(temperature);
            }
        }
    }
    
    // 观察者接口
    interface Observer {
        void update(float temperature);
    }
    
    // 具体观察者(例如显示设备)
    class DisplayDevice implements Observer {
        public void update(float temperature) {
            System.out.println("Current Temperature: " + temperature);
        }
    }
    
  • 场景
    • 事件驱动系统(如GUI按钮点击事件)
    • 发布-订阅模型(如消息队列)
  • 优点:解耦主题与观察者,支持广播通信。
  • 缺点:观察者过多时可能影响性能。

10. 策略模式(Strategy)

  • 核心思想:定义一系列算法,使其可以相互替换,且算法的变化独立于客户端。
  • 代码示例
    // 策略接口
    interface PaymentStrategy {
        void pay(int amount);
    }
    
    // 具体策略:信用卡支付
    class CreditCardPayment implements PaymentStrategy {
        public void pay(int amount) {
            System.out.println("Paid " + amount + " via Credit Card");
        }
    }
    
    // 上下文类(使用策略)
    class ShoppingCart {
        private PaymentStrategy strategy;
        
        public void setPaymentStrategy(PaymentStrategy strategy) {
            this.strategy = strategy;
        }
        
        public void checkout(int amount) {
            strategy.pay(amount);
        }
    }
    
    // 使用
    ShoppingCart cart = new ShoppingCart();
    cart.setPaymentStrategy(new CreditCardPayment());
    cart.checkout(100);
    
  • 场景
    • 支付方式选择(支付宝、微信、银行卡)
    • 排序算法切换(快速排序、归并排序)
  • 优点:避免多重条件判断,易于扩展新算法。
  • 缺点:客户端必须理解不同策略的区别。

11. 责任链模式(Chain of Responsibility)

  • 核心思想:将请求沿着处理链传递,直到有一个处理者处理它。
  • 代码示例
    abstract class Handler {
        protected Handler nextHandler;
        
        public void setNext(Handler handler) {
            this.nextHandler = handler;
        }
        
        public abstract void handleRequest(int request);
    }
    
    // 具体处理者A
    class ConcreteHandlerA extends Handler {
        public void handleRequest(int request) {
            if (request <= 10) {
                System.out.println("Handler A processes request " + request);
            } else if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
    
    // 使用
    Handler chain = new ConcreteHandlerA();
    chain.setNext(new ConcreteHandlerB());
    chain.handleRequest(5);  // 由A处理
    chain.handleRequest(20); // 由B处理
    
  • 场景
    • Web框架的过滤器链(如Spring Security)
    • 审批流程(如请假申请的多级审批)
  • 优点:动态调整处理链,解耦发送者和接收者。
  • 缺点:请求可能未被处理。

四、如何实际应用设计模式?

  • 核心原则:先理解问题,再选择模式,避免为了用模式而用模式。
  • 常见误区
    • 过度设计:简单问题强行套用复杂模式。
    • 模式混用:多个模式叠加导致代码混乱。
  • 学习建议
    1. 从简单模式入手(如工厂、单例、观察者)。
    2. 结合开源框架(如Spring、JDK源码)学习模式的应用。
    3. 在重构中实践模式,逐步替换旧代码。

希望这些详细的解释和代码示例能帮助你深入理解设计模式!如果需要某个模式的进一步扩展,可以告诉我。

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

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

相关文章

基于SpringBoot+Vue的幼儿园管理系统+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、教师、普通用户功能模块&#xff1a;用户管理、教师管理、班级管理、幼儿信息管理、会议记录管理、待办事项、职工考核、请假信息、缴费信息、体检管理、资源管理、原料管理、菜品信息管理等技术选型&#xff1a;SpringBoot&#xff0…

案例5_3: 6位数码管静态显示

文章目录 文章介绍效果图仿真图复习知识&#xff1a;代码思考 文章介绍 第5章 学习数码管&#xff0c;使用6位数码管进行静态显示 效果图 仿真图 新建一个干净的5_3文件夹&#xff0c;用于存放新画的仿真图 除单片机最小系统外&#xff0c;新增3个元器件&#xff0c;分别是&…

Profinet转Modbus RTU/TCP以太网通讯处理器

Profinet转Modbus RTU/TCP以太网通讯处理器 在当今的工业自动化领域&#xff0c;各种通讯协议和标准层出不穷。 其中&#xff0c;Profinet和Modbus作为两种广泛应用的通讯协议&#xff0c;分别在不同的应用场景中发挥着重要作用。 然而&#xff0c;当需要将这两种协议进行转换…

3倍训练速度+40%显存节省!Mamba+Transformer 仅用一半时间,性能提升80%!

在人工智能领域&#xff0c;Mamba与Transformer的结合正在成为研究热点&#xff0c;为自然语言处理和多模态任务带来新的突破。 最新研究表明&#xff0c;通过将Mamba架构与Transformer的强大编码能力相结合&#xff0c;模型在处理复杂的多模态数据时的效率提升了50%&#xff…

春秋云境刷题1

CVE-2022-29464 靶标介绍&#xff1a; WSO2文件上传漏洞&#xff08;CVE-2022-29464&#xff09;是Orange Tsai发现的WSO2上的严重漏洞。该漏洞是一种未经身份验证的无限制任意文件上传&#xff0c;允许未经身份验证的攻击者通过上传恶意JSP文件在WSO2服务器上获得RCE。 Git…

台式机电脑组装---电源

台式机电脑组装—电源 22 33 主板供电是聚集了12V&#xff0c;5V,3.3V的24pin CPU供电的话主要是12V的44pin供电 44pin合并之后&#xff0c;就是8pin 55 SATA硬盘会使用饼io口取电&#xff0c;从电源获取12v,5v,3.3v的电 33

10-BST(二叉树)-建立二叉搜索树,并进行前中后遍历

题目 来源 3540. 二叉搜索树 - AcWing题库 思路 建立二叉搜索树&#xff08;注意传参时用到了引用&#xff0c;可以直接对root进行修改&#xff09;&#xff0c;同时进行递归遍历&#xff1b;遍历可以分前中后三种写&#xff0c;也可以用标志来代替合在一起。其余详见代码。…

蓝桥杯备考:贪心问题之淘淘摘苹果

这是淘淘摘苹果普通版&#xff0c;很可爱的一道题&#xff0c;我们不多陈述&#xff0c;直接上代码 #include <iostream> using namespace std; const int N 15; int a[N]; int main() {for(int i 1;i<10;i){cin >> a[i];}int x;cin >> x;x30;int cnt …

VSTO(C#)Excel开发 系列目录 含源码发布

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

Git使用和原理(3)

1.远程操作 1.1分布式版本控制系统 我们⽬前所说的所有内容&#xff08;⼯作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#xff0c;都是在本地&#xff01;也就是在你的笔记本或者 计算机上。⽽我们的 Git 其实是分布式版本控制系统&#xff01;什么意思呢&a…

博客图床 VsCode + PigGo + 阿里云OSS

关键字 写博客&#xff0c;图床&#xff0c;VsCode&#xff0c;PigGo&#xff0c;阿里云OSS 背景环境 我想把我在本地写的markdown文档直接搬到CSDN上和博客园上&#xff0c;但是图片上传遇到了问题。我需要手动到不同平台上传文件&#xff0c;非常耗费时间和经历。 为了解决…

C++之list类及模拟实现

目录 list的介绍 list的模拟实现 定义节点 有关遍历的重载运算符 list的操作实现 &#xff08;1&#xff09;构造函数 (2)拷贝构造函数 &#xff08;3&#xff09;赋值运算符重载函数 &#xff08;4&#xff09;析构函数和clear成员函数 &#xff08;5&#xff09;尾…

SwinTransformer 改进:添加DoubleAttention模块提升上下文语义提取能力

目录 1. DoubleAttention模块 2. SwinTransformer + DoubleAttention 3. 完整代码 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. DoubleAttention模块 DoubleAttention 是一种用于计算机视觉任务的注意力机制,旨在通过双重注意力机制…

MacBook部署达梦V8手记

背景 使用Java SpringBootDM开发Web应用&#xff0c;框架有License&#xff0c;OSX加载dll失败&#xff0c;安装了Windows 11&#xff0c;只有一个C盘&#xff0c;达梦安装后因为C盘权限问题&#xff0c;创建数据库失败&#xff0c;遂采用Docker容器方式部署。 下载介质 官网在…

外贸 B2B 平台没落?多语言批发系统正在崛起

近年来&#xff0c;全球外贸行业正在发生快速变化&#xff0c;传统的 B2B 平台正面临越来越多的挑战&#xff0c;尤其是在面对新兴的多语言批发系统时。这种变化不仅影响了供应商和买家之间的交易方式&#xff0c;也正在推动外贸行业的数字化升级和转型。今天&#xff0c;让我们…

[spring] Spring JPA - Hibernate 多表联查 1

[spring] Spring JPA - Hibernate 多表联查 之前在 [spring] spring jpa - hibernate 名词解释&配置 和 [spring] spring jpa - hibernate CRUD 简单的学习了一下怎么使用 Hibernate 实现 CRUD 操作&#xff0c;不过涉及到的部分都是逻辑上比较简单的实现——只在一张表上…

鸿蒙Next开发实战教程—电影app

最近忙忙活活写了不少教程&#xff0c;但是总感觉千篇一律&#xff0c;没什么意思&#xff0c;大家如果有感兴趣的项目可以私信给幽蓝君写一写。 今天分享一个电影App。 这个项目也比较简单&#xff0c;主要是一些简单页面的开发和本地视频的播放以及横竖屏切换。 页面搭建以…

停车场停车位数据集,标注停车位上是否有车,平均正确识别率99.5%,支持yolov5-11, coco json,darknet,xml格式标注

停车场停车位数据集&#xff0c;标注停车位上是否有车&#xff0c;平均正确识别率98.0&#xff05;&#xff0c;支持yolov5-11&#xff0c; coco json&#xff0c;darknet&#xff0c;xml格式标注 数据集-识别停车场所有车辆的数据集 数据集分割 一共184张图片 训练组 89&am…

ssm框架之mybatis框架讲解

1&#xff0c;Mybatis 1.1 Mybatis概述 1.1.1 Mybatis概念 MyBatis 是一款优秀的持久层框架&#xff0c;用于简化 JDBC 开发 MyBatis 本是 Apache 的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;并且改名为MyBatis 。2…

CEF 多进程模式时,注入函数,获得交互信息

CEF 控制台添加一函数,枚举 注册的供前端使用的CPP交互函数有哪些-CSDN博客 上篇文章,是在模拟环境,单进程中设置的,这篇文章,将其改到正常多进程环境中设置。 对应于工程中的 CEF_RENDER项目 一、多进程模式中,改写 修改步骤 1、注入函数 client_app_render.cpp 在…