首先看一段程序,这是我以前的编程习惯:
public override void OnPopup()
{
CPopFormBunkMenu menu = (CPopFormBunkMenu)this.ParentMenu;
if (menu != null)
{
this.m_iBunkID = menu.BunkView.BunkID;
if (m_iBunkID != MonitorPlugInTags.InvalidDefineBunkID)
{
m_cdomPatient = (CDomPatient)this.SendSysMsg(new CMsg(MTMonitorPlugIn.GetBunkPatient, m_iBunkID));
if (null != m_cdomPatient)
{
CLoadPropQueryParam lpqp = null;
if (null == m_cdomPatient[CDomObjectNames.ProduceProcess])
{
lpqp = new CLoadPropQueryParam(CDomObjectNames.ProduceProcess, null, null);
if ((bool)this.SendSysMsg(new CMsg(MTAppPatientMgrPlugIn.LoadProp_Sync, m_cdomPatient, lpqp)))
{
CDomProduceProcess pp = (CDomProduceProcess)m_cdomPatient[CDomObjectNames.ProduceProcess];
this.btDeletePP.Enabled = true;
}
else
{
this.btDeletePP.Enabled = false;
return;
}
}
}
}
else
{
this.btDeletePP.Enabled = false;
return;
}
}
else
{
this.btDeletePP.Enabled = false;
return;
}
}
这个函数的主要功能就是,判断一些条件是否满足,以决定是否禁用按钮btDeletePP,当然该段程序在功能是可以满足要求的。但在设计上不合理,一是结构复杂、阅读困难,二是如果要增加条件判断,就会使程序越来越复杂,给维护带来很大困难。针对上述程序可以进行结构上的优化,改为如下代码:
public override void OnPopup()
{
this.btDeletePP.Enabled = false;
CPopFormBunkMenu menu = (CPopFormBunkMenu)this.ParentMenu;
if(null == menu)
{
return;
}
this.m_iBunkID = menu.BunkView.BunkID;
if(MonitorPlugInTags.InvalidDefineBunkID == m_iBunkID)
{
return;
}
m_cdomPatient = (CDomPatient)this.SendSysMsg(new CMsg(MTMonitorPlugIn.GetBunkPatient, m_iBunkID));
if(null == m_cdomPatient)
{
return;
}
CLoadPropQueryParam lpqp = null;
if(null == m_cdomPatient[CDomObjectNames.ProduceProcess])
{
lpqp = new CLoadPropQueryParam(CDomObjectNames.ProduceProcess, null, null);
if(!(bool)this.SendSysMsg(new CMsg(MTAppPatientMgrPlugIn.LoadProp_Sync, m_cdomPatient, lpqp)))
{
return;
}
}
CDomProduceProcess pp = (CDomProduceProcess)m_cdomPatient[CDomObjectNames.ProduceProcess];
this.btDeletePP.Enabled = true;
}
改进后的代码将多个if语句判断分解,每个条件逐一判断,不合法马上返回。这样做的好处:1.多个if语句是平级的关系,尽可能地减少了嵌套的次数; 2. 将是否合法(!=)的判断改为是否不合法(==)的判断,这样可让阅读者(如使用者)一眼就可以看出哪些情况是不合法的,从而避免。3.先将不合法的条件一一列出,只要有一个不满足则退出,意思简洁明了。然后再做条件合法后的处理。这两种情况的条件判断以后可以各自任意添加,而不会增加程序结构的复杂度,因为它们是并列而非嵌套关系。
另外关于程序中的两点编程思想作下说明:
1: 就是函数体的第一句代码:this.btDeletePP.Enabled = false; 这样一开始就假设所有的条件不满足,而将按钮的Enabled 状态设为false,这样在随后的处理中,所有判断不合法的情况下,不用再对该状态进行设置了,都可以用程序一开始设定的默认值。直到合法的情况下,才改变该状态值,将其Enabled状态设为true,这样可以减少代码冗余,提高程序可读性。
2: 在作判断是否相等时,可将常量放在前面,变量放在后面。这样避免书写错误,而将“==”写成了“=”,这样就将后面的常量赋给了前面的常量,而这时程序编译时又不会报错,就会出现预料之外的情况,如代码:if(m_cdomPatient == null) 写成了if(m_cdomPatient =null),那么就将对象m_cdomPatient 赋为null了,那么在随后的程序中该对象将不可用而导致“NULl对象引用”的异常。而这个错误往往不易被发现。如果养成上述的这种习惯,将会避免此问题。