Java之设计模式

概述

设计模式就是经过我们开发人员通过长时间的开发实践得出的一种开发模式,目的就是在开发过程中降低代码耦合度,提高代码可复用性/扩展/维护。目前主要有23种设计模式,分为创建型模式、行为型模式、结构型模式。本文列举了实际项目中使用到的设计模式,包括单例模式、策略模式、代理模式

创建型模式

单例模式

  • 目的就是解决一个类Class在应用程序中只有一个实例存在,并提供对外的全局访问
  • 构造函数私有化、对外提供获取实例静态方法
  • 项目实践
    • 在多线程环境中缓存文件操作记录到队列中,后续通过定时任务添加到数据库
  • public class LazyQueueSingleton {private static int QUEUE_MAX_SIZE = 80000;// LinkedBlockingQueue线程安全的共享队列,并设置队列初始大小避免内存溢出private volatile Queue<HistoryRecords> ShareQueue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE);private static final Object lockedObj = new Object();//懒汉式队列单例,保证实例全局唯一 private static volatile LazyQueueSingleton INSTANCE;private LazyQueueSingleton() {if(ShareQueue == null) {ShareQueue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE);}}public static LazyQueueSingleton getInstance() {if(INSTANCE == null) {synchronized (lockedObj) {if(INSTANCE == null) {INSTANCE = new LazyQueueSingleton();}}}return INSTANCE;}public Queue<HistoryRecords> getPendingTodoQueue() {return ShareQueue;}
    }

行为型模式

策略(Strategy)模式

  • 定义了一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。常常适用于业务存在很多复杂分支场景
  • 上下文/Context(持有一个策略对象的引用,通过该引用来调用算法或行为)、策略/Strategy(定义所有支持的算法的公共接口)、具体策略/Concrete Strategy(实现策略接口的具体算法或行为)
  • 项目实践
    • 系统需要根据不同部门来计算报表生成的内容
    • // 1.定义策略接口
      public interface GernerateReportStrategy {boolean calculateReport(int departmentId);
      }// 2.实现具体策略
      public class BDGernerateReportStrategy implements GernerateReportStrategy {@Overridepublic boolean calculateReport(int departmentId) {......}
      }
      public class SwGernerateReportStrategy implements GernerateReportStrategy {@Overridepublic boolean calculateReport(int departmentId) {......}
      }
      // 3.创建上下文
      public class DownloadReportContext {private GernerateReportStrategy gernerateReportStrategy;public void setGernerateReportStrategy(GernerateReportStrategy gernerateReportStrategy) {this.gernerateReportStrategy = gernerateReportStrategy;}......
      }
      // 4.接下来就可以使用了,若后续有新增部门则直接实现具体策略类即可

结构型模式

代理模式

  • 核心思想:是为其他对象提供一种代理以控制对这个对象的访问
  • 角色:代理角色、真实/原始/目标角色
  • 作用:一是保护真实/原始/目标对象,二是增强真实/原始/目标对象
静态代理
  • 静态代理是一种在编译时就已经确定代理类和目标对象关系的代理模式。它通常通过创建一个接口和两个实现这个接口的类(一个为目标对象类,另一个为代理类)来实现
  • 代码实践
    • // 1.定义一个接口,该接口包含一个或多个方法
      interface Service {void execute();
      }
      // 2.创建一个目标对象类,它实现这个接口
      class RealService implements Service {public void execute() {System.out.println("Executing real service.");}
      }
      // 3.创建一个代理类,也实现这个接口,并包含对目标对象的引用。也可以在调用目标对象的方法之前或之后添加额外的操作
      class ProxyService implements Service {private RealService realService;public ProxyService(RealService realService) {this.realService = realService;}public void execute() {System.out.println("Before execution.");realService.execute();System.out.println("After execution.");}
      }
      // 4.客户端使用
      Service service = new ProxyService(new RealService());
      service.execute();

动态代理
  • 动态代理是一种在运行时动态创建代理对象的代理模式。它不需要事先编写代理类的代码,而是在运行时根据目标对象动态生成代理类
  • 项目实践
    • // 1. 定义接口
      public interface Report {void generateReportByDepartmentId(int departmentId);void generateReportByDepartmentName(String departmentName);
      }
      // 2. 定义目标/原始/真实对象
      public class generateReport implements Report {@Overridepublic void generateReportByDepartmentId(int departmentId) {System.out.println("按部门ID已生成报表:" + departmentId);}@Overridepublic void generateReportByDepartmentName(String departmentName) {System.out.println("按部门名称已生成报表:" + departmentName);}
      }
      // 3. 定义代理对象
      public class ReportJDKProxy implements InvocationHandler {//需要被代理的对象private Object object;public ReportJDKProxy(Object object) {this.object = object;}@SuppressWarnings("unchecked")public <T> T getProxy(){// 使用反射API动态创建代理类return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),//当前线程的上下文ClassLoaderobject.getClass().getInterfaces(), //代理需要实现的接口this); // 处理器自身}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;//进行方法匹配,调用对应方法名的方法if ("generateReportByDepartmentId".equals(method.getName())) {System.out.println("按部门ID已生成报表------前置增强------");result=method.invoke(object, args);System.out.println("按部门ID已生成报表------后置增强------");}if ("generateReportByDepartmentName".equals(method.getName())) {System.out.println("按部门名称已生成报表------前置增强------");result=method.invoke(object, args);System.out.println("按部门名称已生成报表------后置增强------");}return result;}
      }
      // 4. 客户端使用// 调用方式一Report player=new generateReport(); Report proxy=new ReportJDKProxy(player).getProxy(); proxy.generateReportByDepartmentId(666);proxy.generateReportByDepartmentName("SW");/** // 调用方式二 * Report p=new generateReport(); * Report o = (Report)Proxy.newProxyInstance( p.getClass().getClassLoader(),p.getClass().getInterfaces(), new ReportJDKProxy(p) );* o.generateReportByDepartmentId(666); * o.generateReportByDepartmentName("SW");*/

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

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

相关文章

分布式和集群区别

分布式 分布式的主要工作是分解任务&#xff0c;将职能拆解&#xff0c;多个人在一起做不同的事 集群 集群主要是将同一个业务&#xff0c;部署在多个服务器上 &#xff0c;多个人在一起做同样的事

GPT-3:自然语言处理的预训练模型

自然语言处理&#xff08;NLP&#xff09;领域近年来取得了显著的进步&#xff0c;特别是预训练模型的引入&#xff0c;彻底改变了我们与计算机交互和处理自然语言的方式。在这些模型中&#xff0c;GPT-3&#xff08;Generative Pre-trained Transformer 3&#xff09;无疑是最…

Spring常见注解

Spring常见注解 1. 概述2. DI&#xff08;依赖注⼊&#xff09;相关注解2.1 Autowired2.2 Bean2.3 Qualifier2.4 Required &#xff08;很少使用&#xff09;2.5 Value2.6 Lazy2.7 Profile 1. 概述 我们都知道Spring最核心的特性就是IOC&#xff08;控制反转&#xff09; AOP&…

PySODEvalToolkit 使用笔记

1. 克隆仓库 首先&#xff0c;克隆PySODEvalToolkit仓库到你的本地机器&#xff1a; git clone https://github.com/lartpang/PySODEvalToolkit.git2. 创建虚拟环境 cd PySODEvalToolkit conda create -n pysodeval python3.73. 安装依赖 pip install -r requirements.txt4…

[算法] 优先算法(一): 双指针算法(上)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

SpringBoot2.0.x旧版集成Swagger UI报错Unable to infer base url...解决办法

一、问题描述 1.1项目背景 SpringBoot2.0.9的旧版项目维护开发&#xff0c;集成Swagger-ui2.9.2无法访问的问题。不用想啊&#xff0c;这种老项目是各种过滤器拦截器的配置&#xff0c;访问不到&#xff0c;肯定是它们在作妖。懂得都懂啊&#xff0c;这里交给大家一个排错的办…

Flutter设计模式全面解析:单例模式

谈到设计模式这个“古老”的话题&#xff0c;大家先别急着划走哈&#xff0c;虽然对它再熟悉不过&#xff0c;几乎是最初开始学习编程到现在伴随着我们整个编程生涯&#xff0c;最早 Java、C 语言实现的各种设计模式到现在还会经常有所接触&#xff0c;面试中也是必问的环节&am…

Adobe Camera Raw 11 for Mac/win:摄影后期处理的革命性飞跃

在数字摄影的世界里&#xff0c;RAW格式以其未压缩的原始数据特性&#xff0c;为摄影师提供了更大的后期处理空间。而Adobe Camera Raw 11&#xff0c;作为这一领域的翘楚&#xff0c;以其卓越的性能和创新的功能&#xff0c;为摄影师们带来了前所未有的创作体验。 Adobe Came…

LeetCode450删除二叉搜索树中的节点

题目描述 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。一般来说&#xff0c;删除节点可分为两个步骤&#xff1…

Linux环境中部署docker私有仓库Registry与远程访问详细流程

目录 前言 1. 部署Docker Registry 2. 本地测试推送镜像 3. Linux 安装cpolar 4. 配置Docker Registry公网访问地址 5. 公网远程推送Docker Registry 6. 固定Docker Registry公网地址 前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊…

网络安全知识核心20要点

1、什么是SQL注入攻击 概述 攻击者在 HTTP 请求中注入恶意的 SQL 代码&#xff0c;服务器使用参数构建数据库 SQL 命令时&#xff0c;恶意SQL 被一起构造&#xff0c;并在数据库中执行。 注入方法 用户登录&#xff0c;输入用户名 lianggzone&#xff0c;密码‘ or ‘1’’…

揭秘Python的魔法:装饰器的超能力大揭秘 ‍♂️✨

文章目录 Python进阶之装饰器详解1. 引言装饰器的概念与意义装饰器在Python编程中的作用 2. 背景介绍2.1 函数作为对象2.2 高阶函数 3. 装饰器基础3.1 理解装饰器3.2 装饰器的工作原理 4. 带参数的装饰器4.1 为什么需要带参数4.2 实现带参数的装饰器使用函数包裹装饰器使用类实…

TypeScript-泛型

泛型(Generics) 指在定义接口&#xff0c;函数等类型的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性&#xff0c;使用泛型可以复用类型并且让类型更加灵活 泛型接口-interface 语法&#xff1a;在 interface 接口类型的名称后面使用…

AI服务器连接解决方案领军企业Astera Labs宣布,将在台湾组建首个位于硅谷以外的Cloud-Scale Interop Lab

AI服务器连接解决方案领军企业Astera Labs宣布&#xff0c;将在台湾组建首个位于硅谷以外的Cloud-Scale Interop Lab&#xff0c;集结中国台湾制造商共同参与。据《工商时报》报道&#xff0c;Astera Labs将与台湾主要ODM客户紧密合作&#xff0c;预期广达、英业达、纬创资通、…

web前端的路径和Servlet注解开发

目录 在web前端的两种路径 绝对路径的两种写法 相对路径 相对路径进阶 使用注解开发Servlet 使用注解开发Servlet的注意事项 使用idea创建servlet模板 在web前端的两种路径 绝对路径的两种写法 1.带网络三要素 http://ip地址:端口号/资源路径 2.不带网络三要素 /资源路…

『哈哥赠书 - 53期』-『深入浅出 Spring Boot 3.x』

⭐️ 《深入浅出 Spring Boot 3.x》 ⭐️ 学习Spring Boot的必读之书 在 Java 后端开发领域&#xff0c;功能强大的 Spring 开源框架不仅是首选&#xff0c;也是事实上的标准。但由于 Spring 存在配置烦琐、部署不易、依赖管理困难等问题&#xff0c;因此基于 Spring 的快速开…

告别传统,拥抱未来——上门回收小程序引领变革

随着科技的飞速发展&#xff0c;我们生活的方方面面都在经历着前所未有的变革。在环保和可持续发展的背景下&#xff0c;传统的废品回收方式已经难以满足现代社会的需求。而上门回收小程序的出现&#xff0c;正以其便捷、高效的特点&#xff0c;引领着废品回收行业的变革。 一、…

【NLPl练习】Transformer起源与发展

Transformer总结 Transformer模型类别分为&#xff1a; 纯Encoder模型纯Decoder模型Encoder-Decoder模型 Transformer模型的本质是预训练语言模型&#xff0c;首先采用自监督学习的方式在大量生语料库上训练&#xff0c;无需人工标注。常用的预训练任务主要有以下两个&#xff…

力扣343 整数拆分 Java版本

文章目录 题目描述代码 题目描述 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输…

Leedcode69:x的平方根_Java解法

Problem: 69. x 的平方根 题目描述思路解题方法复杂度Code 题目描述 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数函数和…