在上述的隔夜退房的逻辑代码中,我们用了五个嵌套,其中有五个计算,但实际上只有3种不同的计算,在这样的模式下,我们值得思考,是不是代码过于冗余了。
现在我们把隔夜代码改为如下
Code
//隔夜退房
if (outdate.Hour <= 11 || outdate.Hour == 12 && IsZeroTime(outdate)) //12点整之前(含12点整)
{
days += 0; //当天不计算房费
}
else
{ //下午18点整之前(含18点整之前)
if (outdate.Hour <= 17 || outdate.Hour == 18 && IsZeroTime(outdate))
{
days += 0.5; //加收半天房费
}
else //下午18点整之后
{
days++; //加收一天房费
}
}
不必惊讶,你仔细看看,以上的代码就完成了我们原先冗余的隔夜退房逻辑,而这样的逻辑和我们原先描述的退房业务逻辑正好在语义上完全符合。
通过正确的结构化编程,我们可以消除原先复杂冗余的代码,让程序更加清晰可靠。
下面添加了对日期合法性(入住日期不能大于退房日期)的判断,但系统的整体也没有比我们原先冗余逻辑要复杂。
Code
static void Main(string[] args)
{
DateTime indate = new DateTime(2008, 10, 5, 19, 12, 0); //入住时间
DateTime outdate = new DateTime(2008, 10, 5, 19, 13, 0); //退房时间
double days = (outdate.Date - indate.Date).Days; //计算入住了几天
if (days < 0) //日期错误
{
days = 0;
}
else
{
if (days == 0) //同天退房
{
days += (outdate - indate).TotalHours <= 12 ? 0.5 : 1;
}
else //隔夜退房
{ //12点整之前(含12点整)
if (outdate.Hour <= 11 || outdate.Hour == 12 && IsZeroTime(outdate))
{
days += 0; //当天不计算房费
}
else
{ //下午18点整之前(含18点整之前)
if (outdate.Hour <= 17 || outdate.Hour == 18 && IsZeroTime(outdate))
{
days += 0.5; //加收半天房费
}
else//下午18点整之后
{
days++; //加收一天房费
}
}
}
}
System.Console.WriteLine("你的入住结算信息/n入住时间{0}/n退房时间{1}/n一共入住了{2}天", indate, outdate, days);
}
上述代码中的
days += (outdate - indate).TotalHours <= 12 ? 0.5 : 1;
采用了三目表达式,该表达式的含义是:如果(outdate - indate).TotalHours <= 12的逻辑为真则返回0.5,否则返回1。简化了if else的语句。
所以说一段优秀的代码必然是具有高度的可维护性,而可维护性的代码其实就是能最朴素的表达我们业务的代码,不过这个朴素描述应该是正确演绎了逻辑的见山不是山的境界了。