软件设计原则 1小时系列 (C++版)
文章目录
- 前言
- 基本概念
- Design Principles
- ⭐单一职责原则
- (SRP) Single Responsibility Principle
- Code
- ⭐里氏替换原则
- (LSP) Liskov Substitution Principle
- Code
- ⭐开闭原则
- (OCP) Open Closed Principle
- Code
- ⭐依赖倒置原则
- (DIP) Dependency Inversion Principle
- Code
- ⭐接口隔离原则
- (ISP) Interface Segregation Principle
- Code
- ⭐迪米特法则
- (LOD) Law of Demeter
- 无具体Code
- ⭐合成复用原则
- (CRP) Composite Reuse Principle
- Code
- END
- 设计模式 李建忠 C++
- 敏捷软件开发 - 面向对象设计的原则
前言
申明:
原视频:
面向对象-软件设计原则-1小时搞懂-波波酱老师_哔哩哔哩_bilibili
本文为up主的视频教学总结成文本和code
业主要是为了Cpper学习者学习。因为up在视频中使用的是java描述。
基本概念
-
📌可维护性质
在不破坏原有代码设计,不要引入新bug的情况下,能够快速修改或者添加代码
生活案例:比如一个iPhone在维修摄像头的时候,如果一个手抖,就可能呆滞喇叭或者麦克风损坏,从而影响了通讯或者音视频功能,因为它们都集成在一个电路板上。但是,单反在维修的时候,就不存在这种情况‘
-
📌可扩展性
在不修改或者少量修改原有代码的情况下,可以通过扩展的方式添加新的功能代码
生活案例:中秋到了,拿着iPhone想要拍个月亮发朋友圈,但是不管怎么拍,效果都不好。这个时候,只见隔壁老王把单发装在三脚架上,然后换上长焦镜头,“咔嚓”一声,我凑过去一看,“哇,真的是又大又圆啊!”。这个时候,单反可以根据不同的拍摄场景,扩展不同的镜头。
-
📌可复用性
尽量减少代码的重复编写,直接复用已有的代码
生活案例:开发教务系统的时候,直接复用权限管理模块
-
📌内聚性
模块内部元素的紧密程度,内聚性越高,那么模块独立性越好,可维护性,复用性也越高
-
📌耦合性
模块与模块之间的关联关系,耦合度越高,那么模块与模块之间的关联越复杂,那么可维护性,复用性越差
Design Principles
⭐单一职责原则
(SRP) Single Responsibility Principle
一个类或者模块只负责完成一个职责(或者功能)。
通俗的讲,如果这个类包含两个或者多个不相干的功能,那么这个类的职责就不够单一,应该将它拆分成多个功能更加单一,粒度更细的类。
单一职责原则是实现高内聚,低耦合的指导方针,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实现经验。
Code
old
#include <iostream>
#include <string>class UserInfo {
private:long userID;std::string userName;std::string phone;std::string province;std::string city;std::string region;std::string detailAddress;public:void save() {std::cout << "save user information" << std::endl;}void saveAddress() {std::cout << "save address information" << std::endl;}
};
new
#include <iostream>
#include <list>
#include <string>class Address {
private:std::string city;std::string region;std::string detailAddress;public:void saveAddress() {std::cout << "save address information" << std::endl;}
};class UserInfo {
private:long userID;std::string userName;std::string phone;std::string province;std::list<Address> addressList;public:void save() {std::cout << "save user information" << std::endl;}
};
⭐里氏替换原则
(LSP) Liskov Substitution Principle
子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的瑞吉行为不变及正确性不被破快。
通俗理解:子类可以扩展父类的功能,但不改变父类原有的功能。
换句话说,子类继承父类时,除添加新的方法完成新功能外,尽量不要重写父类的方法,如果重写父类方法,程序运行会发生出错概率。
如果一定要用多态,那么父类可以设计成抽象父类或者接口。
Code
old
#include <iostream>// 接口过于庞大
class PhoneFunction {
public:virtual void call() = 0;virtual void message() = 0;virtual void camera() = 0;
};class ApplePhone : public PhoneFunction {
public:virtual void call() override {std::cout << "Apple " << __func__ << std::endl;}virtual void message() override {std::cout << "Apple " << __func__ << std::endl;}virtual void camera() override {std::cout << "Apple " << __func__ << std::endl;}
};class OldPhone : public PhoneFunction {
public:virtual void call() override {std::cout << "Old " << __func__ << std::endl;}virtual void message() override {std::cout << "Old " << __func__ << std::endl;}virtual void camera() override {std::cout << "Old " << __func__ << std::endl;}
};
new
#include <iostream>// 接口粒度最小
struct Call {virtual void call() = 0;
};struct Message {virtual void message() = 0;
};struct Camera {virtual void camera() = 0;
};class ApplePhone : public Call, public Message, public Camera {
public:virtual void call() override {std::cout << "Apple " << __func__ << std::endl;}virtual void message() override {std::cout << "Apple " << __func__ << std::endl;}virtual void camera() override {std::cout << "Apple " << __func__ << std::endl;}
};class OldPhone : public Call, public Message {
public:virtual void call() override {std::cout << "Old " << __func__ << std::endl;}virtual void message() override {std::cout << "Old " << __func__ << std::endl;}
};
⭐开闭原则
(OCP) Open Closed Principle
对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不要去修改原有代码,实现一个热拔插的效果。
简而言之,是为了使程序的扩展性好,易于维护与升级。
想要达到这样的效果,我们需要使用接口和抽象类。
因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。
而软件中异变的细节可以从抽象派生的实现类来进行扩展,当软件需要发生变化时,只需要根据需求派生一个实现类来扩展就可以了。
Code
old
#include <ctime>
#include <iostream>
#include <string>class Equation {
protected:int leftNum;int rightNum;int result;std::string op;public:std::string toString() {return std::to_string(leftNum) + op + std::to_string(rightNum) + "=" +std::to_string(result);}int generateRandom(int min, int max) {return rand() % (max - min + 1) + min;}Equation generateEquation(std::string op) {leftNum = generateRandom(0, 100);rightNum = generateRandom(0, 100);if (op == "+") {result = leftNum + rightNum;} else if (op == "-") {result = leftNum - rightNum;}this->op = op;return *this;}
};int main() {srand(time(0));Equation equation = Equation().generateEquation("-");std::cout << equation.toString() << std::endl;
}
new
#include <ctime>
#include <iostream>
#include <string>class Equation {
protected:int leftNum;int rightNum;int result;std::string op;public:std::string toString() {return std::to_string(leftNum) + op + std::to_string(rightNum) + "=" +std::to_string(result);}int generateRandom(int min, int max) {return rand() % (max - min + 1) + min;}// 抽象方法// 注意,C++中,抽象基类无法实例化,因此无法直接返回`Equation`virtual Equation* generateEquation() = 0;
};class AddEquation : public Equation {
public:Equation* generateEquation() override {leftNum = generateRandom(0, 100);rightNum = generateRandom(0, 100);result = leftNum + rightNum;this->op = "+";return this;}
};class SubEquation : public Equation {
public:Equation* generateEquation() override {leftNum = generateRandom(0, 100);rightNum = generateRandom(0, 100);result = leftNum - rightNum;this->op = "-";return this;}
};int main() {srand(time(0));// 多态Equation* equation = (new SubEquation())->generateEquation();std::cout << equation->toString() << std::endl;delete equation;equation = (new AddEquation())->generateEquation();std::cout << equation->toString() << std::endl;delete equation;
}
⭐依赖倒置原则
(DIP) Dependency Inversion Principle
模块之间要依赖抽象,不依赖实现,要面向接口编程,不要面向实现编程。
高层模块不应该直接依赖底层模块,这样就降低了客户端与实现模块间的耦合。
Code
old
#include <iostream>class IntelCpu {
public:void calculate() {std::cout << "IntelCpu " << __func__ << std::endl;}
};class IntelMemory {
public:void storage() {std::cout << "IntelMemory " << __func__ << std::endl;}
};class Computer {
private:IntelCpu intelCpu;IntelMemory intelMemory;public:Computer() {}Computer(IntelCpu intelCpu, IntelMemory intelMemory) {this->intelCpu = intelCpu;this->intelMemory = intelMemory;}void startRun() {intelCpu.calculate();intelMemory.storage();}
};int main() {IntelCpu intelCpu;IntelMemory intelMemory;Computer computer(intelCpu, intelMemory);computer.startRun();
}
new
#include <iostream>class Cup {
public:virtual void calculate() = 0;
};class Memory {
public:virtual void storage() = 0;
};class IntelCpu : public Cup {
public:void calculate() override {std::cout << "IntelCpu " << __func__ << std::endl;}
};class IntelMemory : public Memory {
public:void storage() override {std::cout << "IntelMemory " << __func__ << std::endl;}
};class AmdCpu : public Cup {
public:void calculate() override {std::cout << "AmdCpu " << __func__ << std::endl;}
};class AmdMemory : public Memory {
public:void storage() override {std::cout << "AmdMemory " << __func__ << std::endl;}
};class Computer {
private:Cup* cpu;Memory* memory;public:Computer() {}Computer(Cup* cpu, Memory* memory) {this->cpu = cpu;this->memory = memory;}void startRun() {cpu->calculate();memory->storage();}
};int main() {Computer computer;IntelCpu intelCpu;IntelMemory intelMemory;computer = Computer(&intelCpu, &intelMemory);computer.startRun();AmdCpu amdCpu;AmdMemory amdMemory;computer = Computer(&amdCpu, &amdMemory);computer.startRun();
}
⭐接口隔离原则
(ISP) Interface Segregation Principle
客户端不应该被迫依赖于它不适用的方法,一个类对于另一个类的依赖应该建立在最小的接口上。
一个类实现一个接口,就必须实现这个接口的所有抽象方法,如果接口的设计过于庞大的话,实现类就被迫实现不需要的抽象方法。
Code
old
#include <iostream>class Bird {
protected:double runSpeed;double flySpeed;public:virtual void setRunSpeed(double runSpeed) {this->runSpeed = runSpeed;}virtual void setFlySpeed(double flySpeed) {this->flySpeed = flySpeed;}double calcFlyTime(double distance) {return distance / flySpeed;}double calcRunTime(double distance) {return distance / runSpeed;}
};class Parrot : public Bird {
public:void studySpeak() {std::cout << __func__ << std::endl;}
};class Ostrich : public Bird {
public:virtual void setFlySpeed(double flySpeed) override {this->flySpeed = 0;}
};int main() {Bird* parrot = new Parrot();parrot->setFlySpeed(150.0);std::cout << "fly 300km" << std::endl;std::cout << "parrot uses " << parrot->calcFlyTime(300.0) << " hours"<< std::endl;Bird* ostrich = new Ostrich();ostrich->setFlySpeed(150.0);std::cout << "fly 300km" << std::endl;std::cout << "ostrich uses " << ostrich->calcFlyTime(300.0) << " hours"<< std::endl;
}
new
#include <iostream>class Bird {
protected:double runSpeed;double flySpeed;public:virtual void setRunSpeed(double runSpeed) {this->runSpeed = runSpeed;}virtual void setFlySpeed(double flySpeed) {this->flySpeed = flySpeed;}double calcFlyTime(double distance) {return distance / flySpeed;}double calcRunTime(double distance) {return distance / runSpeed;}
};class Parrot : public Bird {
public:void studySpeak() {std::cout << __func__ << std::endl;}
};class Ostrich : public Bird {
public:virtual void setFlySpeed(double flySpeed) override {this->flySpeed = 0;}
};int main() {Bird* parrot = new Parrot();parrot->setFlySpeed(150.0);std::cout << "fly 300km" << std::endl;std::cout << "parrot uses " << parrot->calcFlyTime(300.0) << " hours"<< std::endl;Bird* ostrich = new Ostrich();ostrich->setFlySpeed(150.0);std::cout << "fly 300km" << std::endl;std::cout << "ostrich uses " << ostrich->calcFlyTime(300.0) << " hours"<< std::endl;
}
⭐迪米特法则
(LOD) Law of Demeter
迪米特法则来自于1987年美国东北大学的一个名为Demeter的一个项目,只跟朋友联系,不跟“陌生人”说话。
如果两个软件实体无须直接通信,那么就不应该发生直接的互相调用,可以通过第三方转发该调用。
其目的是降低类之间的耦合度,提高模块的相对独立性。
无具体Code
无具体code
这个发展在项目中的各个模块调用非常之多,需要多项目,业务非常熟悉才能搭建良好的结构。
⭐合成复用原则
(CRP) Composite Reuse Principle
尽量先适用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
通常类的复用分为继承复用和合成复用两种。
继承复用虽然简单和易实现的优点,但它也存在以下缺点:
- 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为”白箱“复用。
- 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展和维护。
采用组合或聚合复用时,可以将已有的对象纳入新对象中,使之成功新对象的一部分,新对象可以调用已有对象的功能,它有以下优点:
- 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称”黑箱“复用。
- 对象间的耦合度低。可以在类的成员位置声明抽象(抽象类或者接口)
Code
old
#include <iostream>
#include <string>class A {
protected:std::string name;int age;public:void methodA() {std::cout << "A " << __func__ << std::endl;}
};class B : public A {
public:void methodB() {std::cout << "B " << __func__ << std::endl;}
};int main() {B b;b.methodA();b.methodB();
}
new
#include <iostream>
#include <string>class A {
protected:std::string name;int age;public:void methodA() {std::cout << "A " << __func__ << std::endl;}
};class B : public A {
public:void methodB() {std::cout << "B " << __func__ << std::endl;}
};int main() {B b;b.methodA();b.methodB();
}
END
设计模式 李建忠 C++
设计模式 李建忠 C++
敏捷软件开发 - 面向对象设计的原则
在敏捷软件开发中提出了以下设计原则
SRP 单一职责原则
就一个类而言,应该仅有一个引起它变化的原因
OCP 开放封闭原则
软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改
LSP Liskov替换原则
子类型必须能替换换他们的基本类型
DIP 依赖倒置原则
抽象不应该依赖细节。细节应该依赖于抽象。
ISP 接口隔离原则
不应该强迫客户依赖于他们不用的方法。接口属于客户,不属于他所在的类层次结构。
REP 重用发布等价原则
重用的粒度就是发布的粒度
CCP 共用重用原则
一个包中的所有类应该是共用重用的。如果重用了包中的一个类,那么就重用包中的所有类。互相之间没有紧密联系的类不应该在同一个包中。
CRP 共用封闭原则
一个包中的所有类对于同一个类性质的变化应该是共同封闭的。一个变化若对一个包影响,则将对包中的所有类产生影响,而对其他的包不造成任何影响。
ADP 无依赖原则
在包的依赖关系中不存在环。细节不应该被依赖。
SDP 稳定依赖原则
朝着稳定的方向依赖。
ASP 稳定抽象原则
一个包的抽象程度应该和其他稳定程度一致。
相关文章:
软件设计原则 1小时系列 (C++版)
文章目录 前言基本概念 Design Principles⭐单一职责原则(SRP) Single Responsibility PrincipleCode ⭐里氏替换原则(LSP) Liskov Substitution PrincipleCode ⭐开闭原则(OCP) Open Closed PrincipleCode ⭐依赖倒置原则(DIP) Dependency Inversion PrincipleCode ⭐接口隔离…...
数据结构--》解锁数据结构中树与二叉树的奥秘(一)
数据结构中的树与二叉树,是在建立非线性数据结构方面极为重要的两个概念。它们不仅能够模拟出生活中各种实际问题的复杂关系,还常被用于实现搜索、排序、查找等算法,甚至成为一些大型软件和系统中的基础设施。 无论你是初学者还是进阶者&…...
23.4 Bootstrap 框架5
1. 背景颜色 1.1 背景颜色样式 在Bootstrap 5中, 可以使用以下类来设置背景颜色: * 1. .bg-primary: 设置为主要的背景颜色(#007bff, 深蓝色). * 2. .bg-secondary: 设置为次要的背景颜色(#6c757d, 灰色). * 3. .bg-success: 设置为成功的背景颜色(#28a745, 绿色). * 4. …...
Spring源码解析——IOC属性填充
正文 doCreateBean() 主要用于完成 bean 的创建和初始化工作,我们可以将其分为四个过程: 最全面的Java面试网站 createBeanInstance() 实例化 beanpopulateBean() 属性填充循环依赖的处理initializeBean() 初始化 bean 第一个过程实例化 bean在前面一篇…...
寒露到了,冬天还会远吗?
寒露惊秋晚,朝看菊渐黄。 日复一日间,光影如梭,我们便很快将告别了秋高气爽,白日将变得幽晦, 天寒夜长,风气萧索,雾结烟愁。 还没好好体会秋高气爽,寒露就到了。 今天晚上9点多,我们…...
科普②| 大数据有什么用?大数据技术的应用领域有哪些?
1、提供个性服务很多人觉得大数据好像离我们很远,其实我们在日常所使用的智能设备,就需要大数据的帮助。比如说我们运动时候戴的运动手表或者是运动手环,就可以在我们平时运动的时候,帮助我们采集运动数据及热量消耗情况。进入睡眠…...
golang的切片使用总结二
如果没看golang切片的第一篇总结博客 golang的切片使用总结一-CSDN博客 ,请浏览之 举例9:make([]int, a, b)后访问下标a的元素 s : make([]int, 10, 12) v : s[10] fmt.Printf("v:%v", v) 打印结果: panic: runtime error: index …...
tailscale自建headscale和derp中继
tailscale derp中继服务简介 tailscale是一个基于WireGuard的零配置软件,它可以轻松地在多台设备之间建立点对点加密连接。 derp服务器是tailscale网络的重要组成部分。它作为tailscale客户端之间的中继,帮助客户端找到并连接到其他客户端设备。 但Tailscale 官方…...
布隆过滤器的使用
布隆过滤器简介 Bloom Filter(布隆过滤器)是一种多哈希函数映射的快速查找算法。它是一种空间高效的概率型数据结构,通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合。 布隆过滤器的优势在于,利用很少的空…...
Web开发-单例模式
目录 单例模式介绍代码实现单例模式 单例模式介绍 单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。单例模式可以通过private属性实现。通过将类的构造函数设为private,可以防止类在外部被实例化。单例模式通…...
MySQL:温备份和恢复-mysqldump (4)
介绍 温备:同样是在数据库运行的时候进行备份的,但对当前数据库的操作会产生影响。(只可以读操作,不可以写操作) 温备份的优点: 1.可在表空间或数据文件级备份,备份时间短。 2.备份时数据库依然…...
【力扣每日一题】2023.10.8 股票价格波动
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 这道题是程序设计题,要我们实现一个类,一共是四个功能,第一个是给一个时间戳和价格,表示该…...
Linux隐藏文件或文件夹
在Linux中,以点(.)开头的文件或文件夹是隐藏文件或隐藏文件夹。要创建一个隐藏文件或文件夹,可以使用以下命令: 创建隐藏文件: touch .filename这将在当前目录下创建一个名为 “.filename” 的隐藏文件。…...
leetcode - 365周赛
一,2873.有序三元组中的最大值 I 该题的数据范围小,直接遍历: class Solution {public long maximumTripletValue(int[] nums) {int n nums.length;long ans 0;for(int i0; i<n-2; i){for(int ji1; j<n-1; j){for(int kj1; k<…...
为什么mac上有的软件删除不掉?
对于Mac用户来说,软件卸载通常是一个相对简单的过程。然而,有时你可能会发现某些软件似乎“顽固不化”,即使按照常规方式尝试卸载,也依然存在于你的电脑上。这到底是为什么呢?本文将探讨这一问题的可能原因。 1.卸载失…...
【vue3】wacth监听,监听ref定义的数据,监听reactive定义的数据,详解踩坑点
假期第二篇,对于基础的知识点,我感觉自己还是很薄弱的。 趁着假期,再去复习一遍 之前已经记录了一篇【vue3基础知识点-computed和watch】 今天在学习的过程中发现,之前记录的这一篇果然是很基础的,很多东西都讲的不够…...
跨境电商如何通过软文建立品牌形象?
在全球产业链结构重塑后的今天,越来越多的企业意识到想要可持续发展,就需要在建立品牌形象,在用户心中留下深刻印象,那么应该如何有效建立品牌形象呢?可以利用软文来打造品牌形象,接下来媒介盒子就告诉大家…...
我做了一个简易P图(参数图)分析软件
P图(即参数图,Parameter Diagram),是一个结构化的工具,帮助大家对产品更好地进行分析。 典型P图格式 P图最好是和FMEA软件联动起来,如国可工软的FMEA软件有P图分析这个功能。 单纯的P图分析软件很少,为了方便做P图分…...
209.Flink(四):状态,按键分区,算子状态,状态后端。容错机制,检查点,保存点。状态一致性。flink与kafka整合
一、状态 1.概述 算子任务可以分为有状态、无状态两种。 无状态:filter,map这种,每次都是独立事件有状态:sum这种,每次处理数据需要额外一个状态值来辅助。这个额外的值就叫“状态”2.状态的分类 (1)托管状态(Managed State)和原始状态(Raw State) 托管状态就是由…...
rabbitmq查看节点信息命令失败
不影响访问rabbitmq,但是无法使用 命令查看节点信息 等 查看节点信息命令:rabbitmq-diagnostics status --node rabbitJHComputer Error: unable to perform an operation on node ‘rabbitJHComputer‘. Please see diagnostics informatio rabbitmq-…...
c语言动态内存分布
前言: 随着我们深入的学习c语言,之前使用的静态内存分配已经难以满足我们的实际需求。比如前面我们的通讯录功能的实现,如果只是静态内存分配,那么也就意味着程序开始的内存分配大小就是固定的,应该开多大的空间呢&am…...
1.3.2有理数减法(第一课时)作业设计
【学习目标】 1.理解有理数减法法则,能熟练地进行有理数的减法运算. 2.感受有理数减法与加法对立统一的辨证思想,体会转化的思想方法....
vue3 -- ts封装 Turf.js地图常用方法
Turf.js中文网 地理空间分析库,处理各种地图算法 文档地址 安装 Turf 库 npm install @turf/turf创建src/hooks/useTurf.ts 文件1:获取线中心点 效果: 代码: useTurf.ts import * as turf from @turf/turf// 获取线中心点 export class CenterPointOfLine {...
Qt之实现圆形进度条
在Qt自带的控件中,只有垂直进度条、水平进度条两种。 在平时做页面开发时,有些时候会用到圆形进度条,比如说:下载某个文件的下载进度。 展示效果,如下图所示: 实现这个功能主要由以下几个重点:…...
C# 图解教程 第5版 —— 第1章 C# 和 .NET 框架
文章目录 1.1 在 .NET 之前1.2 .NET 时代1.2.1 .NET 框架的组成1.2.2 大大改进的编程环境 1.3 编译成 CIL1.4 编译成本机代码并执行1.5 CLR1.6 CLI1.7 各种缩写1.8 C# 的演化1.9 C# 和 Windows 的演化(*) 1.1 在 .NET 之前 MFC(Microsoft Fou…...
electronjs入门-聊天应用程序,与Electron.js通信
随着第一章中构建的应用程序,我们将开始将其与Electron框架中的模块集成,并以此为基础,以更实用的方式了解它们。 过程之间的通信 根据第二章中的解释,我们将发送每个进程之间的消息;具体来说联系人和聊天࿱…...
【自用】ubuntu 18.04 LTS安装opencv 3.4.16 + opencv_contrib 3.4.16
1.下载 opencv 3.4.16 opencv_contrib 3.4.16 其中,opencv_contrib解压后的多个文件夹复制到opencv内、合并 声明:尚未验证该方式是否可行 2.安装 参考博文: https://zhuanlan.zhihu.com/p/650792342 https://zhuanlan.zhihu.com/p/8719780…...
递归解析Json,实现生成可视化Tree+快速获取JsonPath | 京东云技术团队
内部平台的一个小功能点的实现过程,分享给大家: 递归解析Json,可以实现生成可视化Tree快速获取JsonPath。 步骤: 1.利用JsonPath读取根,获取JsonObject 2.递归层次遍历JsonObjec,保存结点信息 3.利用z…...
GraceUI相关的 知识
调试工具:UniApp提供了一些调试工具和插件,如uni-app-cli、调试器等,可以帮助你更好地定位和解决问题。同时,使用浏览器的开发者工具或模拟器的调试功能,可以更直观地观察页面效果和调试代码。 对于 GraceUI 的普通版本…...
三十二、【进阶】hash索引结构
1、hash索引结构 (1)简述: hash索引,就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。 (2)图示: 2、hash索引结构…...
扁平化设计网站建设/厦门seo专业培训学校
提到直播大多数人首先想到的可能是各种直播平台,比如花椒斗鱼虎牙YY ,这些直播平台中按照主播风格的不同,又可以分为美女直播、游戏直播、教育直播或者财经直播。除了开始的美女、才艺直播外,其他是直播和细分行业的结合。那么提到…...
万网域名怎么绑定网站/郑州seo网站管理
首先是springboot对数据的处理,前端使用vue进行数据的导出 依赖的导入 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency>RequestMapping("…...
政府网站建设的问题/全网最好的推广平台
卷积计算和池化计算公式 卷积 卷积计算中,()表示向下取整。 输入:n* c0* w0* h0 输出:n* c1* w1* h1 其中,c1就是参数中的num_output,生成的特征图个数。 w1(w02pad-kernel_s…...
怎么做网站和艺龙对接/58同城黄页推广
本文作者:CODING 用户 - 廖石荣 持续集成的概念 持续集成(Continuous integration,简称 CI)是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每…...
英文 科技网站/免费百度下载
路线:xx.pth -> xx.onnx -> xx.trt 实验版本:torch 1.10.0;tensorrt 7.2.3.4; onnx 1.8.1 1. pth2onnx.py # 将pytorch训练的模型xx.pth转为xx.onnx。 import torch from model import resnet50 # 导入模型结构 impo…...
哪里有做网站企业/网店推广的方式
返回:贺老师课程教学链接 画出实现下面求解任务的流程图 1、简单循环的流程图(提示:m是一个变量,在程序中输入)(1)求1到m的倒数和,即 (2)求1到m的平方和&…...