当前位置: 首页 > news >正文

【设计模式】【创建型模式】【02工厂模式】

系列文章

可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501


目录

系列文章

1.简介

2.简单工厂模式

2.1 简介

2.1.1 组成结构

2.1.2 优点和缺点

2.1.3 应用场景

2.2 代码案例

2.2.1 主要步骤

2.2.2 代码

3.工厂方法模式

3.1简介

3.1.1 组成结构

3.1.2 优点和缺点

3.1.3 应用场景

3.2 代码案例

3.2.1 主要步骤

3.2.2 代码

4.抽象工厂模式

4.1简介

4.1.1 组成结构

4.1.2 优点和缺点

4.2 代码案例

4.2.1 主要步骤

4.2.2 代码

5.区别


1.简介

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,即定义一个用于创建对象的接口,让子类决定应该实例化哪个类,使类的实例化延迟到子类。 也可以这样理解,
工厂模式可以分为三类:
1.简单工厂模式(Simple Factory)
2.工厂方法模式(Factory Method)
3.抽象工厂模式(Abstract Factory)

2.简单工厂模式

2.1 简介

简单工厂模式是通过一个工厂类将所有对象的创建封装起来,通过传入不同的参数,工厂负责创建不同的具体对象。

建立对象的类是工厂,被建立的对象是产品,使用产品的人无需关心这个产品是怎样生产的,这样便降低了模块之间的耦合。

2.1.1 组成结构

1.工厂类:用来创建所有产品,通过传入的type不同,从而创建不同的产品。例如:本节案例代码中的Factory类。

2.抽象产品类:它一般是具体产品继承的父类或者实现的接口。例如:本节案例代码中的Car类。

3.具体产品类此类继承抽象产品类,自工厂类所创建的对象就是此角色的实例。例如:本节案例代码中的CarA类和CarB类。

特点:一个工厂生产所有的具体产品。

2.1.2 优点和缺点

优点:
1.将所有对象的创建集合到了一个工厂类中,客户端只需要调用工厂类的接口,传入不同的参数,而无需关注具体对象的创建过程。

2.可以通过工厂类创建不同的对象,而客户端无需改动,实现了客户端和具体所有对象的解耦,提高了代码的灵活性。
缺点:
1.每新增一个产品,则需要修改工厂类的逻辑,违反了开闭原则。
2.当产品足够多的时候,代码会过于臃肿,不利于维护。

2.1.3 应用场景

1.需要根据不同的参数类型创建不同的对象时。

2.2 代码案例

当前代码场景:

我们现在一个工厂要生产车型A和车型B

2.2.1 主要步骤

第一步:创建抽象产品类Car和创建抽象run函数
第二步:创建具体产品类车型A(CarA),实现其抽象run函数。
第三步:创建具体产品类车型B(CarB),实现其抽象run函数
第四步:创建工厂类Factory,并书写根据不同参数创建不同车型的createCar方法。
第五步:客户端(此例是main.cpp调用)创建工厂类对象,通过传递不同的参数,工厂创建不同的对象并返回给客户。

2.2.2 代码

// 抽象产品类
class Car
{public:virtual void run() = 0; // 抽象共同接口string cartype;
};// 具体产品类:车A
class CarA : public Car
{public:CarA(){cartype = "A 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 具体产品类:车B
class CarB : public Car
{public:CarB(){cartype = "B 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 工厂类
class Factory
{
public:Car *createCar(int type){switch (type){case CAR_TYPE_A:return new CarA();break;case CAR_TYPE_B:return new CarB();break;default:return nullptr;break;}}
};int main()
{Factory *mFactory = new Factory();           // c创建工厂类Car *acar = mFactory->createCar(CAR_TYPE_A); // 根据具体的参数创建对应的对象,此处是父类指针指向子类对象Car *bcar = mFactory->createCar(CAR_TYPE_B);acar->run();bcar->run();// 注意析构delete acar;delete bcar;delete mFactory;return 0;
}

3.工厂方法模式

3.1简介

工厂方法模式在简单工厂模式的基础上,去掉了简单工厂模式中的创建所有对象的方法,并提供了一个抽象生产产品的接口,并使其它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
简单工厂模式的特点是一个工厂只生产所有产品,而工厂方法模式则是一个工厂只生产一个产品,这样当生产产品的时候,只需要确定是哪个工厂即可。

3.1.1 组成结构

1.抽象工厂类:是具体工厂类的父类,其包含一个具体工厂类必须实现的抽象接口。例如:本节案例代码的Factory类,抽象接口是createCar函数。
2.具体工厂类:对应其具体产品,用以创建对应的具体产品的对象。例如:本节案例代码的工厂A和工厂B,工厂A负责生产车型A, 工厂B负责生产车型B。
3.抽象产品类:它是具体产品继承的父类。例如:本节案例代码的Car类。
4.具体产品类:具体工厂类所创建的对象就是此类的实例。例如:本节案例代码的车型A类和车型B类。

3.1.2 优点和缺点

优点:
1.当需要增加新的工厂和产品的时候,可以不用更改现有代码,增加了代码的可扩展性,将对象的创建和使用进行了解耦。
缺点:
1.当产品种类过多时,由于每一种产品都需要实现一个工厂类,增加代码复杂性。

3.1.3 应用场景

当只有一类产品时。同时客户端需要生成不同的对象。

3.2 代码案例

此时场景为:
A工厂生产车型A,B工厂生产车型B

3.2.1 主要步骤

第一步:创建抽象产品类(Car类)。

第二步:创建抽象产品类的两个子类(CarA类和CarB类),其子类是具体产品类。

第三步:创建抽象工厂类(Factory类),并提供生产对象的抽象接口。

第四步:创建两个具体工厂类,一个是生产CarA的工厂类,一个是生产CarB的工厂类,并实现抽象方法,创建不同的产品对象。

第五步:客户端(此例是main.cpp调用)创建不同的工厂类对象,从而创建出多个不同的产品对象。

3.2.2 代码

// 抽象产品类
class Car
{public:virtual void run() = 0; // 抽象共同接口string cartype;
};// 具体产品类:车A
class CarA : public Car
{public:CarA(){cartype = "A 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 具体产品类:车B
class CarB : public Car
{public:CarB(){cartype = "B 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 抽象工厂类
class Factory
{
public:virtual Car *createCar() = 0;
};// 具体工厂类:工厂A(对应产品A)
class FactoryA : public Factory
{
public:virtual Car *createCar(){return new CarA();}
};
// 具体工厂类:工厂B(对应产品B)
class FactoryB : public Factory
{
public:virtual Car *createCar(){return new CarB();}
};int main()
{Factory *mFactoryA = new FactoryA(); // 创建具体工厂类ACar *acar = mFactoryA->createCar();  // 根据具体的工厂类创建对应的对象,此处是父类指针指向子类对象acar->run();Factory *mFactoryB = new FactoryB(); // 创建具体工厂类BCar *bcar = mFactoryB->createCar();  // 根据具体的工厂类创建对应的对象,此处是父类指针指向子类对象bcar->run();// 注意析构delete acar;delete bcar;delete mFactoryA;delete mFactoryB;return 0;
}

4.抽象工厂模式

之前的工厂方法模式一个工厂只生产一个产品,而在实际生活中,通过一个工厂会生产多种产品,比如:车的组成需要轮胎和方向盘,那么当出现多个产品的时候,便需要使用抽象工厂模式。

4.1简介

提供一个创建一系列相关或相互依赖的对象接口,而无需指定它们的具体类。其实抽象工厂模式就是多个工厂方法模式,只是因为工厂方法是一个工厂只创建一个产品,而抽象工厂模式是一个工厂创建多个产品。

4.1.1 组成结构

抽象工厂类:是具体工厂类的父类,其内部定义了创建多个产品对象的抽象接口,必须由具体工厂类实现。
例如:本节代码案例中的Factory类,抽象接口为createTire和createWheel。

具体工厂类:对应其具体产品,用以创建对应的具体产品的对象。
例如:本节代码案例中的 具体工厂(工厂白色)和具体工厂(工厂黑色)。

抽象产品类:定义了产品的共同接口,具体的产品类必须实现这个接口。工厂模式会由多个产品,因此抽象产品类也是多个。
例如:本节代码案例中的第一个抽象产品类(轮胎)和第二个抽象产品类(方向盘)。

具体产品类:是抽象工厂模式中具体创建的对象。
例如:本节代码案例中的白轮胎和黑轮胎,白方向盘和黑方向盘。

4.1.2 优点和缺点

优点:
创建产品族,将一系列的产品族,统一到一起进行创建
缺点:
扩展困难,当产品族中有新产品,比如新增发动机产品时,需要修改抽象工厂的接口。

4.2 代码案例

现在场景为:
白色工厂需要生产白色轮胎和白色方向盘。
黑色工厂需要生产黑色轮胎和黑色方向盘。
白色系列产品由白色工厂统一管理。
黑色系列产品由黑色工厂统一管理。

4.2.1 主要步骤

第一步:创建第一个抽象产品类(轮胎类)。

第二步:创建第一个抽象产品类的两个子类(白轮胎类和黑轮胎类),其子类是具体产品类。

第三步:创建第二个抽象产品类(方向盘类)。

第四步:创建第二个抽象产品类的两个子类(白方向盘类和黑方向盘类),其子类是具体产品类。

第五步:创建抽象工厂类(Factory类),并提供生产所有对象的两个抽象接口。

第六步:创建两个具体工厂类,一个是生产白色产品的白色工厂类,一个是生产黑色产品的白色工厂类,并实现两个抽象方法,创建不同的产品对象。

第七步:客户端(此例是main.cpp调用)创建不同的工厂类对象,从而创建出多个不同的产品对象。

4.2.2 代码

// 第一个抽象产品类:轮胎
class Tire
{public:virtual void whcihtype() = 0;string Tiretype;
};// 第一个抽象产类的第一个具体产品类:白轮胎
class WhiteTire : public Tire
{public:WhiteTire(){Tiretype = "白色轮胎";}virtual void whcihtype(){std::cout << "this is Tiretype = " << Tiretype << endl;}
};// 第一个抽象产类的第二个具体产品类:黑轮胎
class BlackTire : public Tire
{public:BlackTire(){Tiretype = "黑色轮胎";}virtual void whcihtype(){std::cout << "this is Tiretype = " << Tiretype << endl;}
};// 第二个抽象产品类:方向盘
class Wheel
{
public:virtual void whcihtype() = 0;string Wheeltype;
};// 第二个抽象产类的第一个具体产品类:白色方向盘
class WhiteWheel : public Wheel
{public:WhiteWheel(){Wheeltype = "白色方向盘";}virtual void whcihtype(){std::cout << "this is Wheeltype = " << Wheeltype << endl;}
};// 第二个抽象产类的第二个具体产品类:黑色方向盘
class BlackWheel : public Wheel
{public:BlackWheel(){Wheeltype = "黑色方向盘";}virtual void whcihtype(){std::cout << "this is Wheeltype = " << Wheeltype << endl;}
};// 抽象工厂类
class Factory
{
public:virtual Tire *createTire() = 0; // 抽象接口virtual Wheel *createWheel() = 0;
};// 具体工厂类:工厂白色(对应生产白色轮胎和白色方向盘)
class FactoryWhite : public Factory
{
public:virtual Tire *createTire(){return new WhiteTire(); // 生产白轮胎}virtual Wheel *createWheel(){return new WhiteWheel(); // 生产白方向盘}
};// 具体工厂类:工厂黑色(对应生产黑色轮胎和黑色方向盘)
class FactorBlock : public Factory
{
public:virtual Tire *createTire(){return new BlackTire(); // 生产黑轮胎}virtual Wheel *createWheel(){return new BlackWheel(); // 生产黑方向盘}
};int main()
{Factory *mFactoryWhite = new FactoryWhite();    // 创建具体工厂类:工厂白色Tire *mWhiteTire = mFactoryWhite->createTire(); // 创建白色轮胎mWhiteTire->whcihtype();Wheel *mWhiteWheel = mFactoryWhite->createWheel(); // 创建白色方向盘mWhiteWheel->whcihtype();Factory *mFactoryBlock = new FactorBlock();     // 创建具体工厂类:工厂黑色Tire *mBlockTire = mFactoryBlock->createTire(); // 创建黑色轮胎mBlockTire->whcihtype();Wheel *mBlockWheel = mFactoryBlock->createWheel(); // 创建黑色方向盘mBlockWheel->whcihtype();// 注意析构delete mFactoryWhite;delete mWhiteTire;delete mWhiteWheel;delete mFactoryBlock;delete mBlockTire;delete mBlockWheel;return 0;
}

5.区别

简单工厂模式:
一个抽象产品类,可以派生出多个具体产品类。
无抽象工厂类,只有一个工厂类,此工厂类负责生产所有产品。

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。

总结:

抽象产品类:工厂方法模式和简单工厂模式都只有一个抽象产品类,而抽象工厂模式有多个。

具体产品类:工厂方法模式和简单工厂模式都只能有一个抽象产品类派生出多个具体产品类,而抽象工厂模式可以从多个抽象产品类派生出多个具体产品类。

抽象工厂类:工厂方法模式和抽象工厂模式都有一个抽象工厂类,而简单工厂模式没有。

具体工厂类:简单工厂模式只有一个工厂类,而工厂方法模式和抽象工厂模式可以有多个具体工厂类。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

相关文章:

【设计模式】【创建型模式】【02工厂模式】

系列文章 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录 系…...

FPGA设计中的流水线 -分割大的计算电路可以更快的处理数据。

FPGA&#xff08;现场可编程门阵列&#xff09;设计中的流水线优化是一种提高设计性能的技术&#xff0c;它通过将设计分解为多个阶段或步骤来实现。每个阶段可以并行执行&#xff0c;从而提高整体的吞吐量和效率。以下是流水线优化的一些关键概念和作用&#xff1a; 意思&…...

GNU/Linux - U-BOOT的GPIO command

在嵌入式Linux开发中&#xff0c;先运行的是u-boot&#xff0c;然后再加载Linux内核。 启动时如果设置了u-boot等待时间&#xff0c;在等待时间内&#xff0c;按任意键就会进入u-boot命令行环境。 在u-boot命令行环境下&#xff0c;可以使用gpio命令来操作GPIO。 Synopsis gpi…...

35.UART(通用异步收发传输器)-RS232(2)

&#xff08;1&#xff09;RS232接收模块visio框图&#xff1a; &#xff08;2&#xff09;接收模块Verilog代码编写: /* 常见波特率&#xff1a; 4800、9600、14400、115200 在系统时钟为50MHz时&#xff0c;对应计数为&#xff1a; (1/4800) * 10^9 /20 -1 10416 …...

OpenLayers学习笔记-点位聚合

需求 用户点击行政区划等操作后,从后台获取区域内的点位数据,在地图上聚合显示。用户手动取消聚合,点位直接渲染在地图上。 实现过程 使用后台返回的点位数据,通过new ol.source.Vector({features})创建矢量数据源。使用new ol.source.Cluster({source})创建聚合标注数据…...

flutter实现语言的国际化

目录 前言 一、GetX实现国际化(推荐) 1.安装Getx 2.创建国际化的文件 3.使用国际化字符串 4.配置GetMaterialApp 5.更改语言 6.系统语言 ​编辑 7.原生工程配置 1.iOS工程配 1.打开iOS工程&#xff0c;在Project的info里面添加语言 2.创建String File文件 2.andr…...

服务端正常启动了,但是客户端请求不到

服务端正常启动了&#xff0c;但是客户端请求不到有哪些原因?如何排查? 如果客户端请求的接口没有响应&#xff0c;排查的方式&#xff1a; 检查接口IP地址是否正确&#xff0c;ping一下接口地址。 检查被测接口端口号是否正确&#xff0c;可以在本机Telnet接口的IP和端口号…...

鸿蒙开发 -本地数据库操作

// 1导入模块 import relationalStore from @ohos.data.relationalStore;export class AthUserDbManager{//2.获取RdbStore实例,要注意的是,此处的getContext(this)用于获取应用上下文:getcreatDbtable(dbname:string){//配置数据库信息:const STORE_CONFIG :relationalStor…...

主机安全-进程、命令攻击与检测

目录 概述反弹shell原理nc/dev/xxx反弹shell下载不落地反弹Shell各种语言反弹shell linux提权sudosuid提权mysql提权 Dnslog参考 概述 本文更新通过在主机&#xff08;不含容器&#xff09;上直接执行命令或启动进程来攻击的场景。检测方面以字节跳动的开源HIDS elkeid举例。每…...

FPGA FIR fdatool filter designer MATLAB

位数问题 fdatool 先确定输入信号的位宽&#xff0c;比如17位在fdatool中&#xff0c;选set quantization parameters 选input/output 设置input word length 为17bit(not confirmed) fir compiler implementation 注意&#xff1a; 当设置输入位宽为16位时&#xff0c;ip核…...

水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集)

水表数字识别2&#xff1a;Pytorch DBNet实现水表数字检测(含训练代码和数据集) 目录 水表数字识别2&#xff1a;Pytorch DBNet实现水表数字检测(含训练代码和数据集) 1.前言 2. 水表数字识别的方法 3. 水表数字识别数据集 4. 水表数字分割模型训练 &#xff08;1&#x…...

Windows 点云生成二维栅格图 [附C++完整代码实现]

点云压缩-2D栅格图 一、点云压缩(二维栅格图)二、算法流程三、代码实现四、结果可视化一、点云压缩(二维栅格图) 点云压缩:点云是海量点的集合,其数据量通常非常庞大。直接存储这些未经压缩的点云数据会消耗大量的存储空间,特别是在处理大规模的点云数据时,这个问题变得…...

SpringBoot结合ip2region实现博客评论显示IP属地

你好呀&#xff0c;我是小邹。 在现代的Web应用中&#xff0c;特别是博客和论坛类网站&#xff0c;为用户提供地理定位服务&#xff08;如显示用户所在地理位置&#xff09;可以极大地增强用户体验。本文将详细探讨如何使用Java和相关技术栈来实现在博客评论中显示用户的地址信…...

设计模式使用场景实现示例及优缺点(行为型模式——策略模式)

在遥远的王国里&#xff0c;有三个重要的角色&#xff1a;国王策略模式、他的皇家顾问算法家族&#xff0c;以及年轻的骑士接口。国王策略模式统治着整个王国&#xff0c;他的职责是确保每一个编程问题都能找到最合适的解决方案。 有一天&#xff0c;王国遇到了一场危机。编程王…...

ReactRouter v6升级的步骤

React Router v6 引入了一个 Routes 组件&#xff0c;它有点像 Switch &#xff0c;但功能要强大得多。与 Switch 相比&#xff0c; Routes 的主要优势在于&#xff1a; <Routes> 中的所有 <Route> 和 <Link> 都是相对的。这导致在 <Route path> 和 &…...

【JVM实战篇】内存调优:内存问题诊断+案例实战

文章目录 诊断内存快照在内存溢出时生成内存快照MAT分析内存快照MAT内存泄漏检测的原理支配树介绍如何在不内存溢出情况下生成堆内存快照&#xff1f;MAT查看支配树MAT如何根据支配树发现内存泄漏 运行程序的内存快照导出和分析快照**大文件的处理** 案例实战案例1&#xff1a;…...

专业条码二维码扫描设备和手机二维码扫描软件的区别?

条码二维码技术已广泛应用于我们的日常生活中&#xff0c;从超市结账到公交出行&#xff0c;再到各类活动的入场验证&#xff0c;条码二维码的便捷性不言而喻&#xff0c;而在条码二维码的扫描识别读取过程中&#xff0c;专业扫描读取设备和手机二维码扫描软件成为了两大主要工…...

基于嵌入式Linux的高性能车载娱乐系统设计与实现 —— 融合Qt、FFmpeg和CAN总线技术

随着汽车智能化的发展&#xff0c;车载娱乐系统已成为现代汽车的标配。本文介绍了一个基于Linux的车载娱乐系统的设计与实现过程。该系统集成了音视频娱乐、导航、车辆信息显示等功能&#xff0c;旨在提供安全、便捷、丰富的驾驶体验。 1. 项目概述 随着汽车智能化的发展&…...

探索IP形象设计:快速掌握设计要点

随着市场竞争的加剧&#xff0c;越来越多的企业开始关注品牌形象的塑造和推广。在品牌形象中&#xff0c;知识产权形象设计是非常重要的方面。在智能和互联网的趋势下&#xff0c;未来的知识产权形象设计可能会更加关注数字和社交网络。通过数字技术和社交媒体平台&#xff0c;…...

泛微Ecology8明细表对主表赋值

文章目录 [toc]1.需求及效果1.1 需求1.2 效果2.思路与实现3.结语 1.需求及效果 1.1 需求 在明细表中的项目经理&#xff0c;可以将值赋值给主表中的项目经理来作为审批人员 1.2 效果 在申请人保存或者提交后将明细表中的人名赋值给主表中对应的值2.思路与实现 在通过js测…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...