專家解析如何有效的簡化你的軟件開發(fā)
當(dāng)設(shè)計一個問題的解決方案的時候,你應(yīng)該努力讓所有的事情盡可能的變得靈活。但是,太靈活會導(dǎo)致難以理解的代碼出現(xiàn)。相反,考慮編寫一個類,它可以用最簡單的方法(Chevy方法)來解決問題。讓你的類可以通過其他類的繼承而得到擴展。讓你的方法虛擬化,所以你或是其他人在重新使用你的部分代碼之后還可以返回,然后添加額外的靈活性和復(fù)雜性,如果有必要的話(Cadillac)。畢竟,這是OPP所涉及的——擴大并覆蓋未來所出現(xiàn)的新需求的能力。嘗試編寫最少的代碼來完成工作。不多不少,剛剛合適。
當(dāng)設(shè)計你的類的時候,對類本身,方法和屬性使用描述性好的名字。一個類通過定義,而且本身有很好的描述,使用起來也非常簡單。盡量避免行話和縮寫。使用完整的,長的單詞讓方法或是屬性呈現(xiàn)得清晰明確。
在有些不好理解的代碼上添加注解。但是,如果注解的行數(shù)比代碼本身還要多,你就要想一想怎樣讓你的方法變得簡單一些。
設(shè)計樣式
是的,有很多種設(shè)計樣式。這些樣式本身就是很好的工具。但是,你會發(fā)現(xiàn)很多的執(zhí)行非常復(fù)雜;大多數(shù)情況下它們是有過度的殺傷威力。你需要試著找到剛好為你需要的解決方案所工作的一些東西。不要嘗試創(chuàng)建那些現(xiàn)在不存在而且也不會發(fā)生的問題的解決方案。最好是采用極簡單的方法,使用一個基本的設(shè)計樣式,而且找到一種產(chǎn)品而不是花很多時間去試圖完成一個樣式,最后,對解決當(dāng)前的業(yè)務(wù)問題也是毫無意義。
不要再去發(fā)明輪子
對于編程者最好的事情就是他們喜歡編程。最壞的事情也是他們喜歡編程。編程有很多樂趣;那么我們?yōu)槭裁匆鲞@個工作呢?但是,不要忽略這個事實就是你的工作是來支持你所工作的行業(yè)的。你真正的工作是創(chuàng)建應(yīng)用程序來為你的公司賺錢。如果那意思就是說你需要重新使用別人的代碼,那就這樣做。不要有“not invented here”綜合癥。如果你這樣做了,你就不是在為你的公司做事情了。
商業(yè)應(yīng)用程序編程者沒有理由去重塑每個解決方案。一個業(yè)務(wù)編程者的首要任務(wù)就是來支持業(yè)務(wù)。你的工作不只是有很有趣的編程過程。不過那樣也很好,但是如果你所工作的公司需要程序來賺錢,你的工作就是越快越有效的完成程序。如果你不這樣做,你的公司就會因為缺少軟件而失去生意,那么你也會發(fā)現(xiàn)你要重新找工作了!
緊密圍繞Microsoft
不要誤解我的意思。我是真的喜歡Microsoft,而且喜歡使用他們的工具。但是,當(dāng)你選擇使用一個新技術(shù)的時候,你需要小心,因為你的決定會導(dǎo)致代碼在未來可能不會工作??紤]一下在.NET 1.x和2.0之間發(fā)生了什么事情。很多Microsoft建議你使用的事情都沒有了。過去這樣的事情我看到過好多。看一看在過去15年里他們有多少讓我們使用的數(shù)據(jù)訪問技術(shù)啊!
在我的研討小組中,我總是告訴人們"put a wrapper around Microsoft."。就是說不要直接去調(diào)用他們的技術(shù),你可以為LINQ to SQL, LINQ to XML, Entity Framework ,ConfigurationManager和其他的技術(shù)構(gòu)建wrapper類,并且從你的自定義類和方法中調(diào)用它們的功能。圍繞這些技術(shù)意思是當(dāng)Microsoft決定改變它的技術(shù)的時候,你只需在一個地方改變代碼就可以了。它確保你可以保證其他的應(yīng)用程序代碼都一致——只不過就是使用了一種不同的技術(shù)。
團隊編程
我很喜歡code review和團隊編程。如果我沒有在一兩分鐘之內(nèi)給別人解釋好我的代碼,那說明我的代碼太復(fù)雜了。每天,你都和你的同伴一起檢查你的代碼以確保它們不是太復(fù)雜。如果你是自己一個人工作,你就去抓一個朋友,你的伴侶或是你的狗,把代碼解釋給他們聽。
由于我教很多的研討小組成員并且撰寫了很多文章和書籍,我知道我的代碼總是成為一個顯微鏡。我很努力的讓我的代碼對大范圍的編程者來說要易讀并且易懂。如果一個初學(xué)者可以理解我的變量的名字,方法的名字和我的邏輯,我想一個有經(jīng)驗的編程者就更能懂了。你也要想一想你的代碼可以幫助你編寫更簡單,易懂的代碼。
“正確”設(shè)計
如果你看一看這兩段代碼。你會立即區(qū)分出哪個是初學(xué)者編寫的代碼,哪個是有經(jīng)驗的編程者編寫的代碼。初學(xué)者會有設(shè)計不足的代碼。但是,一個有經(jīng)驗的編程者可能會有過度設(shè)計的代碼。當(dāng)一個人沒有在解決問題上有足夠想法的時候,設(shè)計不足的代碼就會產(chǎn)生。
考慮Listing 1中的代碼,檢查是否有文件存在。你可以看到這個顯然沒有將足夠的想法融入重用此代碼中,沒有異常處理?,F(xiàn)在,如果你看到由一個編程者過度設(shè)計的代碼來解決同樣的問題,你可以使用Listing 2中的方法。
- .NET languages
- Listing 1. Under-Engineering:
- Inexperienced programmers may not put enough thought into the code's intended use and exception handling.
- // C# implementation
- private bool FileExists()
- {
- if (System.IO.File.Exists(@"C:\MyFile.txt"))
- return true;
- else
- return false;
- }
- ' VB.NET implementation
- Private Function FileExists() As Boolean
- If System.IO.File.Exists("C:\MyFile.txt" Then
- Return True
- Else
- Return False
- End If
- End Function
- .NET languages
- Listing 2. Over-Engineering:
- While this method may handle every conceivable error, it's overkill for the business problem at hand.
- // C# implementation
- private bool FileExists(string fileName)
- {
- System.Diagnostics.Debug.Assert(
- string.IsNullOrEmpty(fileName),
- "The 'fileName' parameter must be passed " +
- "into the FileExists method");
- try {
- return (System.IO.File.Exists(fileName));
- }
- catch (System.IO.DirectoryNotFoundException ex) {
- throw new Exception("The directory from the file name: " +
- fileName + " does not exist.", ex);
- }
- catch (System.IO.DriveNotFoundException ex) {
- throw new Exception("The drive from the file name: " +
- fileName + " does not exist.", ex);
- }
- catch (System.IO.PathTooLongException ex) {
- throw new Exception("The path from the file name: " +
- fileName + " is too long.", ex);
- }
- catch (Exception ex) {
- throw new Exception("The file: " + fileName +
- " was checked to see it is exists, but some unknown " +
- "problem occurred when calling the File.Exists method", ex);
- }
- }
- ' VB.NET implementation
- Private Function FileExists(ByVal fileName As String) As Boolean
- System.Diagnostics.Debug.Assert( _
- String.IsNullOrEmpty(fileName), _
- "The fileName parameter must be passed into " & _
- "the DoesFileExist method")
- Try
- Return (System.IO.File.Exists(fileName))
- Catch ex As System.IO.DirectoryNotFoundException
- Throw New Exception("The directory from the file name: " + _
- fileName + " does not exist.", ex)
- Catch ex As System.IO.DriveNotFoundException
- Throw New Exception("The drive from the file name: " + _
- fileName + " does not exist.", ex)
- Catch ex As System.IO.PathTooLongException
- Throw New Exception("The path from the file name: " + _
- fileName + " is too long.", ex)
- Catch ex As Exception
- Throw New Exception("The file: " + fileName + _
- " was checked to see it is exists, but some unknown " & _
- "problem occurred when calling the File.Exists method", ex)
- End Try
- End Function
是的,在Listing 2中的代碼是非常好的,而且通過嘗試檢查文件是否存在而解決了所有可能發(fā)生的問題,但是這個代碼就是要解決業(yè)務(wù)問題的代碼嗎?是有可能的,這個代碼只用簡單的一個單一的catch塊,其中包括文件名和從.NET返回的錯誤信息,這已經(jīng)足夠了。有些人花費大量時間來創(chuàng)建這個過度設(shè)計的方法并且還要測試它。有那些時間可以更好的用在解決業(yè)務(wù)問題的上面。
擁有強大,靈活而且可以再度使用的軟件是一個偉大的目標(biāo)。但是,如果你不能交付一個產(chǎn)品來幫助你的業(yè)務(wù),那么這個目標(biāo)是無法實現(xiàn)的。開始研發(fā)你所需要的軟件吧。讓你的代碼可以擴展以適應(yīng)未來的需要。使用簡單的設(shè)計樣式,編寫你的代碼,如果你要把它展示給一個大集團的同行們。如果你遵循這些技術(shù),你會發(fā)現(xiàn)你的代碼是簡單的而且是“正確”的設(shè)計。
【編輯推薦】