為使用者設計良好的介面

來源:互聯網
上載者:User

標籤:style   blog   color   使用   ar   strong   div   問題   sp   

前言

  作為一名優秀的程式員,必須保證自己的代碼能提供正確的,完善的介面,如此方能和同事,甲方更好的溝通合作,也讓自己的代碼更加地容易維護。

  本文將介紹一些設計優秀介面的思路。

思路一:匯入新的類型

  下面還是先看這個例子,我定義了一個儲存日期的 Date 類:

1 class Date2 {3 public:4     Date(int month, int day, int year);5     // ......6 };

  可用以下方法定義一個 Date 對象:

1 Date d(30, 3, 1995);

  可有些使用者會犯很蠢的錯誤,比如:

1 Date d(30, 3, 1995);

  顯然,他使用者將介面的參數輸錯位了。然而,優秀的介面應當能夠友好反饋錯誤資訊給使用者,這種情況下,最好的策略就是定義新的類型,請參考下面這個 Date 類的設計:

 1 class Day 2 { 3 public: 4     explicit Day(int d) 5         :val(d) {} 6     // ...... 7 private: 8     int val; 9 };10 11 class Month12 {13 public:14     static Month Jan() {15         return Month(1);16     }17     static Month Feb() {18         return Month(2);19     }20     // ......21 22 private:23     explicit Month(int m) {24         val = m;25     }26     // ......27 28     int val;29     // ......30 };31 32 class Year33 {34 public:35     explicit Year(int y)36         :val(y) {}37 private:38     int val;39 };

  而定義一個 Date 對象,可採用如下方式:

1 Date d(Month::Feb(), Day(30), Year(1995));

  在日,月,年各個類中,還可以實現更進階的封裝。

思路二:引導使用者進行正確編碼

  這裡繼續上一篇文章中提到的智能指標的一個例子,這裡要說明的是,當時給出的那個工廠函數:

1 class Investment2 {3     // ......4 };5 6 Investment * createInvestment();

  並不是很好的一種設計。

  為啥?因為使用者可能忘了使用智能指標把 Investment * 接過去。而使用下面的工廠函數介面設計可以有效避免這個問題:

1 std::tr1::shared_ptr<Investment> createInvestment();

  這樣就讓使用者你不用智能指標都不行了,哈哈。

  甚至你還可以更過分,指定智能指標在資源被指數為0的時候要調用的解構函式:

 1 std::tr1::shared_ptr<Investment> createInvestment() 2 { 3     // 指定智能指標類型及刪除器 4     std::tr1::shared_ptr<Investment>retVal (static_cast<Investment *>(0), getRidOfInvestment); 5      6     // retVal = ... 7     // 令 retVal 指向正確的對象 8  9     return retVal;10 }

  上段代碼中的getRidOfInvestment是你自己指定的刪除器。

思路三:限制類型什麼事情可以做什麼事情不能做

  使用 const,explicit等限制性關鍵字,屏蔽無用的拷貝建構函式等可以做到這點。

  這些在以前的文章中均有講解。

思路四:使你的類盡量表現得像內建類型

  要做到這點可不簡單,你需要以"當初語言設計者設計語言內建類型時"那般謹慎的思考class的設計,對設計出的class,我們需要問自己以下幾個問題:

  1. 新的對象資源在何時建立? 何時銷毀?

    這部分同樣涉及到建構函式,解構函式的編寫。

  2. 對象的初始化和賦值應該有什麼樣的差別?

    這部分涉及到建構函式,拷貝建構函式,賦值運算子的編寫。不要混淆這兩個概念。

  3. 如果對象發生了值傳遞,意味著什嗎?

    你得仔細考慮這期間發生的資源相關的一些問題。

  4. 哪些對象是合法範疇?

    對象的成員是不是合法,這點很重要。它影響到了你諸多成員函數的錯誤檢查工作,也影響到了拋出的異常。

  5. 新的類需不需要配合某個繼承圖系?

    如果這個類的子類要實現多態,那麼成員函數就得聲明為虛函數;如果這個類繼承自其它類,那麼當你自訂拷貝建構函式或者重載賦值運算子的時候,也得對父類部分做出處理。

  6. 什麼樣的操作符和函數對這個新的類型來說是合理的?

    需要考慮這個類型應該對哪些運算子多載,還有哪些函數被當做成員函數,哪些用非成員函數實現。

    具體的選取規則,以後會有篇文章專門講。

  7. 什麼樣的標準函數應當駁回?

    將它聲明為 private

  8. 新的類型成員將被哪些對象取用?

    這個涉及到變數private,protected,以及友元相關機制。

  9. 新的類型是否應當滿足一般化的要求?

    如果你要定義的是一個類家族,那麼你需要的不止是一個類,而是一個類模板

小結

  1. 類的設計不要貪快。要盡量滿足,實現這些規則,貪快會導致開發後期事倍功半。

  2. 本文應當在實際項目中進行類設計的時候邊設計邊看,如此,方能有顯著的提高。

 

為使用者設計良好的介面

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.