在项目中应用设计模式的实践指南

目录

✨✨ 祝屏幕前的您天天开心,每天都有好运相伴。我们一起加油!✨✨
🎈🎈作者主页: 喔的嘛呀🎈🎈

引言

一. 单例模式(Singleton Pattern)

1、实现单例模式的方式

1.1 懒汉式(Lazy Initialization)

1.2. 饿汉式(Eager Initialization)

1.3. 双重检查锁(Double-Checked Locking)

2、在项目中的应用

3、总结

二、 工厂模式(Factory Pattern)

1、工厂模式的实现方式

1.1简单工厂模式(Simple Factory Pattern)

1.2、工厂方法模式(Factory Method Pattern)

2、工厂模式在项目中的应用

3、总结

三. 观察者模式(Observer Pattern)

观察者模式的角色

观察者模式的优点

观察者模式的应用场景

示例代码

总结

四. 策略模式(Strategy Pattern)

策略模式的角色

策略模式的优点

策略模式的应用场景

示例代码

总结

结论


引言

设计模式是软件开发中的重要概念,它提供了一套经过验证的解决方案,可以帮助我们解决常见的设计问题。在项目中合理应用设计模式可以提高代码的质量和可维护性。本文将详细介绍如何在项目中应用设计模式,并提供具体的示例代码来说明。

一. 单例模式(Singleton Pattern)

单例模式用于确保一个类只有一个实例,并提供一个全局访问点。在项目中,单例模式通常用于管理共享资源或全局配置。

单例模式(Singleton Pattern)是一种创建型设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。这种模式非常有用,特别是当一个类需要被多个不同的部分使用时,但我们希望这个类的实例始终保持一致性时。

1、实现单例模式的方式

1.1 懒汉式(Lazy Initialization)

在第一次被调用时才创建实例。

public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
1.2. 饿汉式(Eager Initialization)

在类加载时就创建实例。

public class Singleton {private static Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}
1.3. 双重检查锁(Double-Checked Locking)

结合懒汉式和同步锁,在保证线程安全的同时减少同步开销。

public class Singleton {private volatile static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

2、在项目中的应用

在项目中,单例模式经常被用于以下情况:

  1. 日志记录器(Logger):一个应用可能需要一个全局的日志记录器来记录应用中的事件和错误信息。单例模式可以确保所有部分都使用相同的日志记录器实例。

  2. 配置管理器(Configuration Manager):一个应用可能需要一个全局的配置管理器来加载和保存配置信息。单例模式可以确保所有部分都使用相同的配置管理器实例。

  3. 数据库连接池(Database Connection Pool):在需要频繁访问数据库的应用中,可以使用单例模式管理数据库连接池,以避免频繁地创建和销毁连接。

  4. 线程池(Thread Pool):在需要管理多个线程的应用中,可以使用单例模式管理线程池,以便统一管理线程的创建和销毁。

  5. 缓存管理器(Cache Manager):在需要缓存数据的应用中,可以使用单例模式管理缓存,以便统一管理缓存的读写操作。

  6. GUI组件管理器(GUI Component Manager):在需要管理用户界面组件的应用中,可以使用单例模式管理界面组件,以确保所有部分都使用相同的界面组件实例。

以上是单例模式在项目中的一些常见应用场景。在实际项目中,可以根据具体需求和场景来灵活应用单例模式,以提高代码的质量和可维护性。

3、总结

单例模式是一种简单但非常有用的设计模式,在项目中经常被使用。然而,需要注意在多线程环境下保证线程安全,以及避免对单例实例进行破坏性操作(如反序列化)。

二、 工厂模式(Factory Pattern)

工厂模式是一种创建型设计模式,用于创建对象,但将对象的创建逻辑封装在工厂类中,从而实现解耦。工厂模式可以根据不同的条件来创建不同类型的对象,而客户端代码只需要知道如何使用工厂类来获取对象,而不需要知道具体对象的创建细节。

1、工厂模式的实现方式

1.1简单工厂模式(Simple Factory Pattern)

public interface Shape {void draw();
}public class Circle implements Shape {@Overridepublic void draw() {System.out.println("画一个圆形");}
}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("画一个矩形");}
}public class ShapeFactory {public Shape getShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("circle")) {return new Circle();} else if (shapeType.equalsIgnoreCase("rectangle")) {return new Rectangle();}return null;}
}

1.2、工厂方法模式(Factory Method Pattern)

public interface Shape {void draw();
}public class Circle implements Shape {@Overridepublic void draw() {System.out.println("画一个圆形");}
}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("画一个矩形");}
}public interface ShapeFactory {Shape createShape();
}public class CircleFactory implements ShapeFactory {@Overridepublic Shape createShape() {return new Circle();}
}public class RectangleFactory implements ShapeFactory {@Overridepublic Shape createShape() {return new Rectangle();}
}

2、工厂模式在项目中的应用

工厂模式在项目中的应用非常广泛,它主要用于创建对象,但将对象的创建逻辑封装在工厂类中,从而实现解耦。以下是工厂模式在项目中常见的应用场景和示例:

  1. 数据库连接工厂:在需要访问数据库的应用中,可以使用数据库连接工厂来创建数据库连接对象,根据不同的数据库类型返回不同的连接对象。
public interface Connection {void connect();
}public class MySqlConnection implements Connection {@Overridepublic void connect() {System.out.println("连接到MySQL数据库");}
}public class OracleConnection implements Connection {@Overridepublic void connect() {System.out.println("连接到Oracle数据库");}
}public class ConnectionFactory {public static Connection getConnection(String dbType) {if ("mysql".equalsIgnoreCase(dbType)) {return new MySqlConnection();} else if ("oracle".equalsIgnoreCase(dbType)) {return new OracleConnection();}return null;}
}

日志记录器工厂:在需要记录日志的应用中,可以使用日志记录器工厂来创建日志记录器对象,根据不同的日志级别返回不同的日志记录器对象。

public interface Logger {void log(String message);
}public class InfoLogger implements Logger {@Overridepublic void log(String message) {System.out.println("[INFO] " + message);}
}public class ErrorLogger implements Logger {@Overridepublic void log(String message) {System.out.println("[ERROR] " + message);}
}public class LoggerFactory {public static Logger getLogger(String logLevel) {if ("info".equalsIgnoreCase(logLevel)) {return new InfoLogger();} else if ("error".equalsIgnoreCase(logLevel)) {return new ErrorLogger();}return null;}
}

文件解析器工厂:在需要解析不同类型文件的应用中,可以使用文件解析器工厂来创建文件解析器对象,根据不同的文件类型返回不同的解析器对象。

public interface Parser {void parse(String filePath);
}public class XmlParser implements Parser {@Overridepublic void parse(String filePath) {System.out.println("解析XML文件:" + filePath);}
}public class JsonParser implements Parser {@Overridepublic void parse(String filePath) {System.out.println("解析JSON文件:" + filePath);}
}public class ParserFactory {public static Parser getParser(String fileType) {if ("xml".equalsIgnoreCase(fileType)) {return new XmlParser();} else if ("json".equalsIgnoreCase(fileType)) {return new JsonParser();}return null;}
}

3、总结

工厂模式可以帮助我们在项目中实现对象的创建和管理,同时降低了类之间的耦合度,使得代码更加灵活和可维护。在实际项目中,根据具体需求和场景,可以灵活应用工厂模式来提高代码的质量和可扩展性。

三. 观察者模式(Observer Pattern)

观察者模式是一种行为设计模式,用于定义对象间的一对多依赖关系,当一个对象状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。这种模式涉及到两种类型的对象:主题(Subject)和观察者(Observer)。主题维护一组观察者,提供注册和删除观察者的方法,并在状态变化时通知观察者。

观察者模式的角色

  1. Subject(主题):被观察的对象,它维护一组观察者,并提供注册和删除观察者的方法,以及通知观察者的方法。
  2. ConcreteSubject(具体主题):实现主题接口的具体对象,它存储主题的状态,当状态发生变化时通知所有观察者。
  3. Observer(观察者):定义一个更新接口用于接收并响应主题状态的变化。
  4. ConcreteObserver(具体观察者):实现观察者接口的具体对象,当接收到主题通知时执行特定的动作。

观察者模式的优点

  • 松耦合:主题和观察者之间是松耦合的,主题只知道观察者接口,而不需要了解具体的观察者实现。
  • 可扩展性:可以在运行时动态添加新的观察者。
  • 反应性:观察者能够立即对主题的状态变化做出响应。

观察者模式的应用场景

  • 当一个对象的改变需要同时改变其他对象,并且不知道具体有多少对象需要改变时,可以使用观察者模式。
  • 当一个抽象模型有两个方面,其中一个依赖于另一个,使用观察者模式可以将这两者封装在独立的对象中,使它们可以独立地改变和复用。

示例代码

以下是一个简单的观察者模式示例,模拟了一个简单的气象站发布天气信息的场景:

import java.util.ArrayList;
import java.util.List;// 主题接口
interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}// 观察者接口
interface Observer {void update(float temperature, float humidity, float pressure);
}// 具体主题
class WeatherData implements Subject {private List<Observer> observers;private float temperature;private float humidity;private float pressure;public WeatherData() {observers = new ArrayList<>();}@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(temperature, humidity, pressure);}}public void measurementsChanged() {notifyObservers();}public void setMeasurements(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;measurementsChanged();}
}// 具体观察者
class CurrentConditionsDisplay implements Observer {private float temperature;private float humidity;@Overridepublic void update(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;display();}public void display() {System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");}
}public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();weatherData.registerObserver(currentDisplay);weatherData.setMeasurements(80, 65, 30.4f);}
}

在这个示例中,WeatherData 是具体主题,Display 是具体观察者。当气象站的温度发生变化时,会通知所有注册的观察者更新温度信息。

总结

观察者模式的优点包括降低耦合度、支持广播通信和扩展性好。在项目中,观察者模式常用于事件处理、消息通知和状态监控等场景。通过观察者模式,可以使系统的各个部分之间保持松散耦合,提高代码的灵活性和可维护性。

四. 策略模式(Strategy Pattern)

策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式可以让算法独立于使用它的客户端而变化,即客户端可以根据需要在运行时选择算法。在项目中,策略模式可以用于实现不同的算法或行为,使系统更灵活、可扩展和易于维护。

策略模式的角色

  1. Context(上下文):维护一个对策略对象的引用,在需要的时候调用策略对象的算法。
  2. Strategy(策略):定义所有支持的算法的公共接口,通常是一个接口或抽象类。
  3. ConcreteStrategy(具体策略):实现策略接口,提供具体的算法实现。

策略模式的优点

  • 算法独立性:可以在不影响客户端的情况下单独修改或替换算法。
  • 扩展性:易于增加新的算法或行为。
  • 复用性:可以将算法封装成独立的策略类,方便复用。

策略模式的应用场景

  • 当一个系统中有许多类只是在行为上有差别,可以使用策略模式来将这些行为封装到不同的策略类中,使得这些类可以方便地切换行为。
  • 当一个类的某个行为需要在运行时动态地选择时,可以使用策略模式。

示例代码

以下是一个简单的策略模式示例,模拟了一个电商系统根据不同的促销策略计算折扣价格的场景:

// 策略接口
interface DiscountStrategy {double applyDiscount(double amount);
}// 具体策略:打折策略
class PercentageDiscountStrategy implements DiscountStrategy {private double percentage;public PercentageDiscountStrategy(double percentage) {this.percentage = percentage;}@Overridepublic double applyDiscount(double amount) {return amount * (1 - percentage);}
}// 具体策略:满减策略
class FullReductionDiscountStrategy implements DiscountStrategy {private double full;private double reduction;public FullReductionDiscountStrategy(double full, double reduction) {this.full = full;this.reduction = reduction;}@Overridepublic double applyDiscount(double amount) {return amount >= full ? amount - reduction : amount;}
}// 上下文
class ShoppingCart {private DiscountStrategy discountStrategy;public void setDiscountStrategy(DiscountStrategy discountStrategy) {this.discountStrategy = discountStrategy;}public double checkout(double amount) {return discountStrategy.applyDiscount(amount);}
}public class StrategyPatternExample {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用打折策略cart.setDiscountStrategy(new PercentageDiscountStrategy(0.1));double discountedPrice = cart.checkout(100);System.out.println("打折后价格:" + discountedPrice);// 使用满减策略cart.setDiscountStrategy(new FullReductionDiscountStrategy(200, 50));discountedPrice = cart.checkout(250);System.out.println("满减后价格:" + discountedPrice);}
}

在这个示例中,DiscountStrategy 是策略接口,PercentageDiscountStrategyFullReductionDiscountStrategy 是具体策略。ShoppingCart 类是上下文,根据不同的促销策略计算折扣价格。

总结

总的来说,策略模式可以让算法的变化独立于使用算法的客户端,使得系统更灵活、可扩展和易于维护。

结论

设计模式是软件开发中的重要概念,通过合理应用设计模式,可以提高代码的质量和可维护性。在项目中应用设计模式需要根据具体情况选择合适的模式,并遵循设计模式的原则和规范。希望本文能帮助读者更好地理解和应用设计模式。

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

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

相关文章

【Leetcode】2583. 二叉树中的第 K 大层和

文章目录 题目思路代码结果 题目 题目链接 给你一棵二叉树的根节点 root 和一个正整数 k 。 树中的 层和 是指 同一层 上节点值的总和。 返回树中第 k 大的层和&#xff08;不一定不同&#xff09;。如果树少于 k 层&#xff0c;则返回 -1 。 注意&#xff0c;如果两个节点与根…

eureka 简介和基本使用

Eureka 是Netflix开发的服务发现框架&#xff0c;是Spring Cloud微服务架构中的一部分。它主要用于微服务架构中的服务注册与发现。Eureka由两部分组成&#xff1a;Eureka Server 和 Eureka Client。获取更详细的信息可以访问官网&#xff0c;如下图&#xff1a; Eureka Server…

【Docker 的安装:centos】

文章目录 1 :peach:各版本平台支持情况:peach:2 :peach:CentOS 安装:peach:2.1 :apple:安装依赖:apple:2.2 :apple:安装 Docker:apple:2.3 :apple:实战经验:apple:2.3.1 :lemon:Docker 镜像源修改:lemon:2.3.2 :lemon:Docker 目录修改:lemon: 1 &#x1f351;各版本平台支持情况…

Linux设备模型(二) - kset/kobj/ktype APIs

一&#xff0c;kobject_init_and_add 1&#xff0c;kobject_init_and_add实现 /** * kobject_init_and_add() - Initialize a kobject structure and add it to * the kobject hierarchy. * kobj: pointer to the kobject to initialize * ktype: p…

探索无限:Sora与AI视频模型的技术革命 - 开创未来视觉艺术的新篇章

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

Unity实现帧序列

一、目的 1.想实现序列帧效果 自己使用Animation一直无法实现动画播放效果 二、参考 1. Unity序列帧动画——Sprite图片集制作UI动画_unity 序列帧动画图集-CSDN博客 结果&#xff1a;很好用&#xff0c;能实现效果 三、实操 新建Image&#xff0c;增加Animator组件&#x…

【数据结构】排序(1)

目录 一、概念&#xff1a; 二、直接插入排序&#xff1a; 三、希尔排序&#xff1a; 四、直接选择排序&#xff1a; 五、堆排序&#xff1a; 六、冒泡排序&#xff1a; 一、概念&#xff1a; 排序的概念&#xff1a; 使一串记录&#xff0c;按照其中的某个或某些关键字…

【电路笔记】-RC放电电路

RC放电电路 文章目录 RC放电电路1、概述2、RC放电电路3、RC放电电路示例当电压源从完全充电的 RC 电路中移除时,电容器 C 将通过电阻 R 放电。 1、概述 RC 放电电路利用电阻器-电容器组合的固有 RC 时间常数以指数衰减率对电容器进行放电。 在之前的 RC 充电电路教程中,我们…

向量的组成

向量是有序的一维数组&#xff0c;其中包含多个标量元素。每个元素都有一个索引&#xff0c;表示其在向量中的位置。在数学表示中&#xff0c;我们通常用小写粗体字母表示向量&#xff0c;如 v。 关于向量、张量、标量与矩阵的关系可以参见另一篇文章&#xff1a;线性代数&…

开源免费的NTFS for mac工具mounty

开源免费的NTFS for mac工具mounty 安装依赖 brew install gromgit/fuse/ntfs-3g-macbrew install --cask macfuse安装mounty 如果已经安装macFUSE和ntfs-3g-mac&#xff0c;可以直接点击下载的dmg安装包&#xff0c;安装升级。第一次启动mounty&#xff0c;你需要接受一系列…

项目优化-

前言 用户浏览菜品&#xff0c;添加购物车&#xff0c;下单等操作最终都会反映成一个sql&#xff0c;操作数据库。 但是当前系统只部署了一台数据库&#xff0c;读和写所有压力都由一台数据库承担&#xff0c;压力大&#xff1b;如果数据库服务器磁盘损坏则数据丢失&#xff0…

【这个词(Sequence-to-Sequence)在深度学习中怎么解释,有什么作用?】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;深度学习笔记 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; Sequence-to-Sequence&#xff08;Seq2Seq&#xff09; Sequence-to-Sequence&#xff08;Seq2Seq…

【论文阅读】ICCV 2023 计算和数据高效后门攻击

文章目录 一.论文信息二.论文内容1.摘要2.引言3.主要图表4.结论 一.论文信息 论文题目&#xff1a; Computation and Data Efficient Backdoor Attacks&#xff08;计算和数据高效后门攻击&#xff09; 论文来源&#xff1a; 2023-ICCV&#xff08;CCF-A&#xff09; 论文团…

【DDD】学习笔记-薪资管理系统的测试驱动开发

回顾薪资管理系统的设计建模 在 3-15 课&#xff0c;我们通过场景驱动设计完成了薪资管理系统的领域设计建模。既然场景驱动设计可以很好地与测试驱动开发融合在一起&#xff0c;因此根据场景驱动设计的成果来开展测试驱动开发&#xff0c;就是一个水到渠成的过程。让我们先来…

List集合之UML、特点、遍历方式、迭代器原理、泛型、装拆箱及ArrayList、LinkedList和Vector的区别

目录 ​编辑 一、什么是UML 二、集合框架 三、List集合 1.特点 2.遍历方式 3.删除 4.优化 四、迭代器原理 五、泛型 六、装拆箱 七、ArrayList、LinkedList和Vector的区别 ArrayList和Vector的区别 LinkedList和Vector的区别 一、什么是UML UML&#xff08;Unif…

前端项目打包体积分析与优化

一、安装依赖分析工具 npm install webpack-bundle-analyz 二、修改webpack.config.js文件 1、导入上面下载的包 2、在plugins里创建实例 三、启动打包命令 npm run build 会弹出如下界面&#xff1a; 四、优化 1、通过CDN导入react-dom文件 修改webpack.config.js文件里…

Windows 远程控制 Mac 电脑怎么操作

要从 Windows 远程控制 Mac 电脑&#xff0c;您可以使用内置 macOS 功能或第三方软件解决方案。以下是一些方法&#xff1a; 一、使用内置 macOS 功能&#xff08;屏幕共享&#xff09; 1、在 macOS 上启用屏幕共享 转至系统偏好设置 > 共享&#xff1b;选中“屏幕共享”…

八、线性代数二 ,矩阵的秩

目录 1、矩阵子式的定义与子式个数的计算&#xff1a; 2、矩阵秩的定义&#xff1a; 3、矩阵秩的计算方法&#xff1a; 4、矩阵秩的 性质&#xff1a; 线性代数四——几个重要的矩阵点积_线性代数 矩阵点积-CSDN博客 1、矩阵子式的定义与子式个数的计算&#xff1a; 概念&…

C# OpenCvSharp 利用白平衡技术进行图像修复

目录 效果 灰度世界(GrayworldWB)-白平衡算法 完美反射(SimpleWB)-白平衡算法 基于学习的(LearningBasedWB)-白平衡算法 代码 下载 C# OpenCvSharp 利用白平衡技术进行图像修复 OpenCV xphoto模块中提供了三种不同的白平衡算法&#xff0c;分别是&#xff1a;灰度世界(G…

华清远见嵌入式学习——驱动开发——day9

目录 作业要求&#xff1a; 作业答案&#xff1a; 代码效果&#xff1a; ​编辑 Platform总线驱动代码&#xff1a; 应用程序代码&#xff1a; 设备树配置&#xff1a; 作业要求&#xff1a; 通过platform总线驱动框架编写LED灯的驱动&#xff0c;编写应用程序测试&…