【iOS】——工厂设计模式

news2024/11/17 19:41:37

文章目录

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


一、设计模式

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

创建型模式

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

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

结构型模式

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

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

行为型模式

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

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

二、设计模式七大准则

  • 单一职责原则

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

  • 开放封闭原则

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

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

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

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

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

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

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

三、简单工厂模式

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

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


优点

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

缺点

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

主要作用

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

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

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

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

//CYZActionFactory.h
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CYZActionFactory : NSObject
+(id)createAction:(NSString*)actionType;
@end

NS_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;
@end

NS_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

@end

NS_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;
@end

NS_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;
@end

NS_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

@end

NS_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

@end

NS_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;
@end

NS_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

@end

NS_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

@end

NS_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.coloradmin.cn/o/1712327.html

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

相关文章

Spring学习⑤__Spring AOP的高级应用

Spring AOP的应用配置 Spring中的事务管理 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言&#xff08;如SQL&#xff0c;C或Java&#xff09;书写的用户 程序的执行所引起&#xff0c;并用形如begi…

ABB工业机器人伺服驱动器维修

ABB机器人驱动器是机器人的核心部件&#xff0c;负责驱动机器人的关节进行各种动作。因此&#xff0c;对ABB工业机械手驱动器维修和维护至关重要。 一、ABB机械臂驱动器故障诊断 在ABB工业机器人驱动器维修之前&#xff0c;首先需要准确诊断故障。以下是一些常见的故障诊断方法…

多线程新手村3--多线程代码案例

1.1 单例模式 单例模式是设计模式中非常经典的一种。那么有同学肯定就会好奇了&#xff0c;什么是设计模式呢&#xff1f; 设计模式简单的说就是程序员的“棋谱”&#xff0c;我们下象棋时肯定或多或少都背过棋谱&#xff0c;例如当头炮、马后炮等&#xff0c;设计模式也是这…

【病毒分析】Babuk勒索家族babyk后缀系列分析--Windows篇

1.背景 1.1 Babuk勒索家族 Babuk勒索家族最早曝光于2021年1月初&#xff0c;在几个月内&#xff0c;它就跻身于最臭名昭著的勒索软件组织之列。自回归以来&#xff0c;它通过在地下论坛上积极宣传自己而获得了更多的知名度。在策略方面&#xff0c;其加密功能与其他勒索软件组…

C++|set、map模拟实现<——红黑树

目录 一、红黑树的迭代器 1.1红黑树迭代器框架 1.2operator*() && operator->() 1.3operator() 1.4operator--() 1.5operator() && operator!() 1.6begin() && end() 二、如何用红黑树搭配map和set(仿函数) 三、红黑树封装map和set(简易版…

图片怎么批量重命名从1到50?这3个方法一键改名

图片怎么批量重命名从1到50&#xff1f;图片批量重命名从1到50的过程不仅提高了我们处理大量图片文件的效率&#xff0c;还大大简化了命名过程&#xff0c;让我们能更加有条理地管理和存储图片。通过使用各种专业的工具和方法&#xff0c;我们可以轻松实现图片文件的自动化命名…

【美羊羊拿金币问题】

问题&#xff1a; 有一天美羊羊正在草地上玩耍&#xff0c;突然天上开始落金币&#xff0c;这些金币掉落的范围在一个固定的水平区域内&#xff0c;但这些金币一旦掉落到地上就消失了&#xff0c;因此美羊羊只有不断地移动并从空中接住这些金币才能得到它们。假设金币掉落的位…

宝兰德入选“鑫智奖·2024金融数据智能运维创新优秀解决方案”榜单

近日&#xff0c;由金科创新社主办、全球金融专业人士协会支持的“2024 鑫智奖第六届金融数据智能优秀解决方案”评选结果正式公布。凭借卓越的技术实力和方案能力&#xff0c;宝兰德「智能全链路性能监控解决方案」从90个参选方案中脱颖而出&#xff0c;荣誉入选“鑫智奖2024金…

关于C++的IO流简单总结

基础IO流 C的IO以面向对象的形式实现, 同时兼容了C语言面向过程的IO方式 C 标准库提供了四个基本流对象&#xff1a; cin&#xff1a;用于从标准输入&#xff08;通常是键盘&#xff09;读取数据。 cout&#xff1a;用于向标准输出&#xff08;通常是控制台&#xff09;写入…

【云原生】kubernetes中的认证、权限设置--RBAC授权原理分析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

自动化使用 ChatGPT 生成 PPT 大纲 - 基于 Python 和 PyAutoGUI

这篇文章将指导您利用 Python 的 pyautogui 库创建一个自动化的脚本&#xff0c;帮助您使用 ChatGPT 生成公司智能管理平台的 PPT 大纲。该脚本将打开 Chrome 浏览器&#xff0c;访问 ChatGPT 并输入相应的提示词&#xff0c;让 ChatGPT 为您创建 PPT 大纲。 C:\pythoncode\ne…

为什么宋以前权臣篡位多、宋以后权臣篡位少?

时代不同&#xff0c;主要问题也不同。天下的大气候&#xff0c;自然就要左右王朝的小气候。权臣篡位&#xff0c;得先有权臣。但是&#xff0c;如果当权臣都没有了&#xff0c;又怎么可能有权臣篡位呢&#xff1f;这是一个社会基础的变化。宋以后的主要矛盾是中原和草原的争锋…

白酒:白酒产地的地域文化与品牌形象

云仓酒庄豪迈白酒&#xff0c;作为中国白酒的一部分&#xff0c;其品牌形象深受产地的地域文化影响。地域文化是一个地区与众不同的文化传统和价值观&#xff0c;它影响着当地人的生活方式和审美观念&#xff0c;进而影响白酒的品牌形象。 首先&#xff0c;白酒产地的历史与传统…

质量工具系列之Dependency-Track

项目开发中依赖了很多第三方开源工具&#xff0c;对于其版本&#xff0c;漏洞等因为时间或者是数量太多而无法关注到&#xff0c;Dependency-Track解决这些问题。 Dependency-Track 是一个开源组件分析平台&#xff0c;是开放网络应用安全项目&#xff08;OWASP&#xff09;的一…

电源小白入门学习8——电荷泵电路原理及使用注意事项

电源小白入门学习8——电荷泵电路原理及使用注意事项 电荷泵简介电荷泵原理电荷泵设计过程中需要注意的点fly电容的安秒平衡DC/DC功率转换技术对比 电荷泵简介 电荷泵&#xff08;Charge Pump&#xff09;是一种电路拓扑结构&#xff0c;用于实现电压升压或降压的功能。它通过…

实战15:bert 命名实体识别、地址解析、人名电话地址抽取系统-完整代码数据

直接看项目视频演示: bert 命名实体识别、关系抽取、人物抽取、地址解析、人名电话地址提取系统-完整代码数据_哔哩哔哩_bilibili 项目演示: 代码: import re from transformers import BertTokenizer, BertForTokenClassification, pipeline import os import torch im…

POLARDB:新零售用户MySQL上云最佳选择

什么是云数据库POLARDB&#xff1f; POLARDB是阿里云自主研发的最新一代RDS关系型数据库&#xff0c;是特别针对互联网场景设计的Cloud-Native 云原生数据库。POLARDB for MySQL版本&#xff0c;在提供100%兼容MySQL5.6/8.0的关系型事务处理ACID特性之上&#xff0c;能够提供完…

【NumPy】掌握NumPy的histogram函数:数据直方图的生成与应用详解

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

基于序列深度学习模型的向量海岸线形状分类方法 2024.05

本文中提出了一个数据驱动的方法来分类的形状矢量海岸线&#xff0c;该方法利用基于序列的深度学习算法对海岸线矢量分段进行建模和分类。具体而言&#xff0c;首先将复杂的海岸线划分为一系列弯曲&#xff0c;并进一步提出了一组不同的特征来描述每个弯曲的形态特征。然后&…

Vue热更新出现内存溢出

Vue热更新出现内存溢出 vue-cli2遇到此问题的解决办法&#xff1a;vue-cli3遇到此问题的解决办法&#xff1a;方法一&#xff08;已测试ok&#xff09;方法二&#xff08;未尝试&#xff09; 开发项目有一段时间了&#xff0c;随着项目越来越大&#xff0c;打包的时间也相应的变…