探索设计模式的魅力:抽象工厂模式的艺术
个人主页: danci_
🔥系列专栏:《设计模式》《MYSQL应用》
💪🏻 制定明确可量化的目标,坚持默默的做事。
🚀 转载自文章:探索设计模式的魅力:抽象工厂模式的艺术
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于在不指定具体类的情况下创建一系列相关或相互依赖的对象。它提供了一个接口,用于创建一系列“家族”或相关依赖对象,而无需指定它们的具体类。
主要参与者:
- 抽象工厂(Abstract Factory):提供一个接口,用于创建一些相关或相互依赖的对象家族,而不需要指定它们具体的类。
- 具体工厂(Concrete Factory):实现抽象工厂的操作以生产具体的产品对象。
- 抽象产品(Abstract Product):为一系列产品对象声明一个接口。
- 具体产品(Concrete Product):抽象产品的子类,定义用于生产的具体产品对象。
- 客户(Client):仅使用由抽象工厂和抽象产品类声明的接口。
实现步骤:
- 定义抽象产品,确定产品家族中的不同产品。
- 创建抽象工厂类,定义创建抽象产品的接口。
- 实现具体工厂类,每个工厂类负责创建不同的产品变体。
- 客户端代码通过抽象工厂和抽象产品类接口与工厂和产品交互。
优势:
- 隔离具体类的生成:客户端不需要知道它所使用的对象的具体类,只需要关心所使用对象的接口。
- 易于交换产品系列:因为具体的工厂类都派生自同一个抽象类,可以很容易地更换使用的工厂类来切换整个产品系列。
- 增强一致性:产品在一系列中一致地创建,这保证了客户端始终只使用同一产品系列中的对象。
缺点:
- 难以支持新种类的产品:如果需要添加额外的产品到系列中,抽象工厂和所有具体工厂类都需要改变,这违反了开闭原则。
探索设计模式的魅力:简单工厂模式-CSDN博客文章浏览阅读2.5k次,点赞58次,收藏46次。实现简单工厂的难点就在于 “如何选择” 实现,前面便子中传递参数的方法, 那都是静态的参数,还可以实现成为动态的参数。客户端通过简单工厂创建 了一个实现接口的对象,然后面向接口编程,从客户端来看,它根本不知道具体的实现是什么,也不知道是如何实现的,它只知道通过工厂获得了一个接口对象 , 然后通过这个接口来获取想要的功能。如果通过客户端的参数来选择具体的实现类,那么就必须让客户端能理解各个参数所代表的具体功能和含义,这样会增加客户端使用的难度,也部分暴露了内部实现,这种情况可以选用可配置的方式来实现。https://blog.csdn.net/danci_/article/details/135566105探索设计模式的魅力:工厂方法模式-CSDN博客文章浏览阅读2.5k次,点赞83次,收藏47次。工厂方法模式是一种创建型设计模式,它提供了一种创建对象的接口,但将具体实例化对象的工作推迟到子类中完成。这样做的目的是创建对象时不用依赖于具体的类,而是依赖于抽象,这提高了系统的灵活性和可扩展性。优点:降低耦合度、增加了系统的可扩展性 和 提高代码的可维护性;缺点:增加了代码的复杂性 和 需要更多的设计考虑。https://blog.csdn.net/danci_/article/details/135611783
目录
一、案例
1.1 示例代码
1.1.1 简单工厂实现
1.1.2 问题
1.1.3 抽象工厂实现
二、模式讲解
2.1 功能
2.2 抽象工厂模式的结构及说明
2.3 示例代码程序结构图
2.4 抽象工厂模式与简单工厂模式
2.5 抽象工厂模式与工厂方法模式
一、案例
场景:造一辆汽车(买零件来组装),汽车有很多的零组成,成百上千个零件相互依赖配合工作,比如发动机和变速箱。
选择零件时,每个零件的品牌、规格 等如何才能选择到合适的搭配才能配合正常工作,也就是说汽车是一个整体,每个零件之间有关联的。
1.1 示例代码
汽车零件有成百上升个,这里只举例发动机和变速箱。市面上有各种品牌的发动机和变速箱,同一品牌还有各种型等,这里举两个。
1.1.1 简单工厂实现
发动机接口:
public interface EngineApi {void run();
}
变速箱接口:
public interface GearboxApi {void run();
}
林肯发动机和林肯变速箱:
public class LinkenEngineApiImpl implements EngineApi {@Overridepublic void run() {System.out.println("林肯发动机工作了");}
}public class LinkenGearboxApiImpl implements GearboxApi {@Overridepublic void run() {System.out.println("林肯变速箱工作了");}
}
丰田发动机和丰田变速箱:
public class ToyotaEngineApiImpl implements EngineApi {@Overridepublic void run() {System.out.println("丰田发动机工作了");}
}public class ToyotaGearboxApiImpl implements GearboxApi {@Overridepublic void run() {System.out.println("丰田变速箱工作了");}
}
发动机工厂:
public class EngineFactory {public static EngineApi getEngineApi(int i) {if (i == 1) {return new LinkenEngineApiImpl();}return new ToyotaEngineApiImpl();}
}
变速箱工厂 :
public class GearboxFactory {public static GearboxApi getGearbox(int i) {if (1 == i) {return new LinkenGearboxApiImpl();}return new ToyotaGearboxApiImpl();}
}
汽车组装类:
public class CarEngineer {public void makeCar(int engineType, int gearboxType) {EngineApi engineApi = EngineFactory.getEngineApi(engineType);GearboxApi gearbox = GearboxFactory.getGearbox(gearboxType);engineApi.run();gearbox.run();}
}
客户端:
public class CarClient {public static void main(String[] args) {CarEngineer carEngineer = new CarEngineer();carEngineer.makeCar(1, 1);}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
林肯变速箱工作了
修改客户端carEngineer.makeCar(1, 2); 运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
丰田变速箱工作了
1.1.2 问题
修改了产数之后,组装的汽车使用了林肯的发动机,而变速箱是丰田的,此时发动机与变速箱不是一个品牌,如果发动机与变速箱不匹配无法正常配合工作,那么组装的这个汽车就等于废了(这里假设只有同品牌的零部件才能正常配合动作)。
显然发动机与变速箱是需要互相匹配,强依赖关系。就是选了这个发动机就必须选定某个变速箱。抽象工厂来解决这个问题。
1.1.3 抽象工厂实现
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接又,而无需指定它们具体的类。
解决1.1.2问题是要创建一序列有相互依赖关联和相互约束的产品——抽象工厂模式。
代码改造:
发动机接口和变速箱接口不变:
public interface EngineApi {void run();
}
public interface GearboxApi {void run();
}
发动机和变速箱的实现也不变:
public class LinkenEngineApiImpl implements EngineApi {@Overridepublic void run() {System.out.println("林肯发动机工作了");}
}public class LinkenGearboxApiImpl implements GearboxApi {@Overridepublic void run() {System.out.println("林肯变速箱工作了");}
}public class ToyotaEngineApiImpl implements EngineApi {@Overridepublic void run() {System.out.println("丰田发动机工作了");}
}public class ToyotaGearboxApiImpl implements GearboxApi {@Overridepublic void run() {System.out.println("丰田变速箱工作了");}
}
添加抽象工厂:(工厂抽象出来)
public interface AbstractFactory {/*** 创建发动机 <br/>*/EngineApi createLinken();/*** 创建变速箱 <br/>*/GearboxApi createGearbox();
}
发动机工厂修改为林肯工厂,并实现抽象工厂:(//注释部分为简单工厂代码)
public class LinkenFactory implements AbstractFactory {
//public class EngineFactory {/*** 生产林肯发动机*/@Overridepublic EngineApi createLinken() {return new LinkenEngineApiImpl();}/*** 生产林肯发变速箱*/@Overridepublic GearboxApi createGearbox() {return new LinkenGearboxApiImpl();}//public static EngineApi getEngineApi(int i) {// if (i == 1) {// return new LinkenEngineApiImpl();// }//// return new ToyotaEngineApiImpl();//}
}
变速箱工厂修改为丰田工厂,并实现抽象工厂:(//注释部分为简单工厂代码)
public class ToyotaFactory implements AbstractFactory {
//public class GearboxFactory {/*** 生产丰田发动机*/@Overridepublic EngineApi createLinken() {return new ToyotaEngineApiImpl();}/*** 生产丰田变事箱*/@Overridepublic GearboxApi createGearbox() {return new ToyotaGearboxApiImpl();}//public static GearboxApi getGearbox(int i) {// if (1 == i) {// return new LinkenGearboxApiImpl();// }//// return new ToyotaGearboxApiImpl();//}
}
汽车组装类有修改:(//注释部分为简单工厂代码)
public class CarEngineer {/*** 接收选择好的哪一个序列产品工厂* @param factory*/public void makeCar(AbstractFactory factory) {EngineApi engineApi = factory.createLinken();GearboxApi gearbox = factory.createGearbox();engineApi.run();gearbox.run();}//public void makeCar(int engineType, int gearboxType) {// EngineApi engineApi = EngineFactory.getEngineApi(engineType);// GearboxApi gearbox = GearboxFactory.getGearbox(gearboxType);// engineApi.run();// gearbox.run();//}
}
客户端:(//注释部分为简单工厂代码)
public class CarClient {public static void main(String[] args) {//CarEngineer carEngineer = new CarEngineer();//carEngineer.makeCar(1, 2);CarEngineer carEngineer = new CarEngineer();// 传入选中的哪种产品工厂carEngineer.makeCar(new LinkenFactory());}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
林肯变速箱工作了
修改选中的产品工厂carEngineer.makeCar(new ToyotaFactory()) ,运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
丰田发动机工作了
丰田变速箱工作了
这个抽象工厂相当于选择一套方案,方案确定好,里面的零件也就确定好了。不用一个零件一个零件的选择以免选择出错。
二、模式讲解
2.1 功能
功能: 为一系列相关对象或相互依赖的对象创建一个接口。
接口内的方法是一系列相互依赖和约束的方法。
2.2 抽象工厂模式的结构及说明
AbstractFactory:抽象工厂,定义创建一系列产品对象的操作接口。
FactoryA:具体的工厂,实现抽象工厂定义的方法,具体实现一系列产品对象的创建。
AbstractProduct:定义类产品对象的接口。
ProductA:具体的产品实现对象,通常在具体工厂里面,会选择具体的产品实现对象,来创建符合抽象工厂定义的方法返回的产品类型的对象。
Client:客户端,主要使用抽象工厂来获取一系列所需要的产品对象,然后面向这些产品对象的接口编程,以实现需要的功能。
2.3 示例代码程序结构图
抽象工厂模式主要用于以下几个方面的应用场景中:
需要创建一系列相互依赖的对象:当一组对象之间存在依赖关系,并且需要保证这些对象是兼容的,抽象工厂模式可以用来创建这些对象的族群。
希望实现多个产品族的变化:抽象工厂模式允许你定义多个工厂类,每个工厂类可以创建不同的产品族,从而可以实现对产品族的变化。
需要切换产品组合:通过使用抽象工厂模式,可以很方便地切换不同的产品组合,而无需修改已有的客户端代码。
优势方面,抽象工厂模式具有以下几个优势:
封装了对象的创建过程:客户端只需关注抽象工厂类和抽象产品类,而无需关心具体的创建细节,将对象创建的过程封装在工厂类中,提供了更高的封装性和抽象性。
符合开闭原则:抽象工厂模式对于新增新的产品族非常方便,只需创建对应的新的工厂类即可,并且不需要修改已有的代码,符合开闭原则。
保持产品族的一致性:通过抽象工厂模式创建的产品族中的产品具有一定的约束关系,保证了产品的一致性,避免了不兼容的产品组合。
2.4 抽象工厂模式与简单工厂模式
抽象工厂模式和简单工厂模式是两种常见的设计模式,它们在对象的创建和管理上有一些不同之处。
1. 目的和应用场景:
- 简单工厂模式(Simple Factory Pattern)旨在根据给定的参数来创建单一类型的对象实例。它适用于需要根据条件创建不同类型的对象的情况,但它并没有分离对象的创建和使用,违反了单一职责原则。
- 抽象工厂模式(Abstract Factory Pattern)旨在创建一系列相关或相互依赖的对象,而无需显式指定其具体类。它适用于需要创建一组相关的产品对象,并且需要确保这些产品是兼容的情况。
2. 结构与实现:
- 简单工厂模式通常由一个工厂类通过静态方法来创建对象,客户端通过调用工厂类的方法并传入相应的参数来获得所需的对象。
- 抽象工厂模式通常由一组抽象工厂和一组具体工厂类组成,每个具体工厂负责创建一组特定的产品。
3. 灵活性与扩展性:
- 简单工厂模式的灵活性相对较低,因为一旦需要添加新类型的产品,通常需要修改工厂类的静态方法。
- 抽象工厂模式支持产品族的概念,可以非常容易地添加新的产品族,只需要新增对应的具体工厂类即可,而不需要修改客户端代码。
总的来说,简单工厂模式适用于需要创建单一类型的对象,并且可以根据条件动态地创建不同类型的对象。而抽象工厂模式适用于创建一系列相关或相互依赖的对象,并且需要确保这些对象是兼容的情况。在实际应用中,根据具体的需求和设计目标来选择合适的设计模式。
2.5 抽象工厂模式与工厂方法模式
抽象工厂模式(Abstract Factory Pattern)和工厂方法模式(Factory Method Pattern)虽然同属于创建型设计模式,旨在解耦对象的创建和使用,但两者在目的、实现方式及应用场景上存在明显区别:
1. 目的:
- 工厂方法模式的目的是允许一个类在不知道将要创建的对象的具体类型的情况下,推迟其实例化到子类中进行。
- 抽象工厂模式的目的是创建一系列相关或者相互依赖的对象,而不需要指定它们具体的类。
2. 实现方式:
- 工厂方法模式定义了一个用于创建对象的接口,但由子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类中进行。
- 抽象工厂模式提供了一个创建一系列相关或互相依赖对象的接口,而不需要指定它们具体的类。它通常包含多个工厂方法来创建一系列不同的产品。
3. 应用场景:
- 工厂方法模式主要用于单一产品的创建情形,即客户端只需要一个产品,而具体哪个产品则由具体工厂类在运行时决定。
- 抽象工厂模式适用于创建一组产品(产品族),这些产品设计成合作使用的,客户端需要多个产品对象,这些对象要按照一定的方式配合工作。
4. 结构复杂度:
- 工厂方法模式结构相对简单,每个具体工厂类只需要负责一个产品的创建。
- 抽象工厂模式结构相对复杂,一个工厂类需要负责多个产品对象的创建,这些对象通常属于不同的类系列。
5. 扩展难度:
- 工厂方法模式较容易扩展,引入新的产品类型只需要添加相应的具体工厂类和产品类即可。
- 抽象工厂模式相对难以扩展,如果需要添加新的产品系列,需修改抽象工厂的接口以及所有的实现类,这会违反开闭原则。
总之,工厂方法模式用于创建一个产品,而抽象工厂模式用于创建多个相互依赖或相互关联的产品族。在选择使用哪一个模式时,需要根据具体场景和设计需求去判断。
相关文章:
探索设计模式的魅力:抽象工厂模式的艺术
个人主页: danci_ 🔥系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自文章:探索设计模式的魅力:抽象工厂模式的艺术 抽象工厂模式&…...
果园系统养殖游戏喂养偷菜种植浇水养成小程序
装扮 通过购买装扮场景切换不同的农场风格 土地升级 通过特定的材料对土地和房屋进行升级 日志 记录道具的使用数量及金币农作物的收入情况 幸运转盘 可用金币进行抽奖 宝箱开启 获得宝箱后可以通过金币开启 每日签到 每日签到获得奖励 系统公告 可以第一时间知道游戏的更新和…...
Windows版PHP7.4.9解压直用(免安装-绿色-项目打包直接使用)
安装版和解压版 区别 安装版: 安装方便,下一步------下一步就OK了,但重装系统更换环境又要重新来一遍,会特别麻烦解压版(推荐): 这种方式(项目打包特别方便)能更深了解mysql的配置&…...
凡泰极客亮相2024 亚马逊云科技出海全球化论坛,为企业数字化出海赋能
随着「不出海,即出局」登上热搜榜单,企业出海已成燎原之势,3月29日,2024 亚马逊云科技出海全球化论坛在深圳成功举办,凡泰极客创始人梁启鸿受邀出席,并以 「App 2.0:以SuperApp构建智能数字生态…...
新零售门店、商品、会员管理指标体系总览
新零售,旨在打破传统零售业的边界,引入先进科技和数字化手段,通过整合线上线下渠道,全面提升用户体验,并实现更智能、高效、个性化的零售运营模式。这一模式不仅仅关注销售产品,更注重构建全方位的购物生态…...
网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)
网上订餐系统目录 目录 基于springboot的网上订餐系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户功能模块的实现 (1)用户注册界面 (2)用户登录界面 (3)菜品详情界面 (…...
python的抽象类和抽象方法
抽象类是一种不能直接被继承的类。举个例子,我们可以从类Creature衍生出类People,Cats,其中前者两条腿走路,后者四条腿走路,而单独的类Creature却没有一个几条腿走路的方法,因为这是不确定的。 ࿰…...
Android MVVM架构学习——ViewModel DataBinding
关于MVVM架构,我并不想花篇幅去做重复性的描述,网上一搜都是一堆讲解,大家可以自行了解,我所做的只是以最简单的例子,最有效的步骤,从零开始,去实现一个相对有点学习参考价值的项目。 先来看本…...
防抖与节流
...
理解 Nginx 的多站点配置:为每个网站单独配置
Nginx 是一个高性能的 Web 服务器,广泛用于托管和管理网站。它之所以受欢迎,部分原因在于它的灵活性和强大的配置能力。特别是对于管理多个网站,Nginx 提供了一种高效且组织良好的方法。让我们逐步了解如何使用 Nginx 配置多个网站࿰…...
支持向量机模型pytorch
通过5个条件判定一件事情是否会发生,5个条件对这件事情是否发生的影响力不同,计算每个条件对这件事情发生的影响力多大,写一个支持向量机模型pytorch程序,最后打印5个条件分别的影响力。 示例一 支持向量机(SVM)是一种…...
轮转数组(力扣)
189. 轮转数组 - 力扣(LeetCode) 189. 轮转数组 题解 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 样例输入 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮…...
批量插入10w数据方法对比
环境准备(mysql5.7) CREATE TABLE user (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 唯一id,user_id bigint(10) DEFAULT NULL COMMENT 用户id-uuid,user_name varchar(100) NOT NULL COMMENT 用户名,user_age bigint(10) DEFAULT NULL COMMENT 用户年龄,create_time time…...
HAL STM32 I2C方式读取MT6701磁编码器获取角度例程
HAL STM32 I2C方式读取MT6701磁编码器获取角度例程 📍相关篇《Arduino通过I2C驱动MT6701磁编码器并读取角度数据》🎈《STM32 软件I2C方式读取MT6701磁编码器获取角度例程》📌MT6701当前最新文档资料:https://www.magntek.com.cn/u…...
如何排查nginx服务启动情况,杀死端口,以及防火墙开放指定端口【linux与nginx排查手册】
利用NGINX搭建了视频服务,突然发现启动不了了,于是命令开始 使用以下命令查看更详细的错误信息: systemctl status nginx.service Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. Run…...
用Rust实现免费调用ChatGPT的命令行工具 (一)
代码已经开源:🚀 fgpt 欢迎大家star⭐和fork 👏 ChatGPT现在免费提供了GPT3.5的Web访问,不需要注册就可以直接使用,但是,它的使用方式是通过Web页面,不够方便。 更多技术分享关注 入职啦&…...
mysql 查询实战1-题目
学习了mysql 查询实战-变量方式-解答-CSDN博客,接着练习sql,从实战中多练习。 1,题目: 1,查询部门工资最高的员工 1,建表: DROP TABLE IF EXISTS department; create table department(dept_i…...
Word学习笔记之奇偶页的页眉与页码设置
1. 常用格式 在毕业论文中,往往有一下要求: 奇数页右下角显示、偶数页左下角显示奇数页眉为每章标题、偶数页眉为论文标题 2. 问题解决 2.1 前期准备 首先,不论时要求 1、还是要求 2,这里我们都要做一下设置: 鼠…...
数据赋能(58)——要求:数据赋能实施部门能力
“要求:数据赋能实施部门能力”是作为标准的参考内容编写的。 在实施数据赋能中,数据赋能实施部门的能力体现在多个方面,关键能力如下图所示。 在实施数据赋能的过程中,数据赋能实施部门应具备的关键能力如下。 理性思维与逻辑分…...
Unity URP PBR_Cook-Torrance模型
Cook-Torrance模型是一个微表面光照模型,认为物体的表面可以看作是由许多个理想的镜面反射体微小平面组成的。 单点反射镜面反射漫反射占比*漫反射 漫反射 基础色/Π 镜面反射DFG/4(NV)(NL) D代表微平面分布函数,描述的是法线与半角向量normalize(L…...
Unity之XR Interaction Toolkit如何在VR中实现渐变黑屏效果
前言 做VR的时候,有时会有跳转场景,切换位置,切换环境,切换进度等等需求,此时相机的画面如果不切换个黑屏,总会感觉很突兀。刚好Unity的XR Interaction Toolkit插件在2.5.x版本,出了一个TunnelingVignette的效果,我们今天就来分析一下他是如何使用的,然后我们自己再来…...
html+vue编写分页功能
效果: html关键代码: <div class"ui-jqgrid-resize-mark" id"rs_mlist_table_C87E35BE"> </div><div class"list_component_pager ui-jqgrid-pager undefined" dir"ltr"><div id"pg…...
计算机网络 实验指导 实验17
实验17 配置无线网络实验 1.实验拓扑图 Table PC0 和 Table PC1 最开始可能还会连Access Point0,无影响后面会改 名称接口IP地址网关地址Router0fa0/0210.10.10.1fa0/1220.10.10.2Tablet PC0210.10.10.11Tablet PC1210.10.10.12Wireless互联网220.10.10.2LAN192.16…...
在 Vue中,v-for 指令的使用
在 Vue中,v-for 指令用于渲染一个列表,基于源数据多次渲染元素或模板块。它对于展示数组或对象中的数据特别有用。 数组渲染 假设你有一个数组,并且你想为每个数组元素渲染一个 <li> 标签: <template> <ul>…...
达梦数据库执行sql报错:数据溢出
数据库执行sql报错数据溢出 单独查询对应的数字进行计算是不是超过了某个字段类型的上限或下限 如果已经超过了,进行对字段进行cast类型转换处理,转换为dec num都可以尝试 这里就是从 max(T.BLOCK_ID as dec*8192t.bytes)/1024/1024 max_MB,换成了这个…...
从「宏大叙事」到「生活叙事」,小红书品牌种草的的“正确姿势”
不同于抖音和微博,在小红书上,品牌营销的基调应该是怎样的?品牌怎样与小红书用户对话?什么样的内容,才能走进小红书用户的心中?本期,小编将带大家洞察品牌在小红书营销的“正确姿势”。从「小美…...
Python Selenium 的基本使用方法
文章目录 1. 概述2. 安装Chrome及ChromeDriver2.1 安装Chrome2.2 安装ChromeDriver 3. 安装Selenium4. 常见用法4.1 启动4.2 查找元素4.3 等待页面加载元素 1. 概述 Selenium 是一个用于自动化 web 浏览器的工具,它提供了一套用于测试 web 应用程序的工具和库。Sel…...
上位机图像处理和嵌入式模块部署(树莓派4b固件功能设计)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们说过,上位机的功能都是基于插件进行开发的。但是上位机的成本比较贵,一般的企业不一定愿意接接受。这个时候另外一…...
新手入门人工智能:从零开始学习AI的正确途径
你是否对人工智能(AI)充满了好奇心和探索欲?你是否想了解如何从零开始学习AI,成为一名人工智能领域的专家?那么,这篇文章就是为你准备的!我们将带你了解人工智能的基本概念,学习如何…...
ubuntu git相关操作
1 安装git sudo apt install git git --version git version 2.25.1 2 解决git超时 2.1 扩大post的buffer git config --global http.postBuffer 524288000 git config --global http.postBuffer 157286400 2.2 换回HTTP1上传。上传之后再切换回HTTP2 …...
IDEA工具|添加 GitLab 账户之两三事
📫 作者简介:「六月暴雪飞梨花」,专注于研究Java,就职于科技型公司后端工程师 🏆 近期荣誉:华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 🔥 三连支持:欢迎 ❤️关注…...
蓝桥杯:棋盘(Java)
目录 问题描述输入格式输出格式代码实现 问题描述 小蓝拥有n n大小的棋盘,一开始棋盘上全都是白子。小蓝进行了m.次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋子变为黑色,黑色棋子变为白色)。请输出所…...
跨界融合:ERP与TMS的区分、相通之处、融合方式,全告诉你。
Hi,如今系统的边界越来越模糊,A系统和B系统会有一些功能的交叉,贝格前端工场今天开始介绍第二篇ERP和TMS的融合。 一、什么是ERP和TMS ERP是企业资源规划(Enterprise Resource Planning)的缩写,是一种集成…...
SAP Smartform转存PDF方法汇总
用户会有保存SF至本地PDF文件的需求,下面详细说明一下Smartform转成PDF的四种方法,其中,方法二和三相比于其他方法更便捷实用,如果还有其他方法,欢迎留言补充。 一、代码开发 1)先调用smartform函数获取OTF格式数据 2)后调用函数CONVERT_OTF转换成PDF格式数据 3)再…...
Linux【实战篇】—— NFS服务搭建与配置
目录 一、介绍 1.1什么是NFS? 1.2客户端与服务端之间的NFS如何进行数据传输? 1.3RPC和NFS的启动顺序 1.4NFS服务 系统守护进程 二、安装NFS服务端 2.1安装NFS服务 2.2 创建共享目录 2.3创建共享目录首页文件 2.4关闭防火墙 2.5启动NFS服务 2.…...
Edge的使用心得与深度探索
Microsoft Edge 是微软推出的一款网页浏览器,基于 Chromium 开源项目开发。从 2020 年开始,Edge 浏览器经历了一次重大更新,采用了与 Google Chrome 相同的浏览器引擎,这使得它在性能、兼容性和扩展支持方面都得到了显著改善。以下…...
逆向案例二十八——红某点集登录接口逆向序
网址:aHR0cHM6Ly93d3cuaHJkanl1bi5jb20vIy9sb2dpbj9yZWRpcmVjdD0lMkZyZWFsVGltZUxpdmluZw 登录接口,发现两个参数加密,分别是pwd和sig,t很明显是时间戳。 观察pwd,发现很像md5加密,我输入的密码是123456,在在线加密网…...
我的创作纪念日20240418
机缘 我的技术博客起源于对编程的深深热爱和对知识的渴望。从一开始,我就被编程世界的无限可能所吸引,而这种热情也推动我开始了技术创作之旅。我创建博客的初衷有以下几点: 分享实战经验:在工作中,我遇到了许多技术…...
计算机视觉入门
计算机视觉是人工智能的一个分支,它涉及研究如何使计算机能够理解和解释图像和视频中的视觉信息。这个领域结合了计算机科学、工程学、神经科学和认知科学等多个学科的知识。以下是计算机视觉入门的一些关键点: 1. 基础概念 - **图像处理**:对…...
CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)
CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀) 文章目录 CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)前端验证—MIME绕过有关MIMEMIME的作用 解题时有…...
Java面试题笔记(持续更新)
Java基础 java中的Math.round(-1.5)等于多少? Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)-1,如果是Math.round(1.5)则结果为2 JDK和JRE的区别? JDK 是 Java Development ToolKit 的简称,也就是…...
格式化字符串漏洞学习笔记
简单介绍 格式化字符串漏洞和栈溢出有相似之处,但又有所不同,都是利用了程序员的疏忽大意来改变程序运行的正常流程。 1、格式化字符串的介绍 printf()、fprint()等print()系列的函数可以按照一定的格式将数据进行输出。 实例…...
用友NC avatar接口文件上传漏洞
产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 漏洞介绍 用友 NC avatar接口处…...
【Go语言快速上手(二)】 分支与循环函数讲解
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Go语言专栏⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学习更多Go语言知识 🔝🔝 Go快速上手 1. 前言2. 分支与循环2.1…...
动手写sql 《牛客网80道sql》
第1章:SQL编写基础逻辑和常见问题 基础逻辑 SELECT语句: 选择数据表中的列。FROM语句: 指定查询将要从哪个表中检索数据。WHERE语句: 过滤条件,用于提取满足特定条件的记录。GROUP BY语句: 对结果进行分组。HAVING语句: 对分组后的结果进行条件过滤。O…...
Node.js、Java、Python、PHP在构建BS系统时的特点比较
在现代软件开发领域,构建一个稳定、高效的B/S(浏览器/服务器)系统对于企业的信息化发展至关重要。Node.js、Java、Python和PHP是当下流行的几种后端开发技术,它们各自具有独特的特点和优势。本文将对这几种技术在构建B/S系统时的特…...
快速入门深度学习9.1(用时20min)——GRU
速通《动手学深度学习》9.1 写在最前面九、现代循环神经网络9.1 门控循环单元(GRU)9.1.1. 门控隐状态9.1.1.1. 重置门和更新门9.1.1.2. 候选隐状态9.1.1.3. 隐状态 9.1.3 API简洁实现小结 🌈你好呀!我是 是Yu欸 🌌 20…...
基于51单片机的步进电机调速系统设计
基于51单片机的步进电机调速系统 (仿真+程序+原理图+设计报告) 功能介绍 具体功能: 1.按键可以控制电机正、反转,加、减速,停止; 2.一位7段数码管实时显示档位…...
postcss概述
PostCSS是一个用于转换CSS的工具,它使用插件来处理CSS,并提供了一种方式来编写可扩展的CSS代码。其主要特点如下: 插件驱动:PostCSS的核心非常轻量级,大部分功能都是通过插件来实现的。这意味着用户可以根据项目的需求…...
【Proteus】51单片机对直流电机的控制
直流电机:输出或输入为直流电能的旋转电机。能实现直流电能和机械能互相转换的电机。把它作电动机运行时是直流电动机,电能转换为机械能;作发电机运行时是直流发电机,机 械能转换为电能。 直流电机的控制: 1、方向控制…...
Docker 快速搭建 Kafka 集群
Docker 快速搭建 Kafka 集群 你是否想要一个 Kafka 集群,但又不想经历繁琐的手动配置过程?别担心,有了 Docker 和 Docker Compose,我们可以轻松快捷地搭建一个 Kafka 集群,让你能专注于享受实时数据流处理的乐趣。 环…...
2024-05-07 商业分析-如何在社会层面做一个更好的工具人-记录
摘要: 2024-05-07 商业分析-如何成为一个靠谱的工具人 如何在社会层面做一个更好的工具人 那么今天讲的这个主题呢,对吧?你们一看啊,就觉得这个就不应该我讲是吧啊,但是呢这个逻辑呢我还得跟你们讲一下啊,就是如何成为…...
《十八》QThread多线程组件
本章将重点介绍如何运用QThread组件实现多线程功能。 多线程技术在程序开发中尤为常用,Qt框架中提供了QThread库来实现多线程功能。当你需要使用QThread时,需包含QThread模块,以下是QThread类的一些主要成员函数和槽函数。 成员函数/槽函数 …...
无法添加以供审核,提交以供审核时遇到意外错误。如果问题仍然存在,请联系我们
遇到问题: 无法添加以供审核 要开始审核流程,必须提供以下项目: 提交以供审核时遇到意外错误。如果问题仍然存在,请联系我们。 解决办法: 修改备案号为小写, 例如:京ICP备2023013223号-2A 改…...
如何用TONGYILingma进行AI辅助编程?
通义灵码,是阿里云出品的一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力,并针对阿里云的云服务使用场景调优,…...
stm32f103c8t6最小系统板
STM32F103C8T6最小系统板是为基于ARM Cortex-M3内核的STM32F103C8T6微控制器设计的电路板,它包含了单片机正常运行所需的最基本组件。以下是构成STM32F103C8T6最小系统板的基本部分: 单片机芯片:STM32F103C8T6本身,它是一款32位微…...