【iOS】——工厂设计模式

文章目录

  • 一、设计模式
    • 创建型模式
    • 结构型模式
    • 行为型模式
  • 二、设计模式七大准则
  • 三、简单工厂模式
  • 四、工厂方法模式
  • 五、抽象工厂模式


一、设计模式

设计模式是指在特定上下文中解决常见问题时所采用的一套可复用的解决方案。这些模式是面向对象编程中的通用概念,广泛应用于各种编程语言和平台。设计模式能够帮助开发者编写更加高效、可读性强、易于维护的代码。它们通常分为三大类:创建型模式、结构型模式和行为型模式工厂模式属于创建型模式,这类模式关注于对象的创建过程,提供了创建对象的不同方式,以降低耦合度并提高代码的灵活性。

创建型模式

这类模式关注于对象的创建过程,提供了创建对象的不同方式,以降低耦合度并提高代码的灵活性。

  • 单例模式:确保一个类只有一个实例,并提供一个全局访问点
  • 工厂模式:提供一个创建对象的接口,但让子类决定实例化哪一个类。
  • 抽象工厂模式:为创建一系列相关或相互依赖的对象提供一个接口,而无需指定它们具体的类。
  • 建造者模式:分步骤构建复杂对象,用户只需指定类型和内容,不需知道内部构造细节。
  • 原型模式:通过克隆已有对象来创建新对象,减少创建成本。

结构型模式

这类模式关注于如何组合类和对象以获得更大的结构,同时保持结构的灵活和高效。

  • 适配器模式:将一个类的接口转换成客户期望的另一个接口。
  • 桥接模式:将抽象部分与实现部分分离,使它们可以独立变化。
  • 装饰模式:动态地给一个对象添加一些额外的职责,而不改变其结构。
  • 组合模式:将对象组合成树形结构以表示“整体-部分”层次结构。
  • 外观模式:为一组复杂的子系统提供一个统一的接口,以简化高层模块的使用。

行为型模式

这类模式关注于对象间的通信,以及职责的分配。

  • 责任链模式:将请求沿着链传递,直到有对象处理它。
  • 命令模式:将请求封装成对象,以便使用不同的请求、队列请求、日志请求等。
  • 迭代器模式:提供一种方法顺序访问聚合对象的元素,而又不暴露其内部表示。
  • 观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
  • 策略模式:定义一系列算法,将它们一个个封装起来,并使它们可以相互替换。
  • 模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中实现。
  • 访问者模式:在不改变数据结构的前提下,增加作用于这些元素的新操作。

二、设计模式七大准则

  • 单一职责原则

每个类或者模块应该有且只有一个改变的理由。也就是说,一个类应当专注于做好一件事情,这样可以提高类的内聚性,减少耦合。
比如:UIView负责事件的传递、响应,CALayer负责视图的显示、动画,他们各自都有自己的单一职责。

  • 开放封闭原则

软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当需要改变行为时,应该通过扩展而不是修改已有的代码来实现。

  • 里氏替换原则
    子类应当能够替换它们的基类并且不影响程序的正确性。换言之,使用基类的地方能够无差别地使用子类对象。

  • 依赖倒置原则
    高层模块不应依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

  • 接口隔离原则
    客户端不应该被迫依赖它不需要的接口。接口应该尽量细化,避免臃肿的接口定义,客户端只依赖它实际需要的方法。

  • 迪米特法则/ 最小知识原则
    一个对象应当对其他对象有最少的了解。一个类应该只和它的朋友通信,不要和朋友的朋友通信,以减少耦合。

  • 合成/聚合复用原则
    尽量使用对象组合而非类继承来达到复用的目的。组合使得系统更加灵活,容易扩展和维护。
    合成
    合成是指一个总体对依托他而存在的关系,如一个人对他的房子和家具。该关系依赖性不强,比如人没了,这个关系就自然消失了。
    聚合
    聚合是比合成关系更强的一种依赖关系,如有一台汽车,汽车对引擎、轮胎的关系就是聚合关系。这些关系就是带有聚合性质的。车没了,该车的引擎和轮胎自然也没了。在我们的设计中,这种关系不应该频繁出现,因为这样会增大设计的耦合度。

明确了合成和聚合关系,再来理解合成复用原则应该就清楚了:我们要尽量找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

三、简单工厂模式

简单工厂模式(Simple Factory Pattern)是一种常用的设计模式,它属于创建型模式的一种。这种模式旨在为创建对象提供一个统一的接口,隐藏了创建对象的具体逻辑,使得客户端不需要知道所创建对象的具体类,从而降低了对象之间的耦合度,提高了代码的灵活性和可维护性。

专门定义一个类(工厂类)来负责创建其他类的实例。可以根据创建方法的参数来返回不同类的实例,被创建的实例通常具有共同的父类。(总结来说就是把一大堆if-else判断由业务层放到工厂类里面)。


优点

  • 根据约定好的参数就可以获取所需要的对象,而不需要知道其创建的细节。减少了系统的耦合度。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,减少开发者的记忆成本。

缺点

  • 如果业务上添加新产品的话,就需要修改工厂类原有的判断逻辑,这其实是违背了开闭原则的。
  • 在产品类型较多时,有可能造成工厂逻辑过于复杂。所以简单工厂模式比较适合产品种类比较少而且增多的概率很低的情况。

主要作用

通过引入工厂类,使对象的创建和使用分离了。这样的好处是它们可以独立的变化,易维护和扩展。
客户端依赖抽象基类(接口),而不是具体的类,降低了耦合度。

  • 有一组相似的对象,需要集中统一创建时。
  • 创建对象的过程较为复杂时。
  • 对象很多,并且有扩展需求时。
  • 客户端不需要知道创建对象的过程时。
  • 客户端使用的对象存在变动的可能,或者根本不知道使用哪一个具体对象时。

文件分类
在这里插入图片描述

通过传递进来的字符串来确定生成的类:

//CYZActionFactory.h
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface CYZActionFactory : NSObject
+(id)createAction:(NSString*)actionType;
@endNS_ASSUME_NONNULL_END//CYZActionFactory.m
#import "CYZActionFactory.h"
#import "CYZWork.h"
#import "CYZPlay.h"
#import "CYZStudy.h"
@implementation CYZActionFactory+(id)createAction:(NSString *)actionType {if ([actionType isEqualToString:@"work"]) {return [[CYZWork alloc] init];} else if([actionType isEqualToString:@"play"]) {return [[CYZPlay alloc] init];} else {return [[CYZStudy alloc] init];;}
}
@end

其中通过工厂类返回的各种类(各种行为)必须遵守以下协议:

@protocol AcitonFactoryDelegate <NSObject>
- (void)actionSelect;
@end

在各类中实现此方法:

//  CYZWork.m
#import "CYZWork.h"@implementation CYZWork
- (void)actionSelect {[self work];
}
- (void)work {NSLog(@"I love work!");
}
@end

运行结果如下:
在这里插入图片描述

简单工厂方法和类族模式主要区别就是,类族模式实现各子类方法通过继承去重写父类方法,而简单工厂方法中生成的各类和工厂类并不是父子类关系,通过协议来完成各方法。

四、工厂方法模式

工厂方法模式(Factory Method Pattern)是iOS开发中一种常用的设计模式,属于创建型模式的一种。它为创建对象提供了一种灵活的方式,让子类来决定实例化哪一个类,从而实现了对象创建的延迟化和抽象化,增强了代码的扩展性和可维护性。

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到了子类。就像Cocoa Touch中的NSNumber的numberWithBool和numberWithInt方法,他们传入不同类型的参数,获得NSNumber实例。

优点

和直接创建具体对象相比,使用工厂方法创建对象算是最佳的做法。
根据所需产品找对应工厂进行生产,不关心产品细节,也不需要知道产品类的类名。
当系统中加入新产品时,不需要修改抽象工厂和抽象产品提供的接口,也无须修改客户端和其他的具体工厂和具体产品,而只要添加一个具体工厂和与其对应的具体产品就可以了,符合了“开-闭”原则。

缺点

当系统中加入新产品时,除了需要提供新的产品类之外,还要提供与其对应的具体工厂类。因此系统中类的个数将成对增加,增加了系统的复杂度。

主要作用:

编译时无法准确预期需要创建对象的类。
类想要其子类决定在运行时创建什么类型的实例。
类有若干辅助类为其子类,而你想将返回哪个子类这种信息局部化。

工厂类中并没有类方法,只有一些方法,简单工厂方法是通过协议的方法去令其他类完成方法,而工厂方法模式是通过继承,令其他类继承工厂类,去重写父类的这几个方法,下面是代码:

文件分类
在这里插入图片描述

工厂类:

//FactoryMethodClass.h
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface FactoryMethodClass : NSObject
- (void)createAction;
@endNS_ASSUME_NONNULL_END//FactoryMethodClass.m
#import "FactoryMethodClass.h"@implementation FactoryMethodClass
- (void)createAction  {NSLog(@"action");
}
@end

子类:

//CYZWork.h
#import <Foundation/Foundation.h>
#import "FactoryMethodClass.h"
NS_ASSUME_NONNULL_BEGIN@interface CYZWork : FactoryMethodClass@endNS_ASSUME_NONNULL_END/CYZWork.m
#import "CYZWork.h"@implementation CYZWork
- (void)createAction {[self createWork];
}
- (void)createWork {NSLog(@"I love work");
}
@end

在viewController中初始化时以父类编译,子类运行

if ([button.titleLabel.text isEqualToString:@"work"]) {FactoryMethodClass* object = [[CYZWork alloc] init];[object createAction];} else if ([button.titleLabel.text isEqualToString:@"play"]) {FactoryMethodClass* object = [[CYZPlay alloc] init];[object createAction];} else {FactoryMethodClass* object = [[CYZStudy alloc] init];[object createAction];}

运行结果如下:
在这里插入图片描述

五、抽象工厂模式

抽象工厂方法(Abstract Factory Method)是设计模式中的一个概念,它属于创建型模式。抽象工厂模式是对简单工厂模式的进一步扩展,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。与简单工厂模式相比,抽象工厂模式可以生成多个产品族,每个族内有一系列相关的产品。

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。抽象工厂模式里每个工厂都会生产多种产品,但不同工厂生产的产品属于不同的系列。抽象工厂模式可以用来解决多产品族的问题。

优点

  • 为创建一系列相关或相互依赖的对象提供了一个统一的接口,使得客户端可以通过相同的接口来获取不同类型的对象,而无需直接实例化具体产品类。
  • 通过抽象化产品创建过程,可以在不同的地方重用相同的工厂接口来创建对象,减少了代码重复,增加了代码的复用率。

缺点

  • 增加新的产品种类困难,它需要修改抽象工厂的接口。
  • 代码结构比较复杂。

主要作用

  • 类想让其子类决定在运行时创建什么,无法在编译时准确确定
  • 类有若干个辅助类为其子类,而你想将返回某个子类这一信息局部化

文件分类
在这里插入图片描述
首先Manager相当于最大的工厂类,通过这个类里的函数来确定是哪个工厂,apple厂还是banana厂:

//FactoryManager.h
#import <Foundation/Foundation.h>
#import "BaseFactory.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, CYFactoryType) {CYApple,CYBanana
};
@interface FactoryManager : NSObject
+ (id)factoryWithType:(CYFactoryType)factoryType;
@endNS_ASSUME_NONNULL_END//FactoryManager.m
#import "FactoryManager.h"
#import "AppleFactory.h"
#import "BananaFactory.h"
@implementation FactoryManager
+ (id)factoryWithType:(CYFactoryType)factoryType {if (factoryType == CYApple) {return [[AppleFactory alloc] init];} else if (factoryType == CYBanana) {return [[BananaFactory alloc] init];;}return nil;
}
@end

接下来到了工厂这步:
首先有一个作为两家工厂的父类,两家工厂继承于此类,并重写此基础类的各方法,以此来展示不同的效果:

父类工厂:

//BaseFactory.h
#import <Foundation/Foundation.h>
#import "BasePhone.h"
#import "BasePad.h"
NS_ASSUME_NONNULL_BEGIN@interface BaseFactory : NSObject
- (BasePhone*)createPhone;
- (BasePad*)createPad;
@endNS_ASSUME_NONNULL_END//BaseFatcory.m
#import "BaseFactory.h"@implementation BaseFactory
- (BasePhone*)createPhone {return nil;
}
- (BasePad*)createPad {return nil;
}
@end

子类工厂:

//AppleFactory.h
#import <Foundation/Foundation.h>
#import "BaseFactory.h"
NS_ASSUME_NONNULL_BEGIN@interface AppleFactory : BaseFactory@endNS_ASSUME_NONNULL_END//AppleFactory.m
#import "AppleFactory.h"
#import "ApplePhone.h"
#import "ApplePad.h"
@implementation AppleFactory
- (BasePhone*)createPhone {return [[ApplePhone alloc] init];
}
- (BasePad*)createPad {return [[ApplePad alloc] init];
}
@end
//BananaFactory.h
#import <Foundation/Foundation.h>
#import "BaseFactory.h"
NS_ASSUME_NONNULL_BEGIN@interface BananaFactory : BaseFactory@endNS_ASSUME_NONNULL_END//BananaFactory.m
#import "BananaFactory.h"
#import "BananaPhone.h"
#import "BananaPad.h"
@implementation BananaFactory
- (BasePhone*)createPhone {return [[BananaPhone alloc] init];
}
- (BasePad*)createPad {return [[BananaPad alloc] init];
}
@end

在下面的一步我们让apple和banana厂分别可以生产手机和平板两种产品,这时候和上一步一样,有一个基础手机类和基础平板类:

基础手机类:

//BasePhone.h
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface BasePhone : NSObject
- (void)phoneCell;
@endNS_ASSUME_NONNULL_END//BasePhone.m
#import "BasePhone.h"@implementation BasePhone
- (void)phoneCell {NSLog(@"This is a Phone");
}
@end

苹果手机类:

//ApplePhone.h
#import <Foundation/Foundation.h>
#import "BasePhone.h"
NS_ASSUME_NONNULL_BEGIN@interface ApplePhone : BasePhone@endNS_ASSUME_NONNULL_END//ApplePhone.m
#import "ApplePhone.h"@implementation ApplePhone
- (void)phoneCell {NSLog(@"This is an applePhone");
}
@end

香蕉手机类:

//BananaPhone.h
#import <Foundation/Foundation.h>
#import "BasePhone.h"
NS_ASSUME_NONNULL_BEGIN@interface BananaPhone : BasePhone@endNS_ASSUME_NONNULL_END//BananaPhone.m
#import "BananaPhone.h"@implementation BananaPhone
- (void)phoneCell {NSLog(@"This is a bananaPhone");
}
@end

平板类和上面相似这里就不再赘述
下面是ViewContrroller类

#import "ViewController.h"
#import "FactoryManager.h"
#import "ApplePhone.h"
#import "AppleFactory.h"
#import "ApplePad.h"
#import "BananaFactory.h"
#import "BananaPhone.h"
#import "BananaPad.h"
@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.BaseFactory *appleFactory = [FactoryManager factoryWithType:CYApple];ApplePhone* applePhone = (ApplePhone*)[appleFactory createPhone];[applePhone phoneCell];ApplePad* applePad = (ApplePad*)[appleFactory createPad];[applePad padCell];NSLog(@"-------------------------------------");BaseFactory *bananaFactory = [FactoryManager factoryWithType:CYBanana];BananaPhone *bananaPhone = (BananaPhone*)[bananaFactory createPhone];[bananaPhone phoneCell];BananaPad* bananaPad = (BananaPad*)[bananaFactory createPad];[bananaPad padCell];}

运行结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装OnlyOffice

工作需要&#xff0c;多人在线编辑同一文档&#xff0c;找了一圈发现onlyoffice满足需求&#xff0c;于是使用docker安装了社区版本。下面记录下安装过程。 Onlyoffice 是什么&#xff1f; Onlyoffice 是一个多端协同的 Office 办公套件&#xff0c;相当于微软的 Office365 全…

【Linux网络编程】传输层中的TCP和UDP(TCP篇)

【Linux网络编程】传输层中的TCP和UDP&#xff08;TCP篇&#xff09; 目录 【Linux网络编程】传输层中的TCP和UDP&#xff08;TCP篇&#xff09;TCP协议TCP协议段格式确认应答&#xff08;ACK&#xff09;机制&#xff08;保证可靠性&#xff09;超时重传机制连接管理机制理解T…

ingress-nginx控制器安装(ingress ImagePullBackOff )

支持的版本&#xff08;查看自己的kubernetes版本替换安装过程中的版本选择合适的版本安装&#xff09; 安装过程&#xff1a; 这里不采用helm的方式&#xff0c;而是采用YAML manifest的方式来安装。 下载ingress-nginx的https://raw.githubusercontent.com/kubernetes/ingr…

多线程事务

一、业务场景 我们在工作中经常会到往数据库里插入大量数据的工作&#xff0c;但是既需要保证数据的一致性&#xff0c;又要保证程序执行的效率。因此需要在多线程中使用事务&#xff0c;这样既可以保证数据的一致性&#xff0c;又能保证程序的执行效率。但是spring自带的Trans…

并发编程笔记7--并发编程基础

1、线程简介 1.1、什么是线程 现代操作系统中运行一个程序&#xff0c;会为他创建一个进程。而每一个进程中又可以创建许多个线程。现代操作系统中线程是最小的调度单元。 两者关系&#xff1a;一个线程只属于一个进程&#xff0c;而一个进程可以拥有多个线程。线程是一个轻量…

CS 下载安装详解

目录 CS简介&#xff1a; CS下载地址&#xff1a; CS的安装&#xff1a; CS简介&#xff1a; CS为目前渗透中常用的一款工具&#xff0c;它的强大在于控制windows木马&#xff0c;CS主要控制windows木马。 CS下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/…

WordPress Country State City Dropdown CF7插件 SQL注入漏洞复现(CVE-2024-3495)

0x01 产品简介 Country State City Dropdown CF7插件是一个功能强大、易于使用的WordPress插件,它为用户在联系表单中提供国家、州/省和城市的三级下拉菜单功能,帮助用户更准确地填写地区信息。同时,插件的团队和支持也非常出色,为用户提供高质量的服务。 0x02 漏洞概述 …

【Pytorch】【MacOS】14.m1芯片使用mps进行深度模型训练

读者要先自行安装python以及anaconda&#xff0c;并且配置pytorch环境 第一步 测试环境 import torch # 判断macOS的版本是否支持 print(torch.backends.mps.is_available()) # 判断mps是否可用 print(torch.backends.mps.is_built())如果第一个语句为False&#xff0c;说明当前…

Python简介

Python简介 1. Python定义 Python 是一种简单易学并且结合了解释性、编译性、互动性和面向对象的脚本语言。Python提供了高级数据结构&#xff0c;它的语法和动态类型以及解释性使它成为广大开发者的首选编程语言。 Python 是解释型语言&#xff1a; 开发过程中没有了编译这个环…

AIGC-常见图像质量评估MSE、PSNR、SSIM、LPIPS、FID、CSFD,余弦相似度----理论+代码

持续更新和补充中…多多交流&#xff01; 参考: 图像评价指标PNSR和SSIM 函数 structural_similarity 图片相似度计算方法总结 MSE和PSNR MSE: M S E 1 m n ∑ i 0 m − 1 ∑ j 0 n − 1 [ I ( i , j ) − K ( i , j ) ] 2 MSE\frac{1}{mn}\sum_{i0}^{m-1}\sum_{j0}^{n-1}[…

汽车展厅应用客流统计,洞察客户规律,完成热门车型分析

在汽车展厅中&#xff0c;客流统计正逐渐成为一项不可或缺的重要工具&#xff0c;它帮助我们洞察客户规律&#xff0c;从而能够更好地完成热门车型分析。 一、客流统计-客户画像分析 客流统计下的客户画像构建为我们提供了深入了解客户的途径。通过对进入展厅的人群进行细致分析…

2007NOIP普及组真题 4. Hanoi双塔问题

线上OJ&#xff1a; 【07NOIP普及组】Hanoi双塔问题 题解分析 1、本题考的其实不是Hanoi塔&#xff0c;而是瞪眼法&#xff08;数学推导&#xff09;和高精度。 2、本题不需要输出移动的顺序&#xff0c;只是输出移动的次数即可。 核心思想&#xff1a; 1、从上述图中&#x…

常见算法(3)

1.Arrays 它是一个工具类&#xff0c;主要掌握的其中一个方法是srot&#xff08;数组&#xff0c;排序规则&#xff09;。 o1-o2是升序排列&#xff0c;o2-o1是降序排列。 package test02; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparat…

PostgreSQL用户与角色简述

简述 PostgreSQL通过角色&#xff08;role&#xff09;来控制数据库的访问权限。角色可以拥有数据库对象&#xff08;比如表、函数等&#xff09;&#xff0c;并允许将这些对象的权限授予其他角色&#xff0c;从而实现对象访问的控制。角色&#xff08;role&#xff09;包含了…

虹科Pico汽车示波器 | 免拆诊断案例 | 2012 款雪佛兰科鲁兹车偶尔多个故障灯异常点亮

故障现象 一辆2012款雪佛兰科鲁兹车&#xff0c;搭载1.8 L 发动机&#xff0c;累计行驶里程约为9.6万km。该车组合仪表上的发动机故障灯、ABS故障灯及动力转向故障灯偶尔异常点亮&#xff0c;同时发动机转速表和发动机冷却液温度表的指针会突然归零&#xff0c;严重时发动机无…

独享IP是原生IP吗?二者有何区别?

原生IP&#xff1a; 原生IP是指由Internet服务提供商&#xff08;ISP&#xff09;直接分配给用户的IP地址&#xff0c;这些IP地址通常反映了用户的实际地理位置和网络连接。原生IP是用户在其所在地区或国家使用的真实IP地址&#xff0c;与用户的物理位置直接相关。在跨境电商中…

牛客NC367 第K个n的排列【困难 dfs,全排列问题 Java/Go/PHP/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/1595969179464e4c940a90b36abb3c54 思路 全排列问题本文提供的答案在力扣同一道题60. 排列序列&#xff0c;超时了但是截止文章发表日&#xff0c;牛客上是能通过全部测试用例的Java代码 import java.util.*;pu…

Redis - 优惠卷秒杀

场景分析 为了避免对数据库造成压力&#xff0c;我们在新增优惠卷的时候&#xff0c;可以将优惠卷的信息储存在Redis中&#xff0c;这样用户抢购的时候访问优惠卷信息&#xff0c;通过Redis读取信息。 抢购流程&#xff1a; 业务分析 既然在新增优惠卷的时候&#xff0c;我…

【c语言】了解指针,爱上指针(5)

了解指针&#xff0c;爱上指针&#xff08;5&#xff09; 回调函数qsort函数冒泡排序模拟实现qsort函数 回调函数 回调函数&#xff1a;就是一个通过函数指针调用的函数。 把函数的指针作为参数传给另一个函数&#xff0c;当这个指针被用来调用指向的函数时&#xff0c;此时被…

驱动编译报error: negative width in bit-field ‘<anonymous>’错误

错误如下图所示&#xff1a; 代码如下&#xff1a; 问题点&#xff1a;module_param的其他用户的权限参数上。 在Linux中&#xff0c;文件权限由读(r)、写(w)、执行(x)权限组成&#xff0c;分别对应数值4、2、1。 第一位0是占位符&#xff0c;在这里没有意义&#xff0c;因为…