iOS 类簇(Class Cluster)使用心得

2024-05-08 21:48

本文主要是介绍iOS 类簇(Class Cluster)使用心得,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们都知道在iOS中类簇的使用是非常普遍的,比如NSNumber、NSString、NSArray等等都是类簇。我们以NSNumber举例来说,对于int,bool, unsigned int 等等数据类型,我们如何把它们封装成类的形式呢? 通常情况下我们可能会想到,对于每一种数据类型独立封装成一个类,比如对于int 类型我们可以做一个NSInt的类,以此类推。这样想是正确的,但是,我们再来想想这样会有什么问题呢?当需要支持的数据类型越来越多时,这些类也会相应的越来越多,那么对于开发者来说,我们就需要记住越来越多的类。那么还有没有好的方案呢?哈哈,这个时候类簇就闪亮登场了。
现在我们遇到的问题是,相似的类越来越多,对于开发者来说需要太多的记忆。显然,我们解决问题的方向肯定是朝着减少暴露给开发者的类的数量这个方向。让我们来回忆一下设计模式,抽象工场模式不就是干这个事情的嘛!
对于NSNumber,我们使用一个NSNumber来作为int,bool,long等原生数据类型的工厂,对外定义一堆的工厂方法,在NSNumber内部则转调给相应的像NSInt这样的内部类去实现具体的逻辑。这样,我们遇到的问题就得到了完美的解决。
下面我们来自己实现一个具体的类簇。场景是这样的,我现在有一个App,只支持英文版,现在我想让其也支持中文版和日文版等等。 我们先来看看模型类吧!

@interface PowerUpDetail : WMModelObject@property (nonatomic, copy)     NSString* name;
@property (nonatomic, copy)     NSString* desc;@end

name 和 desc 分别是英文版对应的字段,现在我想实现中文版,并为以后的其他语言版本做好扩展结构。
现在有几个方案:
1. 继承PowerupDetail,实现子类PowerupDetailCN和PowerupDetailEN在所有调用PowerupDetail的地方,区分出到底应该调用PowerupDetailCN还是PowerupDetailEN。
2. 把PowerupDetail做成类簇,对外暴露通用接口,对内转调给内部类来实现具体逻辑。

方案1是最容易想到的,但是它的缺点是需要对已有的调用代码进行修改,而且如果将来随着越来越多的语言被支持,这些类将会非常多,在调用的地方需要一堆的if-else语句来区分,代码很丑,工作量很大。
方案2是比较好的一种方案,做到了对外暴露最小化,而所有调用的地方都可以不用修改,所有的修改可以只在PowerupDetail这个类中即可完成。
下面上代码~(≧▽≦)/~啦啦啦
在PowerUpDetail.h 文件中:

@interface PowerUpDetail : WMModelObject@property (nonatomic, copy)     NSString* name;
@property (nonatomic, copy)     NSString* desc;- (NSString *)localizedName;
- (NSString *)localizedDesc;@end

在PowerUpDetail.m 文件中:

#pragma mark - For English Version
@interface _PowerUpDetailEN : PowerUpDetail
@end@implementation _PowerUpDetailEN
@end#pragma mark - For Chinese Version
@interface _PowerUpDetailCH : PowerUpDetail
@property (nonatomic, copy) NSString *nameCH;
@property (nonatomic, copy) NSString *descCH;
@end@implementation _PowerUpDetailCH- (instancetype)initWithDictionary:(NSDictionary *)dic
{if (self = [super initWithDictionary:dic]) {_nameCH = [[dic objectForKey:@"nameCH"] copy];_descCH = [[dic objectForKey:@"descCH"] copy];}return self;
}- (NSString *)localizedName
{return self.nameCH;
}- (NSString *)localizedDesc
{return self.descCH;
}@end#pragma mark - Class Cluster
@implementation PowerUpDetail+ (instancetype)alloc
{if ([self class] == [PowerUpDetail class]) {if (WMIsChinesePreference) {return [_PowerUpDetailCH alloc];} else {return [_PowerUpDetailEN alloc];}} else {return [super alloc];}
}- (instancetype)initWithDictionary:(NSDictionary *)dic
{if (self = [super initWithDictionary:dic]) {_name       = [[dic objectForKey:@"name"] copy];_desc       = [[dic objectForKey:@"desc"] copy];}return self;
}- (NSString *)localizedName
{return self.name;
}- (NSString *)localizedDesc
{return self.desc;
}@end

这里,我实现了两个内部类_PowerUpDetailCH和_PowerUpDetailEN,他们都继承于PowerUpDetail,而PowerUpDetail暴露给外边两个方法:
- (NSString *)localizedName;
- (NSString *)localizedDesc;
这些方法可以在子类中按需要进行复写。
需要特别注意下类簇PowerUpDetail的alloc方法,这里要注意 if ([self class] == [PowerUpDetail class]) 这个条件的使用,否则会出现死循环,原因你应该很容易看出来,我就不啰嗦了!

+ (instancetype)alloc
{if ([self class] == [PowerUpDetail class]) {if (WMIsChinesePreference) {return [_PowerUpDetailCH alloc];} else {return [_PowerUpDetailEN alloc];}} else {return [super alloc];}
}

OK,我讲完了,类簇其实很简单,就是一个抽象工厂模式的iOS版本的实现。
另外,推荐阅读一下这篇文章《类簇在iOS开发中的应用》,我也是从这篇文章中学到的知识。

这篇关于iOS 类簇(Class Cluster)使用心得的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/971529

相关文章

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客