好代码、坏代码之二
好代码、坏代码之二
4.多注释,少废话
代码,一定是给人看的,而代码本身的逻辑又决定于方法、类型和依赖的关系之中,所以,必要的注释,是必需且必要的。通过注释的进一步解释,来辅助性地告知代码的逻辑、算法或者流程,不仅是好习惯,更是好代码。
另一方面,注释不是“无病呻吟”,没有必要表述那些显而易见的逻辑或者说明,同时注意区分单行注释和多行注释的应用。
在.NET平台下,XML格式的注释还肩负了另一项重要的使命,那就是根据注释生成代码文档。例如:
/// <summary>
/// 根据用户信息,构建标签信息
/// </summary>
/// <param name="memberId">用户Id,根据用户Id,获取<see cref="Member"/>的实例信息</param>
/// <param name="tag">标签信息</param>
/// <returns>标签信息对象</returns>
public Tag BuildTag(int memberId, string tag)
{
return new Tag();
}
在Visual Studio中,可以通过选择PropertiesàBuild来设置“XMLdocumentation files”选项输出生成XML信息,例如上面的注释信息被生成为:
<?xml version="1.0"?>
<doc>
<assembly>
<name>Anytao.Inside.Ch03.GoodCode</name>
</assembly>
<members>
<member name="M:Anytao.Inside.Ch03.GoodCode.Tag.BuildTag(System.Int32,System.String)">
<summary>
根据用户信息,构建标签信息
</summary>
<param name="memberId">用户Id,根据用户Id,获取<see cref="T:Anytao.Inside.Ch03. GoodCode.Member"/>的实例信息</param>
<param name="tag">标签信息</param>
<returns>标签信息对象</returns>
</member>
</members>
</doc>
通过SandCastle工具就可以基于上述信息生成标准统一的文档信息,基于此方式就可以建立类似于MSDN文档的项目帮助文件,大大简化了这项“复杂”的工作。
5.用命名空间组织你的代码
命名空间,是逻辑上的组织单元,通过命名空间建立对代码的有机组织,是现代语言的一大“创举”,《Java夜未眠》作者蔡学镛说:一个语言是否适合大型开发,可以从它对模块、命名空间(或类似概念)支持的良窳看出端倪。从这个意义上说,命名空间并不是大型开发或者团队开发最重要的核心概念,但却是加分的必要因素。
关于.NET命名空间的详细内容,请参考7.3节“using的多重身份”。
6.切勿模式而模式
设计模式是好的,而滥用模式是不好的。
了解和熟悉设计模式,是需要实践和思考的过程,模式并不是一切问题的灵丹妙药,而且大多时候的滥用反而造成更多的问题。滥用模式体现在两个方面:
· 不慎误用,在不合适的场合应用不合适的模式,例如不是所有的场合都需要引入工厂解耦对象创建;对于依赖于执行状态的场合,并非只有状态模式一种选择,工作流或许能带来更好的控制。
· 过度应用,模式的引入都会或多或少地介入了中间层或者中间代码,过度的模式应用将导致代码复杂度的直线上升,除了会带来性能上的问题还有逻辑上的混乱。
举一个简单的例子,策略模式是将算法从宿主类中剥离出来,将易于变化的部分封装为接口,例如:
public interface ITax
{
decimal Calculate(decimal value);
}
public class FoodTax : ITax
{
public decimal Calculate(decimal value)
{
return new decimal(1 + 0.15) * value;
}
}
public class RetailTax : ITax
{
public decimal Calculate(decimal value)
{
return new decimal(1 + 0.1) * value;
}
}
对于算法分离而言,通过ITax策略可以很好地进行不同行业(例如饮食FoodTax或者零售RetailTax)税率的计算,不同的行业提供不同的算法策略,然而对于变化的税率而言,这种实现的方式略显过度,越来越多的算法策略将造成代码的过度膨胀。所以完全可以对策略的方式进行改良,利用委托将税率算法分离看起来更加简洁而优雅:
public interface ITax
{
decimal Calculate(Func<decimal> rateProvider, decimal value);
}
public class Tax : ITax
{
public decimal Calculate(Func<decimal> rateProvider, decimal value)
{
var rate = rateProvider.Invoke();
return rate * value;
}
}
一下子清爽了很多,避免了“策略”带来过度膨胀,又很好地解决了税率算法的变化与分离,对于客户端的消费并没有太大的差别。
《倚天屠龙记》中有一个重要的片段,张三丰指点张无忌修炼太极,有一段“此时无招胜有招”的精彩论述,武术上真正的无敌不在乎一招一式的死记硬背,也不在于一刀一剑的激情挥洒。同样的道理,似乎更适合用于软件设计与模式,很多时候,架构与设计的极致不在于对模式的“应用”,而在于对模式的“活用”,在于灵魂附体,在于无招胜有招。
本文节选自《你必须知道的.NET(第2版)》一书
图书详细信息:http://blog.csdn.net/broadview2006/article/details/6673353