二十三种设计模式
2 工厂方法模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
- 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
《设计模式》一书中,工厂模式被分为了三种:简单工厂、工厂方法和抽象工厂。(不过,在书中作者将简单工厂模式看作是工厂方法模式的一种特例。)
接下来我会介绍三种工厂模式的原理及使用
- 简单工厂模式(不属于GOF的23种经典设计模式)
- 工厂方法模式
- 抽象工厂模式
2.1 需求: 模拟发放奖品业务
需求: 为了让我们的案例更加贴近实际开发, 这里我们来模拟一下互联网电商中促销拉新下的业务场景, 新用户注册立即参与抽奖活动 ,奖品的种类有: 打折券, 免费优酷会员,小礼品.

2.2 原始开发方式
不考虑设计原则,不使用设计模式的方式进行开发
在不考虑任何代码的可扩展性的前提下,只为了尽快满足需求.我们可以这样去设计这个业务的代码结构:
1) 实体类
| 名称 | 描述 |
|---|---|
| AwardInfo | 获奖信息对应实体类 |
| DiscountInfo | 打折券信息对应实体类 |
| YouKuMember | 优酷会员对应实体类 |
| SmallGiftInfo | 小礼品信息对应实体类 |
| DiscountResult | 打折券操作响应结果封装类 |
public class AwardInfo {private String uid; //用户唯一IDprivate Integer awardType; //奖品类型: 1 打折券 ,2 优酷会员,3 小礼品private String awardNumber; //奖品编号Map<String, String> extMap; //额外信息}public class DiscountInfo {//属性信息省略......
}public class YouKuMember {//属性信息省略......
}public class SmallGiftInfo {private String userName; // 用户姓名private String userPhone; // 用户手机private String orderId; // 订单IDprivate String relAddress; // 收货地址}public class DiscountResult {private String status; // 状态码private String message; // 信息
}
2) 服务层
| 名称 | 功能 | 描述 |
|---|---|---|
| DiscountService | DiscountResult sendDiscount(String uid,String number) | 模拟打折券服务 |
| YouKuMemberService | void openMember(String bindMobile , String number) | 模拟赠送优酷会员服务 |
| SmallGiftService | Boolean giveSmallGift(SmallGiftInfo smallGiftInfo) | 模拟礼品服务 |
public class DiscountService {public DiscountResult sendDiscount(String uid, String number){System.out.println("向用户发放打折券一张: " + uid + " , " + number);return new DiscountResult("200","发放打折券成功");}
}public class YouKuMemberService {public void openMember(String bindMobile , String number){System.out.println("发放优酷会员: " + bindMobile + " , " + number);}
}public class SmallGiftService {public Boolean giveSmallGift(SmallGiftInfo smallGiftInfo){System.out.println("小礼品已发货,获奖用户注意查收! " + JSON.toJSON(smallGiftInfo));return true;}
}
3) 控制层
| 名称 | 功能 | 描述 |
|---|---|---|
| DeliverController | ResponseResult awardToUser(AwardInfo awardInfo) | 按照类型的不同发放商品 奖品类型: 1 打折券 ,2 优酷会员,3 小礼品 |
public class DeliverController {/*** 按照类型的不同发放商品* 奖品类型: 1 打折券 ,2 优酷会员,3 小礼品*/public void awardToUser(AwardInfo awardInfo){if(awardInfo.getAwardType() == 1){ //打折券DiscountService discountService = new DiscountService();DiscountResult result = discountService.sendDiscount(awardInfo.getUid(), awardInfo.getAwardNumber());System.out.println("打折券发放成功!"+ JSON.toJSON(result));}else if(awardInfo.getAwardType() == 2){ //优酷会员//获取用户手机号String bindMobile = awardInfo.getExtMap().get("phone");//调用serviceYouKuMemberService youKuMemberService = new YouKuMemberService();youKuMemberService.openMember(bindMobile,awardInfo.getAwardNumber());System.out.println("优酷会员发放成功!");}else if(awardInfo.getAwardType() == 3){ /*小礼品封装收货用户信息*/SmallGiftInfo smallGiftInfo = new SmallGiftInfo();smallGiftInfo.setUserName(awardInfo.getExtMap().get("username"));smallGiftInfo.setOrderId(UUID.randomUUID().toString());smallGiftInfo.setRelAddress(awardInfo.getExtMap().get("adderss"));SmallGiftService smallGiftService = new SmallGiftService();Boolean isSuccess = smallGiftService.giveSmallGift(smallGiftInfo);System.out.println("小礼品发放成功!" + isSuccess);}}}
4) 测试
通过单元测试,来对上面的接口进行测试,验证代码质量.
public class TestApi01 {//测试发放奖品接口@Testpublic void test01(){DeliverController deliverController = new DeliverController();//1. 发放打折券优惠AwardInfo info1 = new AwardInfo();info1.setUid("1001");info1.setAwardType(1);info1.setAwardNumber("DEL12345");deliverController.awardToUser(info1);//2. 发放优酷会员AwardInfo info2 = new AwardInfo();info2.setUid("1002");info2.setAwardType(2);info2.setAwardNumber("DW12345");Map<String,String> map = new HashMap<>();map.put("phone","13512341234");info2.setExtMap(map);deliverController.awardToUser(info2);//2. 发放小礼品AwardInfo info3 = new AwardInfo();info3.setUid("1003");info3.setAwardType(3);info3.setAwardNumber("SM12345");Map<String,String> map2 = new HashMap<>();map2.put("username","大远");map2.put("phone","13512341234");map2.put("address","北京天安门");info3.setExtMap(map2);deliverController.awardToUser(info3);}
}
对于上面的实现方式,如果我们有想要添加的新的奖品时,势必要改动DeliverController的代码,违反开闭原则.而且如果有的抽奖接口出现问题,那么对其进行重构的成本会非常高.
除此之外代码中有一组if分支判断逻辑,现在看起来还可以,但是如果经历几次迭代和拓展,后续ifelse肯定还会增加.到时候接手这段代码的研发将会十分痛苦.
2.3 简单工厂模式
2.3.1 简单工厂模式介绍
简单工厂不是一种设计模式,反而比较像是一种编程习惯。简单工厂模式又叫做静态工厂方法模式(static Factory Method pattern),它是通过使用静态方法接收不同的参数来返回不同的实例对象.
实现方式:
定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
适用场景:
(1)需要创建的对象较少。
(2)客户端不关心对象的创建过程。
2.3.2 简单工厂原理
简单工厂包含如下角色:
- 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品 :实现或者继承抽象产品的子类
- 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

2.3.3 简单工厂模式重构代码
1) service
/*** 免费商品发放接口* @author spikeCong* @date 2022/9/8**/
public interface IFreeGoods {ResponseResult sendFreeGoods(AwardInfo awardInfo);}
/*** 模拟打折券服务* @author spikeCong* @date 2022/9/8**/
public class DiscountFreeGoods implements IFreeGoods {@Overridepublic ResponseResult sendFreeGoods(AwardInfo awardInfo) {System.out.println("向用户发放一张打折券: " + awardInfo.getUid() + " , " + awardInfo.getAwardNumber());return new ResponseResult("200","打折券发放成功!");}
}/*** 小礼品发放服务* @author spikeCong* @date 2022/9/8**/
public class SmallGiftFreeGoods implements IFreeGoods {@Overridepublic ResponseResult sendFreeGoods(AwardInfo awardInfo) {SmallGiftInfo smallGiftInfo = new SmallGiftInfo();smallGiftInfo.setUserPhone(awardInfo.getExtMap().get("phone"));smallGiftInfo.setUserName(awardInfo.getExtMap().get("username"));smallGiftInfo.setAddress(awardInfo.getExtMap().get("address"));smallGiftInfo.setOrderId(UUID.randomUUID().toString());System.out.println("小礼品发放成,请注意查收: " + JSON.toJSON(smallGiftInfo));return new ResponseResult("200","小礼品发送成功",smallGiftInfo);}
}/*** 优酷 会员服务* @author spikeCong* @date 2022/9/8**/
public class YouKuMemberFreeGoods implements IFreeGoods {@Overridepublic ResponseResult sendFreeGoods(AwardInfo awardInfo) {String phone = awardInfo.getExtMap().get("phone");System.out.println("发放优酷会员成功,绑定手机号: " + phone);return new ResponseResult("200","优酷会员发放成功!");}
}
2) factory
/*** 具体工厂: 生成免费商品* @author spikeCong* @date 2022/9/9**/
public class FreeGoodsFactory {public static IFreeGoods getInstance(Integer awardType){IFreeGoods iFreeGoods = null;if(awardType == 1){ //打折券iFreeGoods = new DiscountFreeGoods();}else if(awardType == 2){ //优酷会员iFreeGoods = new YouKuMemberFreeGoods();}else if(awardType == 3){ //小礼品iFreeGoods = new SmallGiftFreeGoods();}return iFreeGoods;}
}
3)controller
public class DeliverController {//发放奖品public ResponseResult awardToUser(AwardInfo awardInfo){try {IFreeGoods freeGoods = FreeGoodsFactory.getInstance(awardInfo.getAwardTypes());ResponseResult responseResult = freeGoods.sendFreeGoods(awardInfo);return responseResult;} catch (Exception e) {e.printStackTrace();return new ResponseResult("201","奖品发放失败!");}}
}
4) 测试
通过单元测试,来对上面的接口进行测试,验证代码质量.
public class TestApi02 {DeliverController deliverController = new DeliverController();@Testpublic void test01(){//1. 发放打折券优惠AwardInfo info1 = new AwardInfo();info1.setUid("1001");info1.setAwardTypes(1);info1.setAwardNumber("DEL12345");ResponseResult result = deliverController.awardToUser(info1);System.out.println(result);}@Testpublic void test02(){//2. 发放优酷会员AwardInfo info2 = new AwardInfo();info2.setUid("1002");info2.setAwardTypes(2);info2.setAwardNumber("DW12345");Map<String,String> map = new HashMap<>();map.put("phone","13512341234");info2.setExtMap(map);ResponseResult result1 = deliverController.awardToUser(info2);System.out.println(result1);}@Testpublic void test03(){//3. 发放小礼品AwardInfo info3 = new AwardInfo();info3.setUid("1003");info3.setAwardTypes(3);info3.setAwardNumber("SM12345");Map<String,String> map2 = new HashMap<>();map2.put("username","大远");map2.put("phone","13512341234");map2.put("address","北京天安门");info3.setExtMap(map2);ResponseResult result2 = deliverController.awardToUser(info3);System.out.println(result2);}
}
2.3.4 简单工厂模式总结
优点:
封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。
缺点:
增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。
2.4 工厂方法模式
2.4.1 工厂方法模式介绍
工厂方法模式 Factory Method pattern,属于创建型模式.
概念: 定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。
2.4.2 工厂方法模式原理
工厂方法模式的目的很简单,就是封装对象创建的过程,提升创建对象方法的可复用性。
工厂方法模式的主要角色:
- 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
我们直接来看看工厂方法模式的 UML 图:

2.4.3 工厂方法模式重构代码
为了提高代码扩展性,我们需要将简单工厂中的if分支逻辑去掉,通过增加抽象工厂(生产工厂的工厂)的方式,让具体工厂去进行实现,由具体工厂来决定实例化哪一个具体的产品对象.
抽象工厂
public interface FreeGoodsFactory {IFreeGoods getInstance();
}
具体工厂
public class DiscountFreeGoodsFactory implements FreeGoodsFactory {@Overridepublic IFreeGoods getInstance() {return new DiscountFreeGoods();}
}public class SmallGiftFreeGoodsFactory implements FreeGoodsFactory {@Overridepublic IFreeGoods getInstance() {return new SmallGiftFreeGoods();}
}
Controller
public class DeliverController {/*** 按照类型的不同发放商品*/public ResponseResult awardToUser(AwardInfo awardInfo){FreeGoodsFactory freeGoodsFactory = null;if(awardInfo.getAwardType() == 1){freeGoodsFactory = new DiscountFreeGoodsFactory();}else if(awardInfo.getAwardType() == 2){freeGoodsFactory = new SmallGiftFreeGoodsFactory();}IFreeGoods freeGoods = freeGoodsFactory.getInstance();System.out.println("=====工厂方法模式========");ResponseResult result = freeGoods.sendFreeGoods(awardInfo);return result;}}
从上面的代码实现来看,工厂类对象的创建逻辑又耦合进了 awardToUser() 方法中,跟我们最初的代码版本非常相似,引入工厂方法非但没有解决问题,反倒让设计变得更加复杂了。
那怎么 来解决这个问题呢?
我们可以为工厂类再创建一个简单工厂,也就是工厂的工厂,用来创建工厂类对象。
/*** 用简单方法模式实现: 工厂的工厂,作用是不需要每次创建新的工厂对象* @author spikeCong* @date 2022/9/9**/
public class FreeGoodsFactoryMap {private static final Map<Integer,FreeGoodsFactory> cachedFactories = new HashMap<>();static{cachedFactories.put(1, new DiscountFreeGoodsFactory());cachedFactories.put(2, new SmallGiftFreeGoodsFactory());}public static FreeGoodsFactory getParserFactory(Integer type){if(type == 1){FreeGoodsFactory freeGoodsFactory = cachedFactories.get(1);return freeGoodsFactory;}else if(type ==2){FreeGoodsFactory freeGoodsFactory = cachedFactories.get(2);return freeGoodsFactory;}return null;}
}
Controller
/*** 发放奖品接口* @author spikeCong* @date 2022/9/7**/
public class DeliverController {/*** 按照类型的不同发放商品*/public ResponseResult awardToUser(AwardInfo awardInfo){//根据类型获取工厂FreeGoodsFactory goodsFactory = FreeGoodsFactoryMap.getParserFactory(awardInfo.getAwardType());//从工厂中获取对应实例IFreeGoods freeGoods = goodsFactory.getInstance();System.out.println("=====工厂方法模式========");ResponseResult result = freeGoods.sendFreeGoods(awardInfo);return result;}
}
现在我们的代码已经基本上符合了开闭原则,当有新增的产品时,我们需要做的事情包括:
- 创建新的产品类,并且让该产品实现抽象产品接口
- 创建产品类对应的具体工厂,并让具体工厂实现抽象工厂
- 将新的具体工厂对象,添加到FreeGoodsFactoryMap的cachedFactories中即可,需要改动的代码改动的非常少.
2.4.4 工厂方法模式总结
工厂方法模优缺点
优点:
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
- 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点:
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
什么时候使用工厂方法模式
- 需要使用很多重复代码创建对象时,比如,DAO 层的数据对象、API 层的 VO 对象等。
- 创建对象要访问外部信息或资源时,比如,读取数据库字段,获取访问授权 token 信息,配置文件等。
- 创建需要统一管理生命周期的对象时,比如,会话信息、用户网页浏览轨迹对象等。
- 创建池化对象时,比如,连接池对象、线程池对象、日志对象等。这些对象的特性是:有限、可重用,使用工厂方法模式可以有效节约资源。
- 希望隐藏对象的真实类型时,比如,不希望使用者知道对象的真实构造函数参数等。
相关文章:
二十三种设计模式
2 工厂方法模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通…...
uniapp 中引入使用uView UI
文章目录 一、前言:选择 uView UI的原因二、完整引入步骤1. 安装 uView UI2. 配置全局样式变量(关键!)3. 在 pages.json中添加:4. 全局注册组件5. 直接使用组件 五、自定义主题色(秒换皮肤) 一、…...
用冒泡排序法模拟qsort函数
目录 1.前言 2.qsort函数的介绍 3.冒泡法回顾 4.模拟qsort---buble_sort 4.1 buble_sort格式 4.2 主函数,以int类型为例 4.3comp_int函数的功能设计 4.4 swap函数的功能设计 5. 总代码概览 1.前言 今天,小邓儿带大家用冒泡排序法来模拟一下qs…...
DCN讲解
DCN是DeepFM的升级版,后者是只能做二阶交叉特征,随着阶数上升,模型复杂度大幅提高,且FM网络层较浅,表达能力有限。google团队通过构建深度交叉网络来自动进行特征的高阶交叉,且时空复杂度均为线性增长&…...
nginx的作用和应用场景
Nginx 是一款高性能的开源 Web 服务器和反向代理服务器,以其高效处理高并发连接和低资源消耗著称。以下是其核心作用及典型应用场景的详细解析: 一、Nginx 的核心作用 1. 静态资源服务器 功能:直接托管 HTML、CSS、JavaScript、图片等静态文…...
[Lc滑动窗口_1] 长度最小的数组 | 无重复字符的最长子串 | 最大连续1的个数 III | 将 x 减到 0 的最小操作数
目录 1. 长度最小的字数组 题解 代码 ⭕2.无重复字符的最长子串 题解 代码 3.最大连续1的个数 III 题解 代码 4.将 x 减到 0 的最小操作数 题解 代码 1. 长度最小的字数组 题目链接:209.长度最小的字数组 题目分析: 给定一个含有 n 个 正整数 的数组…...
基于python的网络爬虫爬取天气数据及可视化分析(Matplotlib、sk-learn等,包括ppt,视频)
基于Python爬取天气数据信息与可视化分析(文末完整源码) 基于python的网络爬虫爬取天气数据及可视化分析 可以看看演示视频。 摘要 基于Python爬取天气数据信息与可视化分析 本论文旨在利用Python编程语言实现天气数据信息的爬取和可视化分析。天气…...
【缓存】缓存雪崩与缓存穿透:高并发系统的隐形杀手
缓存雪崩与缓存穿透:高并发系统的隐形杀手 在高并发系统中,缓存是提升性能的重要手段。然而,缓存使用不当也会带来一系列问题,其中最常见的就是缓存雪崩和缓存穿透。这两个问题如果不加以解决,可能会导致系统崩溃&…...
HTML AI 编程助手
HTML AI 编程助手 引言 随着人工智能技术的飞速发展,编程领域也迎来了新的变革。HTML,作为网页制作的基础语言,与AI技术的结合,为开发者带来了前所未有的便利。本文将探讨HTML AI编程助手的功能、应用场景以及如何利用它提高编程…...
李宏毅机器学习课程学习笔记04 | 浅谈机器学习-宝可梦、数码宝贝分类器
文章目录 案例:宝可梦、数码宝贝分类器第一步:需要定义一个含有未知数的function第二步:loss of a function如何Sample Training Examples > 如何抽样可以得到一个较好的结果如何权衡模型的复杂程度 Tradeoff of Model Complexity todo 这…...
AIGC(生成式AI)试用 26 -- 跟着清华教程学习 - DeepSeek与AI幻觉
目标:继续学习 个人理解: - AI幻觉:一本正经的胡说八道,你还觉得很道理,倾向于相信;事实不一致,指令(预期)与实际不一致:跑题 - 潜在风险:把AI带坏了;信息误…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_add_dump
ngx_conf_add_dump 定义在src\core\ngx_conf_file.c static ngx_int_t ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename) {off_t size;u_char *p;uint32_t hash;ngx_buf_t *buf;ngx_str_node_t *sn;ngx_conf_dump_t *cd;has…...
QEMU源码全解析 —— 内存虚拟化(23)
接前一篇文章:QEMU源码全解析 —— 内存虚拟化(22) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 QEMU内存管理模型...
【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第1章 体验OpenHarmony—烧写镜像
瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…...
TypeScript 类型声明
在 TypeScript 开发中简化类型声明,可以通过以下 7 种实用技巧 显著提升效率: 一、善用类型推断(30% 场景免声明) // ❌ 冗余写法 const user: { name: string; age: number } { name: Jack, age: 25 };// ✅ 自动推断ÿ…...
从0搭建Tomcat第二天:深入理解Servlet容器与反射机制
在上一篇博客中,我们从0开始搭建了一个简易的Tomcat服务器,并实现了基本的HTTP请求处理。今天,我们将继续深入探讨Tomcat的核心组件之一——Servlet容器,并介绍如何使用反射机制动态加载和管理Servlet。 1. Servlet容器的作用 S…...
【Python】yield函数
【Python】yield函数 1. yield介绍2.yield基本用法3.yield高级用法3.1 yield send() 方法3.2 yield from方法3.3 yield 和yield from叠加处理复杂情况下的叠加 4.yield主要应用场景5.总结 python官方api地址 1. yield介绍 在Python中,yield关键字主要用于生成器函…...
Android13修改多媒体默认音量
干就完了! 设置音量为最大音量,修改如下: /framework/base/media/java/android/media/AudioSystem.java/** hide */public static int[] DEFAULT_STREAM_VOLUME new int[] {4, // STREAM_VOICE_CALL7, // STREAM_SYSTEM5, // STREAM_RING-5, // STREAM_MUSIC15, // STREAM…...
nginx+keepalived负载均衡及高可用
一、环境准备 主机名ip地址备注openEuler-1 192.168.121.11(本机) 192.168.131.11(心跳连接) nginx主负载均衡调度器openEuler-2 192.168.121.12(本机) 192.168.131.12(心跳连接) n…...
SP导入智能材质球
智能材质球路径 ...\Adobe Substance 3D Painter\resources\starter_assets\smart-materials 放入之后就会自动刷新...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
