代码规范

2017-05-27  本文已影响0人  WolfTin

推荐文章:禅与 Objective-C 编程艺

前言


为􏰀高产品代码质量,指导广大软件开发人员编写出简洁、可维护、可靠、可测试、高效 、 可移植的代码,编程规范修订工作组分析 、总结了我司的各种典型编码问题,并参考了业界编程规 范近年来的成果,重新对我司1999年版编程规范进行了梳理、优化、刷新,编写了本规范。 本规范将分为完整版和精简版,完整版将包括更多的样例 、规范的解释以及参考材料(what &why),而精简版将只包含规则部分(what)以便查阅。在本规范的最后,列出了一些业界比较优秀的编程规范,作为延伸阅读参考材料。

代码总体原则


1、清晰第一清晰性是易于维护 、易于重构的程序必需具备的特征 。代码首先是给人读的,好的代码应当可以像文章一样发声朗诵出来。目前软件维护期成本占整个生命周期成本的40%~90%。根据业界经验,维护期变更代码的成本,小型系统是开发期的5倍,大型系统( 100万行代码以上)可以达到100倍。
业界的调查指出,开发组平均大约一半的人力用于弥补过去的错误,而不是添加新的功能来帮助公司􏰀高竞争力。

“程序必须为阅读它的人而编写,只是顺便用于机器执行。”——HaroldAbelson和Gerald Jay Sussman
“编写程序应该以人为本,计算机第二。”——Steve McConnell

本规范通过后文中的原则(如头优秀的代码可以自我解释,不通过注释即可轻易读懂/头文 件中适合放置接口的声明,不适合放置实现/除了常见的通用缩写以外,不使用单词缩写,不得使 用汉语拼音)、规则(如防止局部变量与全局变量同名)等说明清晰的重要性。
一般情况下,代码的可阅读性高于性能,只有确定性能是瓶颈时,才应该主动优化。
2、简洁为美简洁就是易于理解并且易于实现。代码越长越难以看懂,也就越容易在修改时引入错误 。写 的代码越多,意味着出错的地方越多,也就意味着代码的可靠性越低 。因此,我们􏰀倡大家通过编 写简洁明了的代码来􏰀升代码可靠性。
废弃的代码(没有被调用的函数和全局变量)要及时清除,重复代码应该尽可能􏰀炼成函数 。
3、选择合适的风格,与代码原有风格保持一致产品所有人共同分享同一种风格所带来的好处,远远超出为了统一而付出的
代价 。在公司已 有编码规范的指导下,审慎地编排代码以使代码尽可能清晰,是一项非常重要的技能。如果重构/修改其他风格的代码时,比较明智的做法是根据现有代码的现有风格继续编写代码 。

规范实施、解释


本规范制定了编写iOS程序的基本原则、规则和建议。本规范适用于公司内所有iOS软件。本规范自发布之日起生效,对以后新编写的和修改的代码应遵守本规范。本规范由质量体系发布和维护。实施中遇到问题,可以 在组内出。 个体程序员不得违反本规范中的相关规则。

术语定义


头文件

常量&变量

//示例-1:
BOOL a = 2.5;
if (a == YES) {
      NSLog(@"a == yes"); }
else if(a == NO) {
NSLog(@"a == no"); 
} else {
NSLog(@"a == other");
}
NSLog(@"a+0.5 = %f",a+0.5);
iOS编程规范v1.0
==========2014-04-07 21:56:14.280 2014-04-07 21:56:14.281 :test[1224:907] a == other test[1224:907] a+0.5 = 2.500000
//示例-2:
BOOL a =130;
if (a == YES) {
      NSLog(@"a == yes"); }
else if(a == NO) {
      NSLog(@"a == no"); 
} else {
      NSLog(@"a == other");
    }
NSLog(@"a=%hhd a+0.5 = %f",a,a+0.5);
==========2014-04-07 22:14:07.986:test[1510:907] a == other2014-04-07 22:14:07.988 test[1510:907] a=-126 a+0.5 =-125.500000
//示例:错误的用法:
-(BOOL)isBold {
      return [self fontTraits] & NSFontBoldTrait;
}
-(BOOL)isValid {
    return [self stringValue];
}
//正确的用法:
-(BOOL)isBold { 
return ([self fontTraits] & NSFontBoldTrait) ?YES : NO;
}
 -(BOOL)isValid {return [self stringValue] != nil;} - (BOOL)isEnabled {
      return [self isValid] && [self isBold];
 }

-点标记语法
说明:属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况 使用方括号标记语法。
示例:

//良好的风格:
view.backgroundColor = [UIColor orangeColor]; 
[UIApplication sharedApplication].delegate;

//不良的风格:
[view setBackgroundColor:[UIColor orangeColor]]; UIApplication.sharedApplication.delegate;

类和方法

#define RECTANGLE_AREA( a, b ) a * b
#define RECTANGLE_AREA( a, b ) (a * b)
 #define RECTANGLE_AREA( a, b ) (a) * (b)

正确的定义应为:

#define RECTANGLE_AREA( a, b )  ((a) * (b))
#define INTI_RECT_VALUE( a, b )\a = 0;\b = 0;for (index = 0; index <
RECT_TOTAL_NUM; index++) INTI_RECT_VALUE( rect.a, rect.b );

正确的用法应为:

#define INTI_RECT_VALUE( a, b )\ {\a = 0;\b = 0;\}
#define SQUARE( a ) ((a) * (a))int a = 5;int b;b = SQUARE( a++ ); //结果:a = 7,即执行了两次增1。 

正确的用法是:

b = SQUARE( a );a++; //结果:a = 6,即只执行了一次增1。

其他

+(instancetype)sharedInstance {
      static id sharedInstance = nil;
      static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{
      sharedInstance = [[self alloc] init];
       });
      return sharedInstance; 
}
//良好的风格:
-(void)someMethod{
      if (![someOther boolValue])
             return;
       //Do something important 
}
//不良好的风格:
 -(void)someMethod{
      if ([someOther boolValue]) { 
            //Do something important
      }
}
================================
//良好的风格:
-(void)someMethod{
        if ([someOther boolValue]) { 
              //Do something important 
               return;
        }
        //Do something else important 
}
//不良好的风格:
-(void)someMethod{
          if ([someOther boolValue]) { 
                  //Do something important
          } else {
                  //Do something else important
          }
}
================================
//例外:
-(void)someMethod{
        if ([someOther boolValue]) {
              //Do something important
        } else {
                //Do something else important 
         }

        //Do this no matter what 
}
//良好的风格:
NSError *error;
if (![self trySomethingWithError:&error]) {
     // Handle Error
}
//不良的风格:
NSError *error;
[self trySomethingWithError:&error]; 
if (error) {
       // Handle Error
}
//在方法执行成功的情况下赋值非Null值给错误参数,会使路径跳转到假条件分支(随后程序奔溃)
//不良的风格:
Blah *b = thingThatCouldBeNil ?: defaultValue;
//多分支条件应该使用if语句或重构为实例变量。
// 良好的风格:
result = a > b ? x : y;
///不良的风格:
result = a > b ? x = c > d ? c : d : y;

命名


//Code
insertObject: atIndex: insert:at: removeObjectAtIndex: removeObject:remove:In general, don’t abbreviate names of things.
/***/
//Code
destinationSelection
destSel
setBackgroundColor:
setBkgdColor:

常量和变量

//错误的命名: 
int w;
int nerr;
int nCompConns;
tix = [[NSMutableArray alloc] init];
obj = [someObject object];
p = [network port];
//正确的命名:
 int numErrors;
int numCompletedConnections;
tickets = [[NSMutableArray alloc] init]; 
userInfo = [someObject object];
port = [network port];
kInvalidHandle
kWritePerm
//良好的风格:
for (i = 0; i < count; i++) {
      oneObject = [ allObjects objectAtIndex: i];
      NSLog (@"oneObject: %@", oneObject); 
}
NSEnumerator *e = [allObjects objectEnumerator];
id item;
while (item = [e nextObject])
      NSLog (@"item: %@", item);
//良好的风格:
NSString *accountName;
NSMutableArray *mailboxes;
NSArray *defaultHeaders;
BOOL userInputWasUpdated;
//不良的风格: 
NSString *accountNameString ; 
NSMutableArray  *mailbox Array ; 
NSArray *defaultHeaders Array ;
BOOL userInputWasUpdated BOOL ;
//如果变量不是以上基本常用类型,则变量的命名就应该反映出自身的类型 。但有时仅需要某 些类的一个实例的情况下,那么只需要基于类名进行命名。
NSImage *previewPaneImage ; 
NSProgressIndicator *uploadIndicator ;
NSFontManager * fontManager ; 
//基于类名命名
//大部分情况下, NSArray或NSSet类型的变量只需要使用单词复数形式(比如mailboxes ),不必在命名中包含“ mutable ”。如果复数变量不是NSArray或NSSet类型,则 需要指定其类型。
//良好的风格:
NSDictionary * keyedAccountNames; 
NSDictionary * messageDictionary ; 
NSIndexSet * selectedMailboxesIndexSet ;

类和方法


示例:

//正确
-(void)sendAction:(SEL)aSelectortoObject:(id)anObject forAllCells:(BOOL)flag;
//错误
-(void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
//正确
- (id)viewWithTag:(NSInteger)aTag; 
//错误
 - (id)taggedView:(int)aTag;

关于类名

-(id)getDelegate; // AVOID
-(id)delegate; // GOOD示例:
rate= [number floatValue];
newString= [string posedStringWithCanonicalMapping ]; 
subarray=[array arrayWithRange :segment];
decom = [path stringByExpandingTildeInPath ];
string = [string ByAppendingString :@"Extra Text"];
sub = [array objectAtIndex :3];
string = [NSString WithFormat :@"%f",1.5]; 
array = [NSArray WithObject :newString];
//不良的风格:
-sortInfo //是返回排序结果还是给info做排序-refreshTimer
 //返回一个用于刷新的定时器还是刷新定时器
-update
 //更新什么,如何更新
//良好的风格:
-currentSortInfo // "current"清楚地修饰了名词SortInfo
-refreshDefaultTimer // refresh是一个动词。-updateMenuItemTitle //一个正在发生的动作
这仅限于Objective-C的方法名。C++的方法与函数的命名规则应该遵从C++风格指南中 的规则。
//良好的风格:
-(void)setTitle:(NSString*)aTitle;
//Cocoa命名举例:
realPath
fullString
object
//类方法newStringnewArray良好的自定义方法命名风格:recipients = [emailrecipients SortedByLastName ];
newEmail = [CDCEmail emailWithSubjectLine :@"Extra Text"]; 
emails = [mailbox messagesReceivedAfterDate :yesterdayDate];
当需要获取对象值的另一种类型的时候,方法命名的格式语法如下: [object adjective +thing];
[object adjective +thing+ condition ];
[object adjective +thing+input :input];
//良好的自定义方法命名风格:
capitalized = [name capitalized String];
-(void) setName:
-(id) keyForOption:
-(NSArray *) emailsForMailbox:
-(CDCEmail *) emailForRecipients: (NSArray *) theRecipients;
-(NSString *) newName; (CDCOption *) anOption (CDCMailbox *) theMailbox;

其他

关于文件名
说明:
文件名须反映出其实现了什么类–包括大小写。遵循你所参与项目的约定。 文件的扩展名应该如下:
类别的文件名应该包含被扩展的类名,如: GTMNSString+Utils.h或GTMNSTextView+Autocomplete.h

良好的风格:
RefreshBarButtonItem / RefreshBarButtonItem@2x和
RefreshBarButtonItemSelected / RefreshBarButtonItemSelected@2x
ArticleNavigationBarWhite / ArticleNavigationBarWhite@2x和ArticleNavigationBarBlackSelected / ArticleNavigationBarBlackSelected@2x.
被用作相似用途的图片应该使用一个图片文件夹进行分开管理。
缩略词 含义和备注
alloc 分配,拨出
alt 轮流,交替
app 应用程序。比如NSApp表示全局程序对象
calc 计算
dealloc 销毁、析构
func 函数
horiz 水平的
info 信息
init 初始化
max 最大的
min 最小的
msg 消息
nib Interface Builder文档
pboard 黏贴板(仅对常量)
rect 矩形
temp 临时、暂时
vert 垂直的

以下是一些常用的首字母缩略词ASCIIPDFXML:

HTML
URL
RTF
HTTP
TIFF
JPG
PNG
GIF
LZW
ROM
RGB
CMYK
MIDI
FTP

注释


良好的风格: 
/**
\* The maximum size of a download that is allowed.
\* If a response reports acontent length greater than the max  will be \* cancelled.
\*This is helpful for preventing excessive memory usage.
\* Setting this to zero will allow all downloads regardless of size. 
\* @default 150000 bytes
**/
@property (nonatomic) NSUInteger maxContentLength;
// A delegate for NSApplication to handle notifications about app // launch and
shutdown. Owned by the main app controller. @interface MyAppDelegate :
NSObject {
...
} 
@end

说明:使用|来引用注释中的变量名及符号名而不是使用引号。 这会避免二

义性,尤其是当符号是一个常用词汇,这使用语句读起来很糟糕。 示例:

对于符号count :// Sometimes we need |count| to be less than zero.或者当引用

已经包含引号的符号:// Remember to call |StringWithoutSpaces("foo bar baz")|

格式


-指针变量的星号指示符应该紧靠变量。
示例:
NSString *text,而不是NSString* textNSString * text

-方法声明中,-/ +和返回类型之间须使用一个空格。
示例:

-(void)doSomethingWithString:(NSString *)theString { ... }
void *ptr = &value + 10 * 3; NewType a = (NewType) b;for ( int i = 0; i < 10; i ++ ) { doCoolThings();
}
NSArray *theShit = @[ @1 , @2, @3 ] ;

字典字面值的键和冒号之间没有空格,冒号和值之间有一个空格。

NSDictionary *keyedShit = @{ GHDidCreateStyleGuide: @YES };

C函数声明中,左括号的前面 不保留空格,并且函数名应该像类一样带有命名空间标识。
良好的风格:

void RNCwesomeFunctio n( BOOL hasSomeArgs);

长的字面值应被拆分为多行。
良好的风格:

NSArray *theShit = @[
@"Got some long string objects in here.", [AndSomeModelObjects too],@"Moar strings."];
NSDictionary *keyedShit = @{@"this.key": @"corresponds to this value",
@"otherKey": @"remoteData.payload", @"some": @"more",@"JSON":
@"keys",@"and": @"stuff",
};
@interface MyProtocoledClass : NSObject { 
@private
id delegate_; 
}
-(void)setDelegate:(id)aDelegate; 
@end

示例:

@interface MyClass : NSObject {
@public ...
@private ...
} 
@end
@try {
      foo(); 
}
@catch (NSException *ex) { 
       bar(ex);
}@finally {
      baz(); 
}
@interface MyClass : NSObject { 
@private
NSString *name_; 
}
@property(copy, nonatomic) NSString *name; @end@implementation MyClass @synthesize name = name_;
- (id)init { ...}
@end
@interface CustomModelViewController : TTViewController <
TTModelDelegate,TTURLRequestDelegate>
-(void)doSomethingWith:(GTMFoo *)theFoo 
                    rect:(NSRect)theRect
                interval:(float)theInterval {
... }

说明:当第一个关键字比其它的短时,保证下一行至少有 直对齐,而不是使用冒号对齐

if (user.isHappy) {
       //Do something
}else {
       //Do something else
}

如果一个方法内有多个功能区域,可以使用空行分隔功能区域。

if(!error) {
      return success;
 }
//不良的风格:
 if (!error)
      return success;
//或:
if (!error) return success;

声明


内容来自这

上一篇 下一篇

猜你喜欢

热点阅读