【HeadFirst系列之HeadFirst设计模式】第14天之与设计模式相处:真实世界中的设计模式

news2025/4/24 0:18:26

与设计模式相处:真实世界中的设计模式

设计模式是软件开发中的经典解决方案,它们帮助我们解决常见的设计问题,并提高代码的可维护性和可扩展性。在《Head First设计模式》一书中,作者通过生动的案例和通俗的语言,深入浅出地介绍了各种设计模式的核心思想和使用场景。本文将基于书中的“与设计模式相处-真实世界中的模式”章节,提炼总结设计模式的核心内容,并结合实际应用场景和代码示例,帮助大家更好地理解和应用设计模式。

在这里插入图片描述

1. 设计模式的核心思想

1.1 遇到什么问题?

在软件开发过程中,我们经常会遇到一些重复出现的问题,例如:

  • 代码重复:相似的代码在不同的地方重复出现,导致维护困难。
  • 紧耦合:模块之间的依赖关系过于紧密,修改一个模块可能会影响其他模块。
  • 扩展性差:系统难以扩展,新增功能时需要修改大量现有代码。

1.2 怎么解决的?

设计模式提供了一套经过验证的解决方案,帮助我们解决上述问题。它们通过封装变化、解耦依赖、提高复用性等方式,使代码更加灵活和可维护。

1.3 引入设计模式

设计模式并不是银弹,它们并不是用来解决所有问题的。相反,设计模式是用来解决特定场景下的特定问题的。在使用设计模式时,我们需要根据具体的问题场景选择合适的模式。

1.4 使用场景

设计模式的使用场景非常广泛,几乎涵盖了软件开发的各个方面。例如:

  • 创建型模式:用于对象的创建,如工厂模式、单例模式等。
  • 结构型模式:用于类和对象的组合,如适配器模式、装饰器模式等。
  • 行为型模式:用于对象之间的交互,如观察者模式、策略模式等。

1.5 优缺点

设计模式的优点在于它们提供了一套经过验证的解决方案,可以帮助我们快速解决常见的设计问题。然而,设计模式也有其缺点,例如:

  • 过度设计:在不必要的情况下使用设计模式,可能会导致代码复杂化。
  • 学习曲线:设计模式需要一定的学习成本,初学者可能需要花费一些时间来理解和掌握。

2. 设计模式在JDK和Spring框架中的应用

2.1 JDK中的设计模式

JDK中广泛使用了各种设计模式,以下是一些常见的例子:

2.1.1 工厂模式

java.util.Calendar 类中的 getInstance() 方法就是一个典型的工厂方法模式的应用。它根据不同的时区和地区返回不同的 Calendar 实例。

Calendar calendar = Calendar.getInstance();
2.1.2 单例模式

java.lang.Runtime 类是一个典型的单例模式的应用。Runtime 类提供了访问运行时环境的方法,并且在整个应用程序中只有一个实例。

Runtime runtime = Runtime.getRuntime();
2.1.3 观察者模式

java.util.Observablejava.util.Observer 是观察者模式的实现。Observable 类代表被观察的对象,Observer 接口代表观察者。

class ConcreteObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Received update: " + arg);
    }
}

Observable observable = new Observable();
observable.addObserver(new ConcreteObserver());
observable.notifyObservers("Hello, Observer!");

2.2 Spring框架中的设计模式

Spring框架中也大量使用了设计模式,以下是一些常见的例子:

2.2.1 依赖注入(DI)模式

Spring框架的核心就是依赖注入模式。通过依赖注入,Spring可以将对象的依赖关系从代码中解耦出来,使得代码更加灵活和可测试。

@Service
public class MyService {
    private final MyRepository repository;

    @Autowired
    public MyService(MyRepository repository) {
        this.repository = repository;
    }
}
2.2.2 代理模式

Spring AOP(面向切面编程)使用了代理模式来实现横切关注点的分离。Spring通过动态代理为目标对象创建代理对象,从而在不修改原始代码的情况下增强其功能。

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }
}
2.2.3 模板方法模式

Spring的 JdbcTemplate 类是一个典型的模板方法模式的应用。JdbcTemplate 封装了JDBC操作的通用流程,用户只需要关注具体的SQL语句和结果处理。

@Autowired
private JdbcTemplate jdbcTemplate;

public List<User> getAllUsers() {
    return jdbcTemplate.query("SELECT * FROM users", new BeanPropertyRowMapper<>(User.class));
}

3. 代码示例

3.1 策略模式

策略模式允许我们定义一系列算法,并将它们封装在独立的类中,使得它们可以互换使用。以下是一个简单的策略模式示例:

interface Strategy {
    int execute(int a, int b);
}

class AddStrategy implements Strategy {
    @Override
    public int execute(int a, int b) {
        return a + b;
    }
}

class SubtractStrategy implements Strategy {
    @Override
    public int execute(int a, int b) {
        return a - b;
    }
}

class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int a, int b) {
        return strategy.execute(a, b);
    }
}

public class StrategyPatternDemo {
    public static void main(String[] args) {
        Context context = new Context(new AddStrategy());
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

        context = new Context(new SubtractStrategy());
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
    }
}

3.2 装饰器模式

装饰器模式允许我们动态地为对象添加新的行为,而不会影响其他对象。以下是一个简单的装饰器模式示例:

interface Coffee {
    String getDescription();
    double getCost();
}

class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double getCost() {
        return 5.0;
    }
}

class MilkDecorator implements Coffee {
    private Coffee coffee;

    public MilkDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + ", Milk";
    }

    @Override
    public double getCost() {
        return coffee.getCost() + 1.5;
    }
}

public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());

        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.getCost());
    }
}

4. 总结

设计模式是软件开发中的宝贵财富,它们帮助我们解决常见的设计问题,并提高代码的可维护性和可扩展性。通过理解设计模式的核心思想和使用场景,我们可以更好地应用它们来解决实际问题。同时,JDK和Spring框架中的设计模式应用也为我们提供了丰富的参考案例。希望本文能够帮助大家更好地理解和应用设计模式,写出更加优雅和高效的代码。


参考文献

  • 《Head First设计模式》 by Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra

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

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

相关文章

自由学习记录(42)

可能会出现到后面没有教程可以看&#xff0c;走不动&#xff0c;&#xff0c;但还是尝试吧 过程远比想象的要多 那连Live2d的这些脚本怎么控制的都要了解一下 ------------ 文件类型和扩展名 | 编辑手册 | Live2D Manuals & Tutorials 全部导入之后 在这下载SDK Live2D…

excel vlookup的精确查询、模糊查询、反向查询、多列查询

目录 入门 精确查询 模糊查询 反向查询 (搭配 if 函数) 多列查询 (搭配 match 函数) 入门 精确查询 需求: 查找 学生编号是008 所在的班级 操作: 在I2单元格输入公式如下,VLOOKUP(H2,B1:E12,4,FALSE), 得出结果 看一下vlookup 公式每一个参数应该怎么写? 语法: vlookup…

安装remixd,在VScode创建hardhat

在终端&#xff0c;以管理员身份&#xff0c;cmd 需要科学上网 npm install -g remix-project/remixd 在vscode插件中&#xff0c;安装solidity插件&#xff0c;是暗灰色那款 1.将nodeJs的版本升级至18以上 2.在vscode打开一个新的文件&#xff0c;在终端输入 npx hardhat 3.…

【Python爬虫】利用代理IP爬取跨境电商AI选品分析

引言 随着DeepSeek的流行&#xff0c;越来越多的用户开始尝试将AI工具融入到日常工作当中&#xff0c;借助AI的强大功能提高工作效率。最近又掀起了一波企业出海的小高潮&#xff0c;那么如果是做跨境电商业务&#xff0c;怎么将AI融入工作流中呢&#xff1f;在做跨境电商的时候…

捣鼓180天,我写了一个相册小程序

&#x1f64b;为什么要做土著相册这样一个产品&#xff1f; ➡️在高压工作之余&#xff0c;我喜欢浏览B站上的熊猫幼崽视频来放松心情。有天在家族群里看到了大嫂分享的侄女卖萌照片&#xff0c;同样感到非常解压。于是开始翻阅过去的聊天记录&#xff0c;却发现部分图片和视…

洛谷 P1480 A/B Problem(高精度详解)c++

题目链接&#xff1a;P1480 A/B Problem - 洛谷 1.题目分析 1&#xff1a;说明这里是高精度除以低精度的形式&#xff0c;为什么不是高精度除以高精度的形式&#xff0c;是因为它很少见&#xff0c;它的模拟方式是用高精度减法来做的&#xff0c;并不能用小学列竖式的方法模拟…

图像滑块对比功能的开发记录

背景介绍 最近&#xff0c;公司需要开发一款在线图像压缩工具&#xff0c;其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此&#xff0c;我们设计了一个对比组件&#xff0c;它允许用户通过拖动滑块&#xff0c;动态调整两张图像的显示区域&#xff0c;从而清晰…

基于Arcgis的python脚本实现相邻矢量面的高度字段取平均值

文章目录 背景效果实现逻辑步骤1、准备数据2、python脚本3、执行通过脚本工具箱来执行背景 在地理信息系统(GIS)数据处理或三维建模等实际应用场景中,我们常常会遇到需要对矢量面数据进行精细化处理的需求。其中一个常见的任务便是对相邻的矢量面中的高度字段开展特定操作。…

Golang的网络流量控制

# Golang的网络流量控制 什么是网络流量控制&#xff1f; 网络流量控制是指针对网络数据传输过程中的流量进行管理和调控的一种技术手段。通过网络流量控制&#xff0c;我们可以对网络中的数据传输速率、带宽使用情况、数据包丢失率等进行监控和调整&#xff0c;以达到优化网络…

Python教程(一):基本语法、流程控制、数据容器

Python&#xff08;一&#xff09; 文章目录 Python&#xff08;一&#xff09;一、基础语法二、数据类型2.1 字符串2.2 空值2.3 类型转换&运算符 三、流程控制3.1 条件判断3.2 循环3.2.1 while循环3.2.2 for循环 四、数据结构4.1 字符串str4.1.1 字符串的格式化输出4.1.1.…

【AI深度学习基础】PyTorch初探

引言 PyTorch 是由 Facebook 开源的深度学习框架&#xff0c;专门针对 GPU 加速的深度神经网络编程&#xff0c;它的核心概念包括张量&#xff08;Tensor&#xff09;、计算图和自动求导机制。PyTorch作为Facebook开源的深度学习框架&#xff0c;凭借其动态计算图和直观的API设…

UE4 组件 (对话组件)

制作一个可以生成对话气泡&#xff0c;显示对话台词的简单组件。这个组件要的变量&#xff1a;台词&#xff08;外部传入&#xff09;。功能&#xff1a;开始对话&#xff08;生成气泡UI&#xff09; &#xff0c;结束对话。 一、对话组件创建 二、开始对话事件 1、注意这里获…

blender看不到导入的模型

参考&#xff1a;blender 快捷键 常见问题_blender材质预览快捷键-CSDN博客 方法一&#xff1a;视图-裁剪起点&#xff0c;设置一个很大的值 方法二&#xff1a;选中所有对象&#xff0c;对齐视图-视图对齐活动项-选择一个视图

【慕课网wiki项目学习笔记01】Spring Boot 项目搭建

2-2 新建SpringBoot项目 一、创建SpringBoot项目 &#xff08;1&#xff09;在SpringBoot官网创建 &#xff08;2.1&#xff09;在 IDEA 中创建 Group&#xff1a;公司名 Artifact&#xff1a;项目名 创建成功后开始下载Maven依赖&#xff08;选择右下角的Import Changes&…

【高分论文密码】AI大模型和R语言的全类型科研图形绘制,从画图、标注、改图、美化、组合、排序分解科研绘图每个步骤

在科研成果竞争日益激烈的当下&#xff0c;「一图胜千言」已成为高水平SCI期刊的硬性门槛——数据显示很多情况的拒稿与图表质量直接相关。科研人员普遍面临的工具效率低、设计规范缺失、多维数据呈现难等痛点&#xff0c;因此科研绘图已成为成果撰写中的至关重要的一个环节&am…

vue3-pc-template后台管理之角色管理与功能权限配置实践

在开发企业级应用时&#xff0c;权限控制无疑是至关重要且不可或缺的一部分。合理的权限控制不仅能够有效保障系统的安全性&#xff0c;还能确保不同用户角色在系统中拥有合适的操作权限&#xff0c;从而提高系统的使用效率和稳定性。本文将详细介绍如何在 Vue3 项目中实现功能…

Android Flow 示例

在Android开发的世界里&#xff0c;处理异步数据流一直是一个挑战。随着Kotlin的流行&#xff0c;Flow作为Kotlin协程库的一部分&#xff0c;为开发者提供了一种全新的方式来处理这些问题。今天&#xff0c;我将深入探讨Flow的设计理念&#xff0c;并通过具体的例子展示如何在实…

前端文件加载耗时过长解决方案

从你的 Network (网络) 面板 看到&#xff0c;许多 JS 文件的加载时间较长&#xff08;1~2秒&#xff09;&#xff0c;可能的原因如下&#xff1a; ✅ 可能的原因 1. 过多的 JS 请求&#xff08;多个小文件加载&#xff09; 你当前页面加载了很多小 JS 文件&#xff08;addSi…

Visual Studio 2022新建c语言项目的详细步骤

步骤1&#xff1a;点击创建新项目 步骤2&#xff1a;到了项目模板 --> 选择“控制台应用” (在window终端运行代码。默认打印"Hello World") --> 点击 “下一步” 步骤3&#xff1a;到了配置新项目模块 --> 输入“项目名称” --> 更改“位置”路径&…

物联网系统搭建

实验项目名称 构建物联网系统 实验目的 掌握物联网系统的一般构建方法。 实验要求&#xff1a; 1&#xff0e;构建物联网系统&#xff0c;实现前后端的交互。 实验内容&#xff1a; CS模式MQTT&#xff08;不带数据分析处理功能&#xff09; 实现智能设备与应用客户端的交…