【iOS】设计模式的六大原则
【iOS】设计模式的六大原则
文章目录
- 【iOS】设计模式的六大原则
- 前言
- 开闭原则——OCP
- 单一职能原则——SRP
- 里氏替换原则——LSP
- 依赖倒置原则——DLP
- 接口隔离原则——ISP
- 迪米特法则——LoD
- 小结
前言
笔者这段时间看了一下有关于设计模式的七大原则,下面代码示例均为OC。
开闭原则——OCP
这原则要求很简单:
- 该原则要求软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
开闭原则的思想是:当新的需求出现时,应该尽可能地通过增加新的代码来满足这些需求,而不是直接修改现有代码。
正如iOS开发中的分类的思想一样。
下面给出一个例子:
//下面是一个有关于Car的例子
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Car : NSObject
@property (nonatomic, strong) NSString* brand;
@endNS_ASSUME_NONNULL_END#import "Car.h"@implementation Car
- (void) startEngine { // 一个汽车启动的业务NSLog(@"the car go to ran");
}
@end
根据我们这个原则的思想来说的话,我们如果想添加一个新的功能,比方说自动泊车,我们应该是添加一个方法,而不是在原先的方法上进行一个修改:
错误案例:
//下面是一个有关于Car的例子
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Car : NSObject
@property (nonatomic, strong) NSString* brand;
@endNS_ASSUME_NONNULL_END#import "Car.h"@implementation Car
- (void) startEngine { // 一个汽车启动的业务NSLog(@"the car go to ran");//添加自动泊车NSLog(@"the car begin to park automatically");
}
@end
这样很显然不符合我们的开闭原则,下面是一个正确的案例:
#import "Car.h"NS_ASSUME_NONNULL_BEGIN
//这里创建一个抽象类来实现,这个抽象类表示所有的一个汽车装饰器
@interface CarDecorator : Car
@property (nonatomic, strong) Car* car;
-(instancetype)initWithCar:(Car*)car;
@endNS_ASSUME_NONNULL_END#import "CarDecorator.h"
//这里是这个抽象类的一个具体实现
@implementation CarDecorator
- (instancetype)initWithCar:(Car *)car {if ([super init]) {self.car = car;}return self;
}
- (void)startEngine {[self.car startEngine];
}
@end
//下面是一个具体某一类别的实现:
#import "CarDecorator.h"NS_ASSUME_NONNULL_BEGIN@interface ElectricCarDecorator : CarDecorator
-(void)autoParking;
@endNS_ASSUME_NONNULL_END
#import "ElectricCarDecorator.h"@implementation ElectricCarDecorator
-(void)autoParking { // 创建一个新的方法用于实现我们的一个自动泊车NSLog(@"Auto Parking");
}
- (void)startEngine { //在这里重写父类的方法,让这个方法在实现我们想要的自动泊车功[super startEngine];[self autoParking];
}
@end
这上面的我们创建了一个新的抽象类来执行他新的一个方法,然后在子类中重写有关于父类的一个方法,既保证了代码不会被修改的同时,实现了一个新的功能,这就体现出了我们的一个开闭原则。
单一职能原则——SRP
该原则要求:
- 不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,否则就应该把类拆分.
要点:
- 一个类只负责一个职能,类的设计应该避免包含过多的一个功能
- 高内聚,低耦合
- 避免滥用接口
下面是一个错误的示例:
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Employee : NSObject // 这是一个工人的基本信息的内容
@property (nonatomic, strong) NSString* name;
@property (nonatomic, assign) NSInteger age;
-(void)calculateSalary:(Employee*)employee; // 计算了工人的薪资
@endNS_ASSUME_NONNULL_END#import "Employee.h"@implementation Employee
-(void)calculateSalary:(Employee *)employee {NSLog(@"calcurlatSalry: name: %@, age : %ld", employee.name, employee.age);
}
@end
这个案例我们可以看出我们这里出现了这个类包含了多个职能,这很显然不符合我们的单一职能原则,我们这个工人的类别就应该仅仅包含一个工人的一个基本信息,而不应该涉及计算薪资的一个内容。
这里我们给出一个正确的例子:
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Employee : NSObject
@property (nonatomic, strong) NSString* name;
@property (nonatomic, assign) NSInteger age;
@endNS_ASSUME_NONNULL_END#import <Foundation/Foundation.h>
@class Employee;
NS_ASSUME_NONNULL_BEGIN@interface SalaryCaculator : NSObject
-(void)calculateSalary:(Employee*)employee;
@endNS_ASSUME_NONNULL_END
#import "SalaryCaculator.h"
#import "Employee.h"
@implementation SalaryCaculator
-(void)calculateSalary:(Employee *)employee {NSLog(@"calcurlatSalry: name: %@, age : %ld", employee.name, employee.age);
}
@end
在这个案例中我们把两个内容分开了,创建了一个新的类来负责他对应的一个工作,从而保证了一个类只负责一个职能,符合我们的一个单一职能原则。
遵循单一职责原则是一个重要的设计原则,可以帮助我们写出更加模块化、可维护和可扩展的代码。
里氏替换原则——LSP
该原则要求:
子类对象可以替换父类对象出现在程序中,而不影响程序的正确性。
这里可能比较难以理解这项原则的一个作用,这里笔者借用学长的一段话来看一下:
- 里氏替换原则是实现开放封闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。【设计模式】六大原则详解,每个原则提供代码示例
这里我们可以看出这项原则一个核心是为来保证类的一个扩展是不会给已经存在的系统引入新的错误,防止我们采用多态的时候出现一个代码上的问题。
下面给出一个经典的长方形不是正方形的一个例子:
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@protocol Shape <NSObject>
- (NSInteger)calculateArea; //定义一个协议方法,也就是一个公共的接口
@endNS_ASSUME_NONNULL_END#import <Foundation/Foundation.h>
#import "Shape.h"
NS_ASSUME_NONNULL_BEGIN@interface Squre : NSObject<Shape> //实现一个正方形类来实现对应的接口的内容
@property (nonatomic, assign) NSInteger length;
@endNS_ASSUME_NONNULL_END#import "Squre.h"@implementation Squre
- (NSInteger)calculateArea {return self.length * self.length;
}
@end#import "Shape.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN@interface Rectangle : NSObject<Shape> //实现长方形类来实现对应接口的内容
@property (nonatomic, assign) NSInteger width;
@property (nonatomic, assign) NSInteger height;
@endNS_ASSUME_NONNULL_END#import "Rectangle.h"@implementation Rectangle
- (NSInteger)calculateArea {return self.width * self.height;
}
@end
这里我们把长方形和正方形分成两个不同的类别遵循不同的协议,这样才不会出现里氏替换原则中将正方形替换成长方形,然后设置长宽出现与预期的结果实际不符的一个情况。
依赖倒置原则——DLP
该原则要求:
- 高层模块不应该依赖低层模块,二者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象
在OC中我认为抽象类是协议,细节是一个类的实现方法,高层模块就是调用端,底层模块就是实现端。
也就是说,模块间依赖是通过抽象发生;实现类之间没有依赖关系,所有的依赖关系通过接口/抽象类产生。【设计模式】六大原则详解,每个原则提供代码示例
下面给出我认为的依赖倒置原则的实现:
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@protocol LoggerProtocol <NSObject> // 一个抽象的接口
-(void) log:(NSString*)message;
@endNS_ASSUME_NONNULL_END#import <Foundation/Foundation.h>
#import "LoggerProtocol.h"
NS_ASSUME_NONNULL_BEGIN@interface Logger : NSObject<LoggerProtocol> //这里是我们的一个具体的底层实现端
@endNS_ASSUME_NONNULL_END#import "Logger.h"@implementation Logger
- (void)log:(NSString*)message { // 底层实现一个抽象NSLog(@"1234 %@", message);
}
@end#import <Foundation/Foundation.h>
#import "Logger.h"
NS_ASSUME_NONNULL_BEGIN@interface MyClass : NSObject // 这里是我们的高层调用端
@property (nonatomic, strong) id<LoggerProtocol> logger; //高层调用这个接口
@endNS_ASSUME_NONNULL_END//使用的时候我们通过下面的方法来实现:
// MyClass.logger = [[Logger alloc] init];在这里进行一个依赖注入
// [MyClass.logger log:@"123"];
接口隔离原则——ISP
该原则要求:
- 一个类不应该强迫其它类依赖它们不需要使用的方法,也就是说,一个类对另一个类的依赖应该建立在最小的接口上
也就说:一个类应该只提供其它类需要使用的方法,而不应该强迫其它类依赖于它们不需要使用的方法
这里我们举一个例子:假设我们设计一个多功能设备,里面可能包含了打印机和扫描仪,但是一般的设备可能不具备对应的一个扫描的一个功能,但是如果这个类遵循这个协议就会导致对应的一个问题,实现了一个他不具备的一个功能。
下面只介绍正确的案例的样式,设置小而专的接口
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@protocol Printable <NSObject> //设置打印的接口
- (void) printDoucment;
@endNS_ASSUME_NONNULL_END#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@protocol Scanabel <NSObject> //设置扫描的接口
-(void) scanDoucment;
@endNS_ASSUME_NONNULL_END#import <Foundation/Foundation.h>
#import "Printable.h"
NS_ASSUME_NONNULL_BEGIN@interface Printer : NSObject <Printable> //普通打印机的一个实现,如果是多功能则多遵循一个协议就可以了,@endNS_ASSUME_NONNULL_END#import "Printer.h"@implementation Printer
-(void)printDoucment {NSLog(!"common Printer");
}
@end
其核心思想在以下的内容:
如果一个接口过于臃肿,就需要将其拆分成多个小的接口,使得每个接口中只包含必要的方法。这样的好处是:
- 接口更加具有内聚性:每个接口只需要关注自己的功能,而不需要关注其他接口中的方法,因此能够使接口更加专注和具有内聚性。
- 接口之间的耦合度更低:每个接口只依赖于必要的方法,而不依赖于其他不必要的方法,因此能够使接口之间的耦合度更低。
- 代码的复用性更高:每个接口只包含必要的方法,因此能够使得代码的复用性更高,也能够提高代码的可读性和可维护性。24种设计模式代码实例学习(一)七大设计原则
迪米特法则——LoD
该原则要求:
- 一个类对自己依赖的类知道的越少越好。无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过
public
方法提供给外部。
最少知道原则的另一个表达方式是:只与直接的朋友通信。
类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。
这里我们以购物车为例子:一个人去超市买东西主要分成三个部分,一个是我们的用户,一个是购物车,一个是商品,这里面我们如果要符合这个设计原则的话,这里的人应该和购物车进行交互,然后购物车和商品进行一个交互,这样符合我们的迪米特法则。
下面给出一段代码示例:
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Product : NSObject // 这个是商品
@property (nonatomic, assign) CGFloat price;
@property (nonatomic, strong) NSString* name;
@endNS_ASSUME_NONNULL_END#import <Foundation/Foundation.h>
@class Product;
NS_ASSUME_NONNULL_BEGIN@interface ShopCart : NSObject // 这个是购物车
@property (nonatomic, strong) NSMutableArray<Product*>* products;
-(void) addProduct:(Product*)product;
@endNS_ASSUME_NONNULL_END#import "ShopCart.h"@implementation ShopCart //与商品发生直接关系
- (void)addProduct:(Product *)product {[self.products addObject:product];
}
@end#import <Foundation/Foundation.h>
@class ShopCart;
@class Product;
NS_ASSUME_NONNULL_BEGIN@interface User : NSObject //用户
@property (nonatomic, strong) ShopCart* shopCart;
-(void)addToCart:(Product*)product;
@endNS_ASSUME_NONNULL_END#import "User.h"
#import "ShopCart.h"
@implementation User
- (void)addToCart:(Product *)product {[self.shopCart addProduct:product]; // 与购物车发生直接关系
}
@end
在上面的代码示例中,每个类都只和自己直接的朋友进行通信,遵循了最少知道原则。
小结
这里笔者简单介绍了一下六大设计模式的一个内容,笔者对这部分内容也是初次接触,如有纰漏或者还请不吝赐教,笔者会及时改正。
参考博客:
【设计模式】六大原则详解,每个原则提供代码示例
24种设计模式代码实例学习(一)七大设计原则
相关文章:
【iOS】设计模式的六大原则
【iOS】设计模式的六大原则 文章目录 【iOS】设计模式的六大原则前言开闭原则——OCP单一职能原则——SRP里氏替换原则——LSP依赖倒置原则——DLP接口隔离原则——ISP迪米特法则——LoD小结 前言 笔者这段时间看了一下有关于设计模式的七大原则,下面代码示例均为OC…...
网络安全:攻防技术-Google Hacking的实现及应用
前言 google hacking其实并算不上什么新东西,在早几年我在一些国外站点上就看见过相关的介绍,但是由于当时并没有重视这种技术,认为最多就只是用来找找未改名的mdb或者别人留下的webshell什么的,并无太大实际用途。但是前段时间仔…...
输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。-多语言
目录 C 语言实现 Python 实现 Java 实现 Js 实现 Ts 实现 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。 程序分析:利用while语句,条件为输入的字符不为\n。 C 语言实现 #include <stdio.h>int mai…...
2-2-18-9 QNX系统架构之文件系统(三)
阅读前言 本文以QNX系统官方的文档英文原版资料为参考,翻译和逐句校对后,对QNX操作系统的相关概念进行了深度整理,旨在帮助想要了解QNX的读者及开发者可以快速阅读,而不必查看晦涩难懂的英文原文,这些文章将会作为一个…...
各大浏览器(如Chrome、Firefox、Edge、Safari)的对比
浏览器如Chrome、Firefox、Edge等在功能、性能、隐私保护等方面各有特点。以下是对这些浏览器的详细对比,帮助你选择合适的浏览器。 1. Google Chrome 市场份额:Chrome是目前市场上最流行的浏览器,约占全球浏览器市场的65%以上。 性能&#…...
nginx搭建直播推流服务
文章目录 学习链接步骤使用nginx搭建直播推流服务安装依赖库下载nginx-http-flv-module模块下载nginx解压nginx,进入nginx目录设置nginx编译配置编译并安装配置nginx rtmp服务启动nginx 准备另外一台电脑下载OBS下载OBS windows | linux 安装vlc观看直播flv协议hls协…...
单片机-- 松瀚sonix学习过程
硬件:松瀚sn8f5701sg、SN-LINK 3 Adapter模拟器、sn-link转接板 软件: keil-c51(v9.60):建立工程,编辑,烧录程序 SN-Link_Driver for Keil C51_V3.00.005:安装sonix设备包和snlin…...
循环神经网络:从基础到应用的深度解析
🍛循环神经网络(RNN)概述 循环神经网络(Recurrent Neural Network, RNN)是一种能够处理时序数据或序列数据的深度学习模型。不同于传统的前馈神经网络,RNN具有内存单元,能够捕捉序列中前后信息…...
从扩散模型开始的生成模型范式演变--SDE
SDE是在分数生成模型的基础上,将加噪过程扩展时连续、无限状态,使得扩散模型的正向、逆向过程通过SDE表示。在前文讲解DDPM后,本文主要讲解SDE扩散模型原理。本文内容主要来自B站Up主deep_thoughts分享视频Score Diffusion Model分数扩散模型…...
【python使用kazoo连ZooKeeper基础使用】
from kazoo.client import KazooClient, KazooState from kazoo.exceptions import NoNodeError,NodeExistsError,NotEmptyError import json# 创建 KazooClient 实例,连接到 ZooKeeper 服务器 zk KazooClient(hosts127.0.0.1:2181) zk.start()# 定义节点路径 path…...
【设计模式系列】解释器模式(十七)
一、什么是解释器模式 解释器模式(Interpreter Pattern)是一种行为型设计模式,它的核心思想是分离实现与解释执行。它用于定义语言的文法规则,并解释执行语言中的表达式。这种模式通常是将每个表达式抽象成一个类,并通…...
只出现一次的数字
只出现一次的数字 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。 示例 1 ÿ…...
SpringMVC-08-json
8. Json 8.1. 什么是Json JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写…...
技术文档的语言表达
技术文档的语言表达 在这个瞬息万变的技术世界中,了解如何撰写有效的技术文档显得尤为重要。无论是开发团队还是最终用户,清晰、简洁且有条理的文档都是连接各方的桥梁。本文将深入探讨技术文档的语言表达,从其重要性、写作原则到各种类型&a…...
UEFI 事件
UEFI 不再支持中断(准确地说,UEFI 不再为开发者提供中断支持,但在UEFI内部还是使用了时钟中断),所有的异步操作都要通过事件(Event)来完成。 启动服务为开发者提供了用于操作事件、定时器及TPL…...
大师开讲-图形学领域顶级专家王锐开讲Vulkan、VSG开源引擎
王锐,毕业于清华大学,图形学领域顶级专家,开源技术社区的贡献者与推广者。三维引擎OpenSceneGraph的核心基石开发者与维护者,倾斜摄影数据格式osgb的发明人。著有《OpenSceneGraph 3 Cookbook》,《OpenSceneGraph 3 Beginers Guid…...
小F的矩阵值调整
问题描述 小F得到了一个矩阵。如果矩阵中某一个格子的值是偶数,则该值变为它的三倍;如果是奇数,则保持不变。小F想知道调整后的矩阵是什么样子的。 测试样例 样例1: 输入:a [[1, 2, 3], [4, 5, 6]] 输出:…...
ORB-SLAM2 ----- LocalMapping::SearchInNeighbors()
文章目录 一、函数意义二、函数讲解三、函数代码四、本函数使用的匹配方法ORBmatcher::Fuse()1. 函数讲解2. 函数代码 四、总结 一、函数意义 本函数是用于地图点融合的函数,前面的函数生成了新的地图点,但这些地图点可能在前面的关键帧中已经生成过了&a…...
给UE5优化一丢丢编辑器性能
背后的原理 先看FActorIterator的定义 /*** Actor iterator* Note that when Playing In Editor, this will find actors only in CurrentWorld*/ class FActorIterator : public TActorIteratorBase<FActorIterator> {//..... }找到基类TActorIteratorBase /*** Temp…...
【Docker】常用命令汇总
Docker 是1个开源的应用容器引擎,基于Go 语言并遵从 Apache2.0 协议开源。 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相…...
Mybatis:CRUD数据操作之多条件查询及动态SQL
Mybatis基础环境准备请看:Mybatis基础环境准备 本篇讲解Mybati数据CRUD数据操作之多条件查询 1,编写接口方法 在 com.itheima.mapper 包写创建名为 BrandMapper 的接口。在 BrandMapper 接口中定义多条件查询的方法。 而该功能有三个参数,…...
【笔记】轻型民用无人驾驶航空器安全操控
《轻型民用无人驾驶航空器安全操控》 理论考试培训材料 法规部分 【民用无人驾驶航空器的分类】 1、如何定义微型、轻型无人驾驶航空器? 微型无人驾驶航空器,是指空机重量小于0.25千克,最大平飞速度不超过40千米/小时,无线电发…...
TouchGFX设计模式代码实例说明
一)Model - View - Presenter (MVP) 模式在 TouchGFX 中的应用 1)Model(模型): 模型代表应用程序的数据和业务逻辑。例如,在一个简单的计数器应用中,模型可以是一个包含计数器当前值的类。 class CounterModel { pri…...
flink学习(7)——window
概述 窗口的长度(大小): 决定了要计算最近多长时间的数据 窗口的间隔: 决定了每隔多久计算一次 举例:每隔10min,计算最近24h的热搜词,24小时是长度,每隔10分钟是间隔。 窗口的分类 1、根据window前是否调用keyBy分为键控窗口和非键控窗口…...
restTemplate get请求
报错解释: 这个报错信息表明在使用RestTemplate进行GET请求时,需要提供一个请求类型(reqType),但是传入的值为空。这通常意味着在构建请求或者调用方法时,没有正确设置请求的Content-Type头部,…...
ffmpeg 预设的值 加速
centos 安装ffmpeg 编译安装 官网获取最新的linux ffmpeg 代码 https://ffmpeg.org//releases/ mkdir -p /data/app/ffmpeg cd /data/app/ffmpeg wget http://www.ffmpeg.org/releases/ffmpeg-7.1.tar.gz tar -zxvf ffmpeg-7.1.tar.gz#安装所需的编译环境 yum install -y \…...
maven <scope>compile</scope>作用
在 Maven 项目中, 元素用于定义依赖项的作用范围。 元素可以有多个值,每个值表示不同的作用范围。其中,scope compile scope 是默认的作用范围,表示该依赖项在编译、测试和运行时都需要。 scope compile scope 的含义 1、编译时…...
Ubuntu Server 22.04.5 从零到一:详尽安装部署指南
文章目录 Ubuntu Server 22.04.5 从零到一:详尽安装部署指南一、部署环境二、安装系统2.1 安装2.1.1 选择安装方式2.1.2 选择语言2.1.3 选择不更新2.1.4 选择键盘标准2.1.5 选择安装版本2.1.6 设置网卡2.1.7 配置代理2.1.8 设置镜像源2.1.9 选择装系统的硬盘2.1.10 …...
反射机制了解
反射概念 了解反射背景 存在某些变量或形参的声明类型是Object类型,但是程序却需要调用该对象运行时类型的方法,该方法不是Object中的方法,如何解决。转到如何获取该对象运行时类型的方法。 只能运行时才能获取,这就用到反射。 …...
机器学习策略Ⅰ
机器学习策略Ⅰ 在构建一个好的监督学习系统时,通常需要确保以下四个方面: 系统需要在训练集上能够很好地拟合数据,达到某种可接受的性能水平(如接近人类水平)。如果训练集表现不好,可以使用更大的模型&…...
资讯类网站怎么做/谷歌seo搜索引擎
数据库设计说明书 1引言 1.1编写目的 本文档描述了机房收费系统数据库的设计,提供了数据库设计的可视性以及软件支持所需的信息,应用于机房收费系统开发前期,为后期的数据库设计指引方向,也可以为系统程序设计提供借鉴与参照。预…...
典型b2c模式的网站/怎样做品牌推广
硬盘分区不是自己想要的?分区容量不够需要扩容?电脑硬盘已经分好区,需要调整分区大小怎么办?下载分区助手专业版易我分区大师专业版软件,帮助管理磁盘分区,调整磁盘布局。 官网详情访问: https://www.ease…...
内贸在什么网站做/石家庄限号
支付宝沙箱环境支付demo 下载电脑网站的官方demo: 下载地址:https://docs.open.alipay.com/270/106291/ 解压导入demo项目 3.配置AlipayConfig 3.1 注册蚂蚁金服开发者账号 注册地址:https://open.alipay.com/platform/home.htm ÿ…...
网站建设与运营考试/百度url提交
Flask > 目录结构 一:目标 1.要求: 1. 熟悉Flask的目录结构。 2. 了解应用,装上新的组件往里面放,改怎么弄? 2.作业: 1.基于flask实现权限管理 2.笔记: - flask的请求周期 二:…...
佛山搭建建网站哪家好/seo关键词优化排名软件
欢迎来到梁钟霖个人博客网站。本个人博客网站提供最新的站长新闻,各种互联网资讯。 还提供个人博客模板,最新最全的java教程,java面试题。在此我将尽我最大所能将此个人博客网站做的最好! 谢谢大家,愿大家一起进步! 背景 既然我们已经使用springbootdubbo 那么也不放继续深…...
网站默认首页/网络广告策划书范文
volatile关键字区分C程序员和嵌入式系统程序员的最基本的问题:嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所有这些都要求使用volatile变量。不懂得volatile内容将会带来灾难。 volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而…...