架構師之路(5)面向對象的設計原則

字號:

1 OO的設計原則
    采用面向對象的分析和設計思想,為我們分析和解決問題提供了一種全新的思維方式。我們在拿到需求之后(略去OOA,以后補全),接下來的問題就是:如何對系統(tǒng)進行面向對象的設計呢?
    按照軟件工程的理論,面向對象的設計要解決的核心問題就是可維護性和可復用性。尤其是可維護性,它是影響軟件生命周期重要因素,通常情況下,軟件的維護成本遠遠大于初期開發(fā)成本。
    一個可維護性很差的軟件設計,人們通常稱之為“臭味”的,形成的原因主要有這么幾個:過于僵硬、過于脆弱、復用率低或者黏度過高。相反,一個好的系統(tǒng)設計應該是靈活的、可擴展的、可復用的、可插拔的。在20世紀80到90年代,很多業(yè)內專家不斷探索面向對象的軟件設計方法,陸續(xù)提出了一些設計原則。這些設計原則能夠顯著地提高系統(tǒng)的可維護性和可復用性,成為了我們進行面向對象設計的指導原則:
    1、 單一職責原則SRP
    每一個類應該只專注于做一件事。
    2、 “開-閉”原則OCP
    每一個類應該是對擴展開放,對修改關閉。
    3、 里氏代換原則LSP
    避免造成派生類的方法非法或退化,一個基類的用戶應當不需要知道這個派生類。
    4、 依賴倒轉原則DIP
    用依賴于接口和抽象類來替代依賴容易變化的具體類。
    5、 接口隔離原則ISP
    應當為客戶提供盡可能小的接口,而不是提供大的接口。
    其中,“開-閉”原則是面向對象的可復用設計的基石,其他設計原則是實現(xiàn)“開-閉”原則的手段和工具。
    我會為大家一一進行講解。
    2 單一職責原則SRP(Single-Responsibility Principle)
    2.1什么是單一職責
    單一職責就是指一個類應該專注于做一件事?,F(xiàn)實生活中也存謚釗绱死嗟奈侍猓?ldquo;一個人可能身兼數(shù)職,甚至于這些職責彼此關系不大,那么他可能無法做好所有職責內的事情,所以,還是專人專管比較好?!蔽覀冊谠O計類的時候,就應該遵循這個原則:單一職責。
    我們以計算器編程為例:
    在有些人眼里,計算器就是一件東西,是一個整體,所以它把這個需求進行了抽象,最終設計為一個Calculator類,代碼如下:
    class Calculator{
    public String calculate() {
    Console.Write("Please input the first number:");
    String strNum1 = Console.ReadLine();
    Console.Write(Please input the operator:");
    String strOpr= Console.ReadLine();
    Console.Write("Please input the second number:");
    String strNum2 = Console.ReadLine();
    String strResult = "";
    if (strOpr == "+"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) + Convert.ToDouble(strNum2));
    }
    else if (strOpr == "-"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) - Convert.ToDouble(strNum2));
    }
    else if (strOpr == "*"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) * Convert.ToDouble(strNum2));
    }
    else if (strOpr == "/"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) / Convert.ToDouble(strNum2));
    }
    Console.WriteLine("The result is " + strResult);
    }}
    另外,還有一部分人認為:計算器是一個外殼和一個處理器的組合。
    class Appearance{
    public int displayInput(String &strNum1,String &strOpr, String &strNum2) {
    Console.Write("Please input the first number:");
    strNum1 = Console.ReadLine();
    Console.Write(Please input the operator:");
    strOpr= Console.ReadLine();
    Console.Write("Please input the second number:");
    strNum2 = Console.ReadLine();
    return 0;
    } 1 OO的設計原則
    采用面向對象的分析和設計思想,為我們分析和解決問題提供了一種全新的思維方式。我們在拿到需求之后(略去OOA,以后補全),接下來的問題就是:如何對系統(tǒng)進行面向對象的設計呢?
    按照軟件工程的理論,面向對象的設計要解決的核心問題就是可維護性和可復用性。尤其是可維護性,它是影響軟件生命周期重要因素,通常情況下,軟件的維護成本遠遠大于初期開發(fā)成本。
    一個可維護性很差的軟件設計,人們通常稱之為“臭味”的,形成的原因主要有這么幾個:過于僵硬、過于脆弱、復用率低或者黏度過高。相反,一個好的系統(tǒng)設計應該是靈活的、可擴展的、可復用的、可插拔的。在20世紀80到90年代,很多業(yè)內專家不斷探索面向對象的軟件設計方法,陸續(xù)提出了一些設計原則。這些設計原則能夠顯著地提高系統(tǒng)的可維護性和可復用性,成為了我們進行面向對象設計的指導原則:
    1、 單一職責原則SRP
    每一個類應該只專注于做一件事。
    2、 “開-閉”原則OCP
    每一個類應該是對擴展開放,對修改關閉。
    3、 里氏代換原則LSP
    避免造成派生類的方法非法或退化,一個基類的用戶應當不需要知道這個派生類。
    4、 依賴倒轉原則DIP
    用依賴于接口和抽象類來替代依賴容易變化的具體類。
    5、 接口隔離原則ISP
    應當為客戶提供盡可能小的接口,而不是提供大的接口。
    其中,“開-閉”原則是面向對象的可復用設計的基石,其他設計原則是實現(xiàn)“開-閉”原則的手段和工具。
    我會為大家一一進行講解。
    2 單一職責原則SRP(Single-Responsibility Principle)
    2.1什么是單一職責
    單一職責就是指一個類應該專注于做一件事。現(xiàn)實生活中也存謚釗绱死嗟奈侍猓?ldquo;一個人可能身兼數(shù)職,甚至于這些職責彼此關系不大,那么他可能無法做好所有職責內的事情,所以,還是專人專管比較好。”我們在設計類的時候,就應該遵循這個原則:單一職責。
    我們以計算器編程為例:
    在有些人眼里,計算器就是一件東西,是一個整體,所以它把這個需求進行了抽象,最終設計為一個Calculator類,代碼如下:
    class Calculator{
    public String calculate() {
    Console.Write("Please input the first number:");
    String strNum1 = Console.ReadLine();
    Console.Write(Please input the operator:");
    String strOpr= Console.ReadLine();
    Console.Write("Please input the second number:");
    String strNum2 = Console.ReadLine();
    String strResult = "";
    if (strOpr == "+"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) + Convert.ToDouble(strNum2));
    }
    else if (strOpr == "-"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) - Convert.ToDouble(strNum2));
    }
    else if (strOpr == "*"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) * Convert.ToDouble(strNum2));
    }
    else if (strOpr == "/"){
    strResult = Convert.ToString(Convert.ToDouble(strNum1) / Convert.ToDouble(strNum2));
    }
    Console.WriteLine("The result is " + strResult);
    }}
    另外,還有一部分人認為:計算器是一個外殼和一個處理器的組合。
    class Appearance{
    public int displayInput(String &strNum1,String &strOpr, String &strNum2) {
    Console.Write("Please input the first number:");
    strNum1 = Console.ReadLine();
    Console.Write(Please input the operator:");
    strOpr= Console.ReadLine();
    Console.Write("Please input the second number:");
    strNum2 = Console.ReadLine();
    return 0;
    }