您的位置:首页 > 编程语言

如何写出漂亮的代码——不应有的返回值

2013-04-08 21:32 507 查看
项目中有下面这样一段代码,大家看有什么问题:

public class TemplateService
{
public Template Add(Template template)
{
//do save it to db
return template;
}
}


上面的代码我们可能经常都在写,好像看不出有什么问题。但我认为上面这个Add方法读起来就不通顺。如果代码是上面这么写的,那么调用的代码可能就像下面的这样:

var service = new TemplateService();
var template = new Template(){...};
template = service.Add(template);


注意到上面最后一行代码,读起来是不是非常别扭?

我认为好的代码应该是这样的:

var service = new TemplateService();
var template = new Template(){...};
service.Add(template);


(在Add方法体里面,可能会对template实例的某些属性进行赋值,比如ID,因此没有必要再返回template)。

其实,除了Add, 我认为还有很多方法都不应该带返回值。我可以随便列举一些非常常见的调用例子:

userService.Save(user);
userService.Update(user);
userService.Delete(user.Id);
userService.Login(user);


你可能会想,上面这些方法可以返回bool值啊。事实上,在很多代码里可以看到这些方法确实返回了bool值,甚至是有经验的程序员也在这么写。但我并不认为这是一种好的做法。对于那些返回bool值的方法(无非就是想告诉调用者方法是否执行成功),我认为应该用抛出异常的方式来处理。这样做有多个好处:

可以根据输入抛出多个不同的异常信息,而不是将异常吃掉,只是返回一个简单的true/false。

调用处的代码读起来更通顺。

对于某些方法如果你确实不想抛出详细的异常信息,只想告诉调用者成功与否,也就是说你的方法体里面自己会处理异常,那么我建议给方法名称加前缀“Try”. 然后你的代码就会变成这样:

var success = userService.TryLogin(username, password);


上面这段代码就告诉调用者不用处理异常了,因为service里面已经有try/catch了。如果使用抛出异常的模式,我也简单写个例子吧:

public void Login(username, password){
var user = Get(username);
if(user == null){
throw new Exception("The user doesn't exist");
// throw new UserNotExistException();
}
if(user.Password != EncodePassword(password)){
throw new Exception("Incorrect password!");
// throw new PasswordDosntMatchException();
}
// do other logic
}


最后,我再举更多的那些不应该带返回值的方法调用例子:

var person = new Person();
person.Talk();
person.MoveTo(target.X, target.Y);
person.Go();

var browser = new Browser();
browser.Open();
browser.Go(url);
browser.Close();


假如上面的这些方法带有返回值,你很难想象它们应该返回什么。

好了,本文就写到这里了。本文想说的是,想要写出漂亮的代码,那么你的代码读起来要朗朗上口。如果你有些不同意本文的观点,非常欢迎交流探讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: