程式設計的藝術 不巢狀主義
之前不記得是在哪裡看到的這個不巢狀主義,貌似是在B站上看到的,算是我看了這麼多和程式設計相關的meme裡面對我影響最大的。
是什麼?
什麼是不巢狀主義?準確的說 不巢狀主義 並不是不讓你縮排,而是針對程式碼的結構而言,要儘量少使用巢狀關係,而儘量去使用斷言,或者說將其當成一個單獨的程式碼塊去操作。
比較常見的方式是將報錯提前,而不是用“未報錯則繼續執行”的模式去進行。
怎麼做?
什麼意思?讓我們來閱讀一段程式碼
//巢狀1
if (clsTeachServerInfo)
{
strValue = clsTeachServerInfo->WsSvrAddr;
//巢狀2
if (!System::String::IsNullOrEmpty(strValue))
{
intValue = strValue->IndexOf(":");
//巢狀3
if (intValue > 0)
{
strTeachServerIp = strValue->Remove(intValue);
strTeachServerPort = strValue->Substring(intValue + 1);
this->DebugMessage("CloudPreparation.Initialize " + strTeachServerIp + " " + strTeachServerPort);
PublicObjects::CloudPreparation->Initialize(strTeachServerIp, strTeachServerPort);
}
}
}
我們可以看到這一段程式碼,裡面有三層巢狀的程式碼,這就會導致整個程式碼變得非常的龐大和臃腫,不僅對寫程式碼的使用者不友好,對維護程式碼的使用者更是壓力山大。
或者我們換一個角度來看這段程式碼,如果是不滿足巢狀的條件,會發生什麼?實際上什麼都不會發生對不對?也就是說我們從上往下走程式碼,這個巢狀唯一代表的含義就是:如果在幾個判斷中有一個失敗了,則程式碼不會走到下一步去。
那我們能不能換一種思路,我們把判定失敗的情況提前,讓它單獨去進行判斷,然後用一個bool值去做判斷,或者精簡一點直接return掉,那這樣程式碼的可讀性會不會好很多呢?
讓我們來看一段功能類似的程式碼:
QString strValue;
QString title = "InitTeachServerInfo";
if (SysID.isEmpty()) {
this->eLog(title, "SysID is Empty");
return;
}
CloudPlatformSubsystem_cpp cls_TeachServerInfo;
cls_TeachServerInfo = ptr->GetSubSysAddr(SysID.toStdString());
if (cls_TeachServerInfo.SubjectID.empty()) {
//判定這個是否為空
this->eLog(title, "cls_teachServerInfo return null");
return;
}
strValue = QString::fromStdString(cls_TeachServerInfo.WsSvrAddr);
if (strValue.isEmpty()) {
this->eLog(title, "WsSvrAddr return Error");
return;
}
QStringList list = strValue.split(':');
if (list.size() == 0) {
this->eLog(title, "list's size is zero");
return;
}
雖然這也寫可能程式碼稍微會長一點,但是其可讀性比之前算的上是顯著性地高上了不少。
就我個人而言,有時候程式碼寫的時候可以稍微囉嗦一點多寫一點,但是這也寫的程式碼邏輯結構清晰很多,可讀性也強,不管是維護也好還是除錯也好,都會大大降低查錯的難度