Java设计模式以及代理模式
一、设计模式
1.JAVA六大设计原则
JAVA设计模式提供六个基本原则,分别是:
- 开闭原则(OCP) - The Open-Closed Principle
- 单一职责原则(SRP) - Single Responsibility Principle
- 里氏替换原则(LSP) - Liskov Substitution Principle
- 依赖倒置原则(DIP) - Dependency Inversion Principle
- 接口隔离原则(ISP) - Interface Segregation Principle
- 迪米特法则(DP) - Demeter Principle
2.JAVA23种设计模式
在软件工程当中,设计原则和设计模式是不同的.
3.设计原则
设计原则是为了更好的设计软件的高层指导方针.
它不提供具体的实现方式也不会绑定任何一种编程语言.
最常用的原则是SOLID(SRP, OCP, LSP, ISP, DIP)原则
4.设计模式
设计模式对关于面向对象问题的具体解决方案.
比如说, 如果你想创建一个类而且它在任何时刻只会有一个对象,那么你就应该使用单例类模式.
设计模式是经过大量检测的安全的做法.
4.1 工厂模式(factory)
案例:
INoodles:
package com.ztt.test;public interface INoodles {public void noodleType();
}
LanZhouLaMianImp:
package com.ztt.test;public class LanZhouLaMianImp implements INoodles{@Overridepublic void noodleType() {System.out.println("========来一碗兰州拉面========");}
}
ReGanMianNoodleImp:
package com.ztt.test;public class ReGanMianNoodleImp implements INoodles{@Overridepublic void noodleType() {System.out.println("========来一碗武汉热干面========");}
}
YouPoMianNoodleImp:
package com.ztt.test;public class YouPoMianNoodleImp implements INoodles{@Overridepublic void noodleType() {System.out.println("========来一碗油泼面========");}
}
NoodleFactory:
package com.ztt.test;
/*** 面长* */
public class NoodleFactory {/*** 规范下面条类型* */public static final int NOODLE_YOUPO = 1;public static final int NOODLE_REGAN = 2;public static final int NOODLE_LANZHOULA = 3;/***创建面条**/public static INoodles getNoodle(int type){if (type == 1){return new YouPoMianNoodleImp();}else if(type ==2){return new ReGanMianNoodleImp();}else if(type ==3 ){return new LanZhouLaMianImp();}return null;}}
package com.ztt.test;public class Test01 {public static void main(String[] args) {NoodleFactory.getNoodle(NoodleFactory.NOODLE_LANZHOULA).noodleType();NoodleFactory.getNoodle(3).noodleType();}
}
4.2 单列设计模式(singlton)
饿汉式:
package com.ztt.hungrytest;
/*** 饿汉式* */
public class Student {//3.创建static修饰的成员变量private static Student stu = new Student();//1.设计私有构造方法private Student(){super();}//2.提供共有的方法public static synchronized Student getInstance(){return stu;}}
package com.ztt.hungrytest;import com.ztt.lazytest.Student;
public class Test03 {public static void main(String[] args) {com.ztt.lazytest.Student stu1 = com.ztt.lazytest.Student.getInstance();Student stu2 = Student.getInstance();System.out.println(stu1== stu2);}}
懒汉式:
package com.ztt.lazytest;
/*** 懒汉式* */
public class Student {//3.创建static修饰的成员变量private static Student stu;//1.设计私有构造方法private Student(){super();}//2.提供共有的方法public static synchronized Student getInstance(){if(stu == null){stu = new Student();}return stu;}}
package com.ztt.lazytest;public class Test02 {public static void main(String[] args) {Student stu1 = Student.getInstance();Student stu2 = Student.getInstance();System.out.println(stu1== stu2);}}
六、代理模式
1.什么是代理模式?
- 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
- 通俗的来讲代理模式就是我们生活中常见的中介。
- 举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,
- 做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。
- 我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介
- 公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择
- 自己喜欢的车,然后付钱就可以了。
2.为什么要用代理模式?
2.1 中介隔离作用:
在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
2.2 开闭原则,增加功能:
代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。
3.有哪几种代理模式?
我们有多种不同的方式来实现代理。如果按照代理创建的时期来进行分类的话可以分为两种:
3.1 静态代理:
静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。
在程序员运行之前,代理类.class文件就已经被创建了。
静态代理案例:
package com.ztt.statictest;public interface IWonman {public void makeEyeWithMan();
}
package com.ztt.statictest;public class PanJinLianImp implements IWonman{@Overridepublic void makeEyeWithMan() {System.out.println("回眸一笑,抛个媚眼~");}
}
package com.ztt.statictest;//代理
public class WangPoImp implements IWonman{//被代理对象IWonman obj;public WangPoImp(IWonman obj) {this.obj = obj;}@Overridepublic void makeEyeWithMan() {System.out.println("镇一壶酒,搞搞气氛~");obj.makeEyeWithMan();}
}
package com.ztt.statictest;public class XiMenQingTest {public static void main(String[] args) {//1.创建被代理对象IWonman pan = new PanJinLianImp();//2.创建代理IWonman wang = new WangPoImp(pan);wang.makeEyeWithMan();}
}
3.2 动态代理:
动态代理是在程序运行时通过反射机制动态创建的。
动态代理分为:
基于接口的动态代理(jdk自带)
基于子类的动态代理(第三方)
3.2.1 动态代理jdk自带的案例:
package com.ztt.jdktest;/*** @author 甜甜* @version 1.0* @since 2024/8/8*/
public interface ISinger {public void sing();public int dance(int num);
}
package com.ztt.jdktest;/*** @author 甜甜* @version 1.0* @since 2024/8/8*/
public class XuezhiqianImp implements ISinger{@Overridepublic void sing() {System.out.println("唱歌");}@Overridepublic int dance(int num) {System.out.println("跳舞");return 0;}
}
package com.ztt.jdktest;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** @author 甜甜* @version 1.0* @since 2024/8/8*/
public class Test01 {public static void main(String[] args) {//1.创建被代理对象final ISinger xue = new XuezhiqianImp();//2.创建代理对象ISinger jingJiRen = (ISinger) Proxy.newProxyInstance(xue.getClass().getClassLoader(), xue.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("===做个自我介绍===");Object obj = method.invoke(xue,args);return obj;}});jingJiRen.sing();//jingJiRen.dance(6);}
}
3.2.2 动态代理第三方案例:
① 导入坐标
<dependencies><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.2.2</version></dependency></dependencies>
② 代码展示:
package com.ztt.cglibtest;/*** @author 甜甜* @version 1.0* @since 2024/8/8*/
public interface ISinger {public void sing();
}
package com.ztt.cglibtest;/*** @author 甜甜* @version 1.0* @since 2024/8/8*/
public class TengGeErImp implements ISinger{@Overridepublic void sing() {System.out.println("听了赵雷的成都去了成都,听了汪峰的北京去了北京,至今不敢听腾格尔的天堂~");}
}
package com.ztt.cglibtest;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;import java.lang.reflect.Method;/*** @author 甜甜* @version 1.0* @since 2024/8/8*/
public class Test02 {public static void main(String[] args) {//创建被代理对象final ISinger teng = new TengGeErImp();//创建代理对象ISinger jing=(ISinger) Enhancer.create(teng.getClass(), teng.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {Object object = method.invoke(teng,objects);return object;}});jing.sing();}
}
相关文章:
Java设计模式以及代理模式
一、设计模式 1.JAVA六大设计原则 JAVA设计模式提供六个基本原则,分别是: 开闭原则(OCP) - The Open-Closed Principle单一职责原则(SRP) - Single Responsibility Principle里氏替换原则(LSP) - Liskov Substitution Principle依赖倒置原则(DIP) - D…...
Elasticsearch 索引库管理:查询、修改与删除
Elasticsearch 是一个高度可扩展的开源全文搜索和分析引擎,它允许用户通过 RESTful API 进行数据的索引、搜索、更新和管理。在 Elasticsearch 中,索引库(Index)是存储数据的基本单元。本文将介绍如何查询、修改和删除 Elasticsea…...

视频大怎么压缩小?分享3种视频压缩方法
视频大怎么压缩小?视频文件过大时,压缩视频不仅能帮助我们节省宝贵的存储空间,使其更容易在有限容量的设备中保存,还能显著提升传输效率,特别是在网络条件有限或需要快速分享视频内容的场合。通过专业的压缩工具&#…...

springboot项目搭建集成 redis/跨域/远程请求
目录 一,创建maven项目 1,左上角file > new > maven project 2,next 到 创建 Group id 和 Artifact id编辑编辑 二,配置springboot 1,配置pom文件, 2,创建启动类 3ÿ…...

lvs详解及实例配置
目录 1.什么是负载均衡 1.1为什么用负载均衡 1.2.负载均衡类型 1.2.1.四层负载均衡 1.2.2.七层负载均衡 1.3 四层和七层的区别 2.LVS介绍 2.1LVS 的优势与不足 2.2LVS 核心组件和专业术语 3.ipvsadm命令 4.LVS集群中的增删改 4.1.管理集群服务中的增删改 4.2.管理集…...
DAY41-动态规划-买卖股票
LeetCode121. 买卖股票的最佳时机 public int maxProfit(int[] prices) {//dp数组含义:0为持有该股票,1为不持有该股票int[][] dp new int[prices.length][2];dp[0][0]-prices[0];dp[0][1]0;for(int i1;i<prices.length;i) {dp[i][0]Math.max(dp[i-…...
【C#】StringComparer
什么是“文化” 在 .NET 中,“文化”(Culture)指的是与语言、地区、和区域设置相关的特定信息集合。这些信息包括了日期和时间的格式、数字的表示方式、货币符号、字符串比较规则等等。文化的概念在软件开发中特别重要,因为应用程…...
阿里云服务器远程登录问题解决指南
前言 在使用阿里云服务器时,可能会遇到无法通过密码进行远程登录的情况。这种情况通常是因为操作系统默认禁用了密码登录功能。本文将介绍如何解决这一问题,确保能够顺利地通过密码进行远程登录。 问题描述 当尝试通过Workbench进行密码登录时&#x…...

Datawhale X 魔搭 AI夏令营(2024第四期)AIGC方向 学习笔记
粗谈 这一期是使用可图lora微调进行文生图任务的比赛 文生图也算是跨模态了,输入Prompt文本,输出图片。Prompt很重要,分为prompts和negative prompts。可以指导结果图片的生成。 lora可以参考我上期夏令营的文章:Datawhale AI 夏令营&…...

VScode前端环境搭建
前言 VScode是企业中最常用的前端开发工具,本文描述如何利用VScode搭建前端开发环境 一、安装VScode 下载Vscode 点击前往下载页面 安装 安装时一直点击下一步即可 二、环境配置 1)更改语言 点击拓展搜索Chinese后下载第一个,下载完后…...
Python自动化测试之selenium - 元素定位
元素定位 元素定位就是通过元素的信息或者元素层级结构来定位元素。当定位到了重复的属性,默认会定位到第一个标签。 id定位 - find_element_by_id 同一个html页面中id值是唯一的。 模拟在百度输入框中输入想要查找的内容 python 代码解读 复制代码 from sel…...
深入探索 npm cache clean --force:清理 npm 缓存的艺术
npm 是 JavaScript 编程语言的包管理器,它是 Node.js 运行环境的默认包管理器。npm 提供了一个丰富的生态系统,包括数以百万计的可重用代码包。然而,随着时间的推移,npm 的缓存可能会变得庞大,影响性能或导致一些奇怪的…...
如何看待“低代码”开发平台的兴起?
如何看待“低代码”开发平台的兴起? 近年来,“低代码”开发平台如雨后春笋般涌现,承诺让非专业人士也能快速构建应用程序。这种新兴技术正在挑战传统软件开发模式,引发了IT行业的广泛讨论。低代码平台是提高效率的利器࿰…...

自动控制——过阻尼、欠阻尼、临界阻尼及无阻尼
自动控制——过阻尼、欠阻尼、临界阻尼及无阻尼 引言 在自动控制系统和振动分析中,系统的阻尼特性对于系统的动态响应至关重要。阻尼决定了系统在受到扰动或输入信号后,如何恢复到稳定状态。本文将详细介绍过阻尼(overdamped)、…...

从AlphaGo到AlphaPong:AI乒乓球机器人将如何改变乒乓球竞技?
在人工智能领域,谷歌DeepMind的AlphaGo曾以其超凡的围棋能力震惊了世界。而如今,DeepMind又将其技术延伸到了乒乓球领域,推出了乒乓球机器人,被网友戏称为“AlphaPong”。这一机器人使用ABB的IRB1100机械手臂,能够与普…...

荒原之梦:考研期间可以玩游戏吗?
有不少同学,特别是男同学,在考研之前,会有玩游戏的习惯,那么,对于考研的同学来说,就会产生这样一个疑问。在考研备考期间,我还可以玩游戏吗? 其实关于这个问题的答案是因人而异的&am…...

Hive SQL ——窗口函数源码阅读
前言 使用Starrocks引擎中的窗口函数 row_number() over( )对10亿的数据集进行去重操作,BE内存溢出问题频发(忘记当时指定的BE内存上限是多少了.....),此时才意识到,开窗操作,如果使用 不当,反而…...

用python的Manim 创建大括号
Brace 是 Manim 中用于创建大括号(curly braces)的一个对象类。它有几个子类,自定义了不同的功能。下面是每个类的简要解释: 1. ArcBrace 功能: 创建一个环绕弧线的括号。适用于需要围绕弧形线条的场景。用法: 通常用于图形中有…...
白骑士的Matlab教学附加篇 5.2 代码规范与最佳实践
系列目录 上一篇:白骑士的Matlab教学附加篇 5.1 MATLAB开发工具 在 MATLAB 编程中,遵循良好的代码规范和最佳实践有助于提高代码的可读性、可维护性和可重用性。无论是变量命名、注释风格,还是代码格式化,合理的规…...
Javaweb--SpringBoot
1.SpringBoot入门 简化Spring开发的一个框架,Spring Boot 旨在帮助开发者快速搭建 Spring 框架。 整个Spring的一个合集,可以简化配置 2.微服务 (1)微服务就是一种架构风格 (2)微服务就是把一个项目拆…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

Element-Plus:popconfirm与tooltip一起使用不生效?
你们好,我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip,产品要求是两个需要结合一起使用,也就是鼠标悬浮上去有提示文字,并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...