原型,模板,策略,适配器模式
原型模式
原型模式(创建型模式),核心思想就是:基于一个已有的对象复制一个对象出来,通过复制来减少对象的直接创建的成本。
总结一下,原型模式的两种方法,浅拷贝只会复制对象里面的基本数据类型和引用对象的内存地址,不会递归地复制引用对象,以及引用对象的引用对象。而深拷贝就是会完全拷贝一个新的对象出来。所以,深拷贝的操作会比浅拷贝更加耗时,性能更差一点。同时浅拷贝的代码写起来也比深拷贝的代码写起来更简单一点。如果咱们拷贝的对象是不可变的,也就是说我这个对象只会查看,不会增删改,那么,直接用浅拷贝就好了,如果拷贝的对象存在增删改的情况,那么就需要使用深拷贝了。总而言之,就是要深浅得当,根据项目实际情况而定。
代码举例
// 原型接口
interface Shape extends Cloneable {void draw();Shape clone();
}// 具体原型类 - 圆形
class Circle implements Shape {private String color;public Circle(String color) {this.color = color;}@Overridepublic void draw() {System.out.println("Drawing a circle with color: " + color);}@Overridepublic Shape clone() {return new Circle(color);}
}// 具体原型类 - 正方形
class Square implements Shape {private String color;public Square(String color) {this.color = color;}@Overridepublic void draw() {System.out.println("Drawing a square with color: " + color);}@Overridepublic Shape clone() {return new Square(color);}
}// 原型管理器
class ShapeCache {private static Map<String, Shape> shapeMap = new HashMap<>();public static Shape getShape(String type) {Shape cachedShape = shapeMap.get(type);return (Shape) cachedShape.clone();}public static void loadCache() {Circle circle = new Circle("red");shapeMap.put("circle", circle);Square square = new Square("blue");shapeMap.put("square", square);}
}// 示例使用
public class PrototypePatternExample {public static void main(String[] args) {ShapeCache.loadCache();Shape clonedShape1 = ShapeCache.getShape("circle");clonedShape1.draw(); // 输出: Drawing a circle with color: redShape clonedShape2 = ShapeCache.getShape("square");clonedShape2.draw(); // 输出: Drawing a square with color: blue}
}
模板模式
模板方法模式也非常简单,但是,他却是比较重要的,在很多开源框架里面都用到了这个模式,并且,我们在做项目的时候,也会经常用到这个模式。这个模板方法模式,简单来说就是一句话:在父类中定义业务处理流程的框架,到子类中去做具体的实现。
代码举例
// 抽象模板类
abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 模板方法,定义算法框架public final void play() {initialize();startPlay();endPlay();}
}// 具体模板类 - 足球游戏
class FootballGame extends Game {@Overridevoid initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Playing football...");}@Overridevoid endPlay() {System.out.println("Football Game Finished!");}
}// 具体模板类 - 篮球游戏
class BasketballGame extends Game {@Overridevoid initialize() {System.out.println("Basketball Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Playing basketball...");}@Overridevoid endPlay() {System.out.println("Basketball Game Finished!");}
}// 示例使用
public class TemplatePatternExample {public static void main(String[] args) {Game footballGame = new FootballGame();footballGame.play();// 输出:// Football Game Initialized! Start playing.// Playing football...// Football Game Finished!System.out.println();Game basketballGame = new BasketballGame();basketballGame.play();// 输出:// Basketball Game Initialized! Start playing.// Playing basketball...// Basketball Game Finished!}
}
策略模式
接着我们来看一下策略模式,策略模式呢也是非常简单,他就是定义一个主要的接口,然后很多个类去实现这个接口,比如说我们定义一个文件上传的接口,然后阿里云的上传类去实现它,腾讯云的上传类也去实现它,这样因为都是实现的同一个接口,所以上传类之间是可以在代码中互相替换的。
代码举例
// 策略接口
interface Strategy {int doOperation(int num1, int num2);
}// 具体策略类 - 加法
class AddStrategy implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}// 具体策略类 - 减法
class SubtractStrategy implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}// 上下文类
class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int num1, int num2) {return strategy.doOperation(num1, num2);}
}// 示例使用
public class StrategyPatternExample {public static void main(String[] args) {Context context = new Context(new AddStrategy());int result1 = context.executeStrategy(10, 5);System.out.println("10 + 5 = " + result1); // 输出: 10 + 5 = 15context = new Context(new SubtractStrategy());int result2 = context.executeStrategy(10, 5);System.out.println("10 - 5 = " + result2); // 输出: 10 - 5 = 5}
}
委派模式
委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式,基本作用就是负责任务的调用和分配;是一种特殊的静态代理,可以理解为全权代理(代理模式注重过程,而委派模式注重结果),委派模式属于行为型模式,不属于GOF23种设计模式;
代码举例
// 委派接口
interface Printer {void print();
}// 具体委派类 - 打印机A
class PrinterA implements Printer {@Overridepublic void print() {System.out.println("Printer A is printing.");}
}// 具体委派类 - 打印机B
class PrinterB implements Printer {@Overridepublic void print() {System.out.println("Printer B is printing.");}
}// 委派类
class PrinterManager {private Printer printer;public void setPrinter(Printer printer) {this.printer = printer;}public void print() {printer.print();}
}// 示例使用
public class DelegatePatternExample {public static void main(String[] args) {PrinterManager printerManager = new PrinterManager();// 使用打印机APrinterA printerA = new PrinterA();printerManager.setPrinter(printerA);printerManager.print(); // 输出: Printer A is printing.System.out.println();// 使用打印机BPrinterB printerB = new PrinterB();printerManager.setPrinter(printerB);printerManager.print(); // 输出: Printer B is printing.}
}
适配器模式
适配器模式也比较简单,核心思想就是是:将一个类的接口转换成客户希望的另一个接口,讲白了就是通过适配器可以将原本不匹配、不兼容的接口或类结合起来;
代码举例
// 目标接口
interface Target {void request();
}// 适配者类
class Adaptee {public void specificRequest() {System.out.println("Specific request from Adaptee.");}
}// 适配器类
class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}// 示例使用
public class AdapterPatternExample {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target adapter = new Adapter(adaptee);adapter.request(); // 输出: Specific request from Adaptee.}
}相关文章:
原型,模板,策略,适配器模式
原型模式 原型模式(创建型模式),核心思想就是:基于一个已有的对象复制一个对象出来,通过复制来减少对象的直接创建的成本。 总结一下,原型模式的两种方法,浅拷贝只会复制对象里面的基本数据类型…...
Ollama 在本地快速启动并执行LLM【大语言模型】
文章目录 1. 什么是Ollama?1.1. SDK库1.2. 提供的api服务1.3. [支持的LLM](https://ollama.com/library)2. 如何安装2.1.下载docker镜像2.2. 启动docker容器3. 如何使用?3.1. 如何加载模型3.2. 使用 Ollama CLI 进行推理3.3. 使用 Ollama API 进行推理参考1. 什么是Ollama?...
ubuntu : 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
往后看,90%能解决你的问题 原文链接:学一下 (suxueit.com) 我相信很多人刚使用ubuntu都遇到过这个问题,如果没有遇到,可能是你运气好使用了正确的软件源 libprotobuf-dev : 依赖: zlib1g-dev 但是它将不会被安装 zlib1g-dev : 依…...
瑞芯微RK3576|触觉智能:开启科技新篇章
更多产品详情可关注深圳触觉智能官网! “瑞芯微,创新不止步!”——全新芯片RK3576即将震撼登场。指引科技风潮,创造未来无限可能!这款芯片在瑞芯微不断创新和突破的道路上,不仅是对过往成就的完美延续&…...
Visual Studio 2013 - 清理
Visual Studio 2013 - 清理 1. 清理1.1. 工程清理1.2. 解决方案清理 References 1. 清理 Debug Release 1.1. 工程清理 (right mouse click on the project) -> 清理 1.2. 解决方案清理 (right mouse click on the solution) -> 清理解决方案 References [1] Yongq…...
1、初识JVM
一、JVM是什么? JVM的英文全称是 Java Virtual Machine,其中文译名为Java虚拟机。它在本质上就是是一个运行在计算机上的程序,他的职责是运行Java字节码文件。 JVM执行流程如下 二、JVM有哪些功能? 2.1 解释和运行 对字节码文…...
JavaScript 权威指南第七版(GPT 重译)(七)
第十六章:用 Node 进行服务器端 JavaScript Node 是 JavaScript 与底层操作系统的绑定,使得编写 JavaScript 程序读写文件、执行子进程和在网络上通信成为可能。这使得 Node 作为以下用途变得有用: 现代替代 shell 脚本的方式,不…...
从零开始搭建游戏服务器 第四节 MongoDB引入并实现注册登录
目录 前言正文添加依赖安装MongoDB添加MongoDB相关配置创建MongoContext类尝试初始化DB连接实现注册功能测试注册功能实现登录逻辑测试登录流程 结语下节预告 前言 游戏服务器中, 很重要的一点就是如何保存玩家的游戏数据. 当一个服务端架构趋于稳定且功能全面, 开发者会发现服…...
【Unity】宏定义Scripting Define Symbols
1.宏的用处 我们在使用Unity开发的时候,经常需要根据不同环境执行不同的代码 比如安卓手机和苹果手机获取路径代码 这个时候,宏就派上用场了。 代码示例: //获取路径public string GtePath(){//不同平台,取不同的存储路径string…...
算法 之 排序算法
🎉欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨ 🎉感谢各位读者在百忙之中抽出时间来垂阅我的文章,我会尽我所能向的大家分享我的知识和经验📖 🎉希望我们在一篇篇的文章中能够共同进步!!&…...
Prism:打造WPF项目的MVVM之选,简化开发流程、提高可维护性
概述:探索WPF开发新境界,借助Prism MVVM库,实现模块化、可维护的项目。强大的命令系统、松耦合通信、内置导航,让您的开发更高效、更流畅 在WPF开发中,一个优秀的MVVM库是Prism。以下是Prism的优点以及基本应用示例&a…...
Springboot+vue的四川美食分享网站+数据库+报告+免费远程调试
项目介绍: Springbootvue的四川美食分享网站。Javaee项目,springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的四川美食分享网站,采用M(model)V(view)C(controller&am…...
温湿度项目V1.0——原理图设计
工程 首先要有安装好的Altium Designer软件。新建工程,添加sch、pcb文件;新建原理图库和PCB库。画原理图之前应该要有自己的原理库,可以从自己的原理图库中拖元器件到原理图中。那么就要先画原理图库的元器件,再画该元器件的封装…...
H5 与 App、网页之间的通信
前言 本文整理工作中 H5 嵌入 Android、iOS 与 PC 网页后,如何与各端通信。(提供 H5 端的代码) 环境判断 const ua navigator.userAgent.toLowerCase()const isAndroid /android/i.test(ua)const isIos /iphone|ipod|ios/i.test(ua)cons…...
亚马逊云科技:企业如何开启生成式AI之旅?
如果要评选最近两年全球科技行业最热门的细分领域,那么生成式AI绝对会以遥遥领先的票数成为当仁不让的冠军。 然而眼见生成式AI发展得如火如荼,越来越多的企业却陷入了深深的焦虑:应该如何开启生成式AI之旅?又该怎样搭建大模型&am…...
AMPQ和rabbitMQ
RabbitMQ 的 Channel、Connection、Queue 和 Exchange 都是按照 AMQP(Advanced Message Queuing Protocol)标准实现的。 AMPQ的网络部分 AMQP没有使用HTTP,使用TCP自己实现了应用层协议。 AMQP实现了自己特有的网络帧格式。 一个Connection…...
在存在代理的主机上,为docker容器配置代理
1、配置Firefox的代理 (只配置域名或者ip,前面不加http://) 2、为容器中的Git配置代理 git config --global http.proxy http://qingteng:8080 3、Git下载时忽略证书校验 env GIT_SSL_NO_VERIFYtrue git clone https://github.com/nginx/nginx.git 4、docker的…...
备考ICA----Istio实验4---使用 Istio 进行金丝雀部署
备考ICA----Istio实验4—使用 Istio 进行金丝雀部署 上一个实验已经通过DestinationRule实现了部分金丝雀部署的功能,这个实验会更完整的模拟展示一个环境由v1慢慢过渡到v2版本的金丝雀发布. 1. 环境清理 kubectl delete gw/helloworld-gateway vs/helloworld dr/helloworld…...
LeetCode-热题100:39.组合总和
题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被…...
演讲嘉宾公布 | 智能家居与会议系统专题论坛将于3月28日举办
一、智能家居与会议系统专题论坛 智能家居通过集成先进的技术和设备,为人们提供了更安全、舒适、高效、便捷且多彩的生活体验。智能会议系统它通过先进的技术手段,提高了会议效率,降低了沟通成本,提升了参会者的会议体验。对于现代…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
