实习生的代码

最近接手一个项目,项目之前估计是实习生做的,看到很多实习生经常会出现的问题,随手摘几个出来。

不会使用间接

例子一

间接是一个很简单入门级的编程原则,但我发现很多实习生还是会犯这样的错误,比如下面的代码:

if (!isFavorite) {
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"取消收藏" style:UIBarButtonItemStyleBordered target:self action:@selector(favourite)];
} else {
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"收藏" style:UIBarButtonItemStyleBordered target:self action:@selector(favourite)];
}

这段代码很明显违反了间接原则,调用函数的代码是一样的,唯一不同的的title参数,为什么不用变量取代title?

正确的做法:

NSString *title = isFavorite ? @"收藏" : @"取消收藏";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStyleBordered target:self action:@selector(favourite)];

这样不是简单了很多?如果你不喜欢用三元操作符,可以用if代替,甚至你可以这样:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:isFavorite ? @"收藏" : @"取消收藏" style:UIBarButtonItemStyleBordered target:self action:@selector(favourite)];

但我还是推荐使用变量,这样代码看起来会清晰一些。

例子二

再看另一例代码

switch (indexPath.row) {
	case 0:{
          cell.textLabel.text = @"我的订单";
          cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
         break;
      }
      case 1:{
          cell.textLabel.text = @"我的代金券";
          cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
          break;
      }
      case 2:{
          cell.textLabel.text = @"我的常住酒店";
          cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
          break;
      }
      case 3:{
          cell.textLabel.text = @"我的收藏";
          cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
          break;
      }
  }

首先且不论这样的UITableView最好用Interface Builder中的StaticCell实现,如果一定要用代码,也不用这么多重复的代码,我们可以这样。

 NSString *text;
 UITableViewCellAccessoryType accessoryType = UITableViewCellAccessoryDisclosureIndicator;
 switch (indexPath.row) {
	case 0:{
     text = @"我的订单";
     //accessoryType=xxx;
     break;
   }
   case 1:{
     text = @"我的代金券";
     break;
   }
   case 2:{
     text = @"我的常住酒店";
     break;
   }
   case 3:{
     text = @"我的收藏";
     break;
   }
 }
 cell.textLabel.text = text;
 cell.accessoryType = accessoryType;

假如accessoryType很少改变或者不变的情况下,我们可以这样:

cell.textLabel.text = @[@"我的订单", @"我的代金券", @"我的常住酒店", @"我的收藏"][indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

没错,我们只需要两行代码就可以了,这样的代码是不是要清晰简洁一些?

另外,不太推荐这种用indexPath.row的方式来做条件判断,例如你需要在中间插入一行的话,你就知道这是一个恶梦了。即使某些时候我们需要用indexPath.row来判断,也应该尽量用变量代替。

嵌套过深

例子一

如果一个函数/循环有多个条件,不会使用continue/return退出。

-(void) someMethod{
	if(conditionOne){
		//do something
	}else if(conditionTwo){
		//do something
	}else if(conditionThree){
		//do something
	}else if(conditionFour){
		//do something
	}
}

其实这个是属于编程技巧问题了,像这种情况,通常我会尽早退出,我的做法如下:

-(void) someMethod{
	if(conditionOne){
		//do something
		return;
	}

	if(conditionTwo){
		//do something
		return;
	}

	if(conditionThree){
		//do something
		return;
	}

	if(conditionFour){
		//do something
	}
}

代码是长一点,因为每个条件都会多一个return,但如果第一个已经匹配,后面的条件再判断是没有必要的。

例子二

-(void) someMethod{
	if(condition){
		//复杂的处理
		if(subCondition){
			//More
		}

		//do something
	}else{
		//简单的处理
	}
}

像这种况,我会把简单的逻辑写在前面,然后尽早退出,这样复杂的代码就不会过多的嵌套,而导致阅读困难。代码如下:

-(void) someMethod{
	if(!condition){
		//简单的处理
		return;
	}

	//复杂的处理
	if(subCondition){
		//More
	}

	//do something
}

我先判断条件做完简单的处理,然后退出,再进行复杂的处理,这样可以避免过多的嵌套。

单个函数/类代码过长

有些实习生可以一个函数写数百行上千行代码,这样阅读起来很难受,要知道,代码不只是写给你一个人看的。即使是一个人写代码,过几个月你自己还要看的。即使没人看,也应该弄得漂亮一点。

一个函数20行代码就够啦,一个类500行代码就差多了

不会抽象

这个是一个非常非常典型的问题,抽象能力是一个程序员的基本功,如果无法好好的抽象,就不能应付多变的需求。要程序员既要懒又要勤,遇到类似的逻辑要抽象出来,不要犯懒就粘贴复制党,碰到不合理的地方要去重构。

下面的例子,是一个读取xml的代码

HotelListData *itemData = [[HotelListData alloc] init];
NSArray *arrA = [element elementsForName:@"Hotelid"];
itemData.hotelID = [(DDXMLElement *)[arrA objectAtIndex:0] stringValue];
NSArray *arrB = [element elementsForName:@"Hotelname"];
itemData.hotelName = [(DDXMLElement *)[arrB objectAtIndex:0] stringValue];
NSArray *arrC = [element elementsForName:@"Address"];
itemData.hotelAddress = [(DDXMLElement *)[arrC objectAtIndex:0] stringValue];
//更多这样的代码

这种做法相当不优雅,完全是copy+paster,且不说那名称为ABCD的了。为什么不把同样的操作抽象出来做为一个方法呢,而且当xml数据少了某一个节点,这样的代码有可能就会报错。

来看如何改正,首先抽象出一个方法,用来处理从xml节点读取文本内容。

-(NSString *) getNodeTextWithName: (NSString *) name element: (DDXMLElement *) element{
  NSArray *list = [element elementsForName: name];
  if(list.count == 0) return nil;
  return [((DDXMLElement *)list.firstObject) stringValue];
}

然后

itemData = [[HotelListData alloc] init];
itemData.hotelID = [self getNodeTextWithName:@"Hotelid" element:element];
itemData.hotelName = [self getNodeTextWithName:@"Hotelname" element:element];
itemData.hotelAddress = [self getNodeTextWithName:@"Address" element:element];
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值