iOS开发——命名的艺术

前言

代码的写法应当使别人理解它所需的时间最小化。 ——《编写可读代码的艺术》

在这里插入图片描述
一个名字是一段小小的注释,虽然空间很小,但是会获得最多且最直接的注视。一个好的名字可以让接手这段代码的人快速明白上下文,一个烂名字会让接手者和调用方感到很困惑,增大协作成本。

命名理论

译事三难:信、达、雅。 ——严复

起一个好的名字也需要讲究“信达雅”:
信:含义准确
达:通顺流畅
雅:简明优雅

把信息装在名字里

起一个好名字需要有更高的信息密度,尽量选择专业的词

具体&专业

空洞四剑客:get, make, find, stop

/// 获取当前图片的大小
- (CGSize)getCurrentLayerSize;

e.g. "get"这个词过于笼统,蕴含的信息量太少了,获取一个size有很多种途径可以拿:

  • 直接取:- (CGSize)currentLayerSize;
  • 计算:- (CGSize)calculateCurrentLayerSize;
  • 请求:- (CGSize)fetchCurrentLayerSize;
  • 生成:- (CGSize)generateCurrentLayerSize;

e.g. "make"这个词太业余了,可以有更加专业的动词替换:

  • 生成:- (NSArray *)generate/create/calculateListViewModels;
  • 有副作用:- (void)setup/updateListViewModels;

e.g. "stop"本身没啥问题,只是可能存在更优的固定搭配:

  • kill + thread
  • terminate + app / runloop
  • pause / remove + animation

移花接木

单词替换词
senddeliver, dispatch, announce, distribute, route, fire
findsearch, extract, locate, discover
getgenerate, calculate, create, fetch, extract
showlaunch(monitor), display(view), open(url, file), popup(alertController), present(viewController)

具体具体再具体

  • 尽量避免给变量取名为ret, tmp, case, num等空泛的词,请绞尽脑汁取一个语义化的名字。
  • 前后缀可以丰富含义,rawContent, escapedString, stringifiedText, stayTimeMs
  • 不要使用 -1 等边界量用于标记“未使用”或者“范围外”,使用NSIntegerMin, NSIntegerMax, NSNotFound

清晰和精确比装可爱好。 ——《编写可读代码的艺术》

PHP中有一个字符串处理函数叫做explode(),这是一个很有表现力的名字,描绘了将一个字符串拆成碎片的景象,但是看名字根本看不出和split()有什么区别(功能相同)。
explode -> split (by string)
split -> preg_split (by regular expression pattern)

符合预期的语义

布尔值命名

  1. 使用is, should, has, can, need等前缀,令bool属性更加明确
  2. 尽量避免使用反义前缀,例如disable,以统一语义
  3. 避免使用二义性词语,例如过去式和过去分词相同的词语

Example 1

@interface ChildView : UIView
@property (nonatomic, readonly, assign) BOOL isLeft;
@end

isLeft是离开了还是在左边?
修改建议:isOnLeft / isLeftPosition

Example 2

// 相册授权状态
NSString *authStatus = @"未授权";
BOOL readAssetCount = NO;
if ([AlbumPickerHelper photoLibraryAuthorizationStatus] == AuthorizationStatusAuthorized) {
  authStatus = @"全部授权";
  readAssetCount = YES;
} else if ([AlbumPickerHelper isPhotoLibraryLimited]) {
  authStatus = @"部分授权";
  readAssetCount = YES;
}

if (readAssetCount) {
  // 获取相册资源数量
  videoCount = [[AlbumQuickLoader sharedQuickLoader].albumResult countOfAssetsWithMediaType:AssetMediaTypeVideo];
  imageCount = [[AlbumQuickLoader sharedQuickLoader].albumResult countOfAssetsWithMediaType:AssetMediaTypeImage];
}

readAssetCount是已经读取了还是需要去读取?
修改建议:
强调完成:isAccessedAssetCount
强调预期:needReadAssetCount

方法(接口)的命名

真正的命名艺术还得看我 => Code Naming Basics

  1. 名称自解释(self-documenting)
    e.g. 一个字符串中用一个子串替换另一个子串,并返回替换后结果
    cpp的写法:
    重载得令人头痛
  • python的写法:
# newStr分别为多少
srcStr = 'abcba'
newStr1 = srcStr.replace('a', 'b')
newStr2 = srcStr.replace('a', 'b', 1)

如果名字无法自解释,点开文档看参数原型,使用成本较高,且代码可读性不佳

  • objective-c的写法:
- [NSString stringByReplacingOccurrencesOfString:withString:]

方法名字虽然很长,但是读上去非常类似于日常语言里的句子:
The source string returns a new string by replacing the occurrences of the string ‘xxx’ with the string ‘yyy’.
如果一个方法名从左到右读起来狗屁不通,please rename it !

  1. 不要用缩写
    苹果在官方文档中详细论述过为什么不要使用缩写,oc本来就是用代码空间来换理解时间的,没必要省那几个字。
    在这里插入图片描述

它甚至还开了一个白名单 => Acceptable Abbreviations and Acronyms

  1. 方法名要与使用者的期望相匹配

以get为前缀的方法一般是“轻量级访问器”,若其时间复杂度较高或者篡改了属性,可能会给调用者带来困扰🤔。
calculate, compute, generate看上去是有代价的操作(非常数级时间复杂度),update, setup, clear则显得有副作用。

  1. 私有方法不要用_开头
    这个前缀是预留给苹果公司使用的,如果使用可能会误覆写父类的私有方法,而导致错误调用
    例如:UIViewController 有一个_resetViewController方法
    解决方案:使用自定义前缀,例如:p_

类与对象的命名

  1. 后缀必须体现出其类型
    子类通常需要继承父类的后缀,若子类名与父类对应不上,会给使用者带来困扰
    e.g. 继承自 NSObject 的model若叫做viewController,会给使用者一种错觉,比如可以挂在响应链上

  2. 类名需要符合使用的预期
    xxxRequest: 一个发请求的Utils实例
    xxxData/Info: 一个model
    xxxManager/Helper/Center: 一个单例类
    xxxProducer/Factory: 工厂类
    xxxing/able: 协议

  3. 对象名也要和类名对应
    UIImage *image; UIImageView *imageView; UITapGestureRecognizer *tapGestureRecognizer;

避免变成裹脚布

一个名字可以通过堆冗余的信息来显得天衣无缝,但过长的名字会很难记,屏占空间大,产生更多的换行,这违背了KISSDRY原则

  1. 提炼语言:convertToInteger, doHandlerXXX -> handleXXX
  2. 作用域小的标识符无需携带太多信息,因为上下文较为清晰。
    category名字不需要重复前缀,系统原生类需要替换前缀(UIViewController+PrefixXxx)
  3. 不要花里胡哨
    主态:hostState -> isAuthorSelf
    头像框:avartarPendant -> avatarDecorator

注释是命名之友

  1. 当名字无法包含足够丰富的上下文信息,可以用注释去补充。
  2. 好名字>烂名字+注释。名字总是第一时间映入眼帘的,与其写一大段注释来解释不如改掉这个名字。

文档注释

  • option+cmd+/
  • /**回车
/**
 @brief 取消投票
 @discussion 接下来是这个方法的使用说明
 @code
 [self.viewModel revokeVoteWithCompletionHandler:^{
   @strongify(self);
 }];
 @endcode
 @note 超级简单是不是
 @param completionHandler 结束回调
 @return 这是一个返回值
 */
- (NSInteger)revokeVoteWithCompletionHandler:(HandlerType)completionHandler;

效果
在这里插入图片描述

枚举注释

/// 表情补充方式
typedef NS_ENUM(NSInteger, SomeEnumType) {
  SomeEnumTypeDefault,	///< 默认样式
  SomeEnumTypeA			///< A类型
};

相关阅读

Introduction to Coding Guidelines for Cocoa
Markup Formatting Reference

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值