??? 下面是昨天和同事討論一個(gè)函數(shù)了的實(shí)現(xiàn)時(shí)的對(duì)話。(為了簡(jiǎn)化,減去了其中我由于‘著急上火’而導(dǎo)致‘高音’部分的言語(yǔ)...)?
??
??? C(同事):現(xiàn)在需要由你提供一個(gè)Sample()函數(shù)。
??? J(我):OK,功能是否是為了完成必要的數(shù)據(jù)采集工作?
??? C: 是的,最終數(shù)據(jù)要放到文件中。?
??? J: 放到文件中?那是當(dāng)然。但你的意思是整個(gè)Sample()都要我這邊的代碼實(shí)現(xiàn)嗎?
??? C: 當(dāng)然,你應(yīng)該會(huì)寫(xiě)文件吧??
??? J: 等等,不是會(huì)不會(huì)寫(xiě)的問(wèn)題,而是文件要我來(lái)寫(xiě)嗎?現(xiàn)在的分工上是否是我負(fù)責(zé)數(shù)據(jù)處理,你完成流程調(diào)度?
??? C: 有什么數(shù)據(jù)、流程之分嗎,我們寫(xiě)的是一個(gè)程序啊。如果你非要區(qū)分一下,那應(yīng)該是這樣的。
??? J: 那你看文件存儲(chǔ)和數(shù)據(jù)處理有什么關(guān)系嗎?
??? C: 數(shù)據(jù)最終不是要放到文件中嗎?你數(shù)據(jù)獲取后,保存到文件中,這有什么不對(duì)嗎?
??? J: 你沒(méi)有發(fā)現(xiàn)有什么沒(méi)考慮的問(wèn)題嗎?像是要保存的文件名稱(chēng)我這邊怎么知道?具體數(shù)據(jù)該如何存儲(chǔ)?
??? C: 文件名稱(chēng)在調(diào)用是我會(huì)傳給你的,需要什么都會(huì)傳給你的了;至于存儲(chǔ),按照現(xiàn)在的規(guī)范,字符串格式!
??? J: 都傳過(guò)來(lái)?你確信以后不會(huì)被改成二進(jìn)制方式存儲(chǔ)嗎?好吧,先說(shuō)說(shuō)你想Sample()該如何實(shí)現(xiàn)吧?
??? C: 不用考慮二進(jìn)制了,再說(shuō)如果改了,我們到時(shí)跟著改就是了。好,你看,我想應(yīng)該這樣做,先Open個(gè)文件,然后獲取數(shù)據(jù)的結(jié)果,變成字符串保存到文件中,然后Cose。很清晰的過(guò)程,是吧??
????int?Sample(
)

????
{
????????OpenFile();
????????
????????str?=?GetResult(
);
????????Save(str);
????????
????????CloseFile();????????
????}??? J: OK, 你看這些代碼跟我現(xiàn)在實(shí)現(xiàn)的數(shù)據(jù)部分有多少關(guān)系?而且我們的‘?dāng)?shù)據(jù)’的Result并不都是string類(lèi)型,而且已經(jīng)為不同的Result都定義了相應(yīng)類(lèi)型了,難道這里你要GetResult都轉(zhuǎn)換為string嗎?要是那天存儲(chǔ)改為二進(jìn)制了,我們來(lái)改GetResult()嗎?而且這個(gè)Save()接口參數(shù)也要改,是吧?
??? C: 如果需要改,我們跟著改就是了,這不是問(wèn)題。
??? J: 是的,改不是問(wèn)題,但改多改少,和改動(dòng)的影響的大小應(yīng)該是問(wèn)題吧?最主要的一個(gè)問(wèn)題是,這樣的過(guò)程將數(shù)據(jù)和存儲(chǔ)緊緊耦合在一起了。這種做法對(duì)于分解工作很不利的。
??? C: 我并沒(méi)有覺(jué)得有什么不妥,你打算如何做?
??? J: 首選我們看一下,你需要的是File,Result(數(shù)據(jù))和Save三個(gè)部分代碼,是吧?我們能看出Result是數(shù)據(jù)部分的操作,而File,Save兩部分是流程上的操作,把這樣的代碼都加到‘?dāng)?shù)據(jù)’部分去,是不是有些亂?要不把GetResult()加到‘流程’部分?
??? J: 其次,簡(jiǎn)單地舉個(gè)列子說(shuō),如果有需求要我們獲得Result后,不保存到文件,而只是顯示在屏幕上,那么對(duì)于這種需要,我們要再寫(xiě)個(gè)GetResult()函數(shù)吧?
??? J: 你看,如果涉及Sample()的修改,我們需要修改的地方涉及太多功能塊了。所以根據(jù)功能的不同,分離這些函數(shù)是必要的。Sample()不應(yīng)該能過(guò)作為一個(gè)‘原子’操作,提供出去,應(yīng)該把它分解開(kāi)。 在分解功能時(shí),或者設(shè)計(jì)函數(shù)時(shí),應(yīng)該是功能該是什么樣子的,就按照什么樣子去做,做自己能做的和該做的,而不是為了問(wèn)了迎合另一個(gè)功能的需求而改變自己;功能間的連接我們可以通過(guò)傳遞結(jié)果或者添加‘適配器’等等方法。
????int?Sample(
)

????
{
????????Result?=?GetResult(
);
????????
????????ResultProc(Result);????
????}
????
????int?ResultProc(filename,?result)

????
{
????????str?=?ResultToStr(result);
????????OpenFile(filename);
????????Save(str);
????????CloseFile();
????}??? J: 因此,look,Sample()不是我們需要的,我們需要的是GetResult()和ResuoltToStr(), 而Sample()只是對(duì)它們的再封裝而已。如果發(fā)生前面說(shuō)到的更改需求,GetResult()就不用動(dòng)了。所以,數(shù)據(jù)處理是我這邊要做的,而寫(xiě)文件。。。。是吧?
<----- 吐血的分割線 ---->
?
??? C: 寫(xiě)到了再說(shuō)。。。