寧以non-member、non-friend替換member函數

       有個class表示網頁瀏覽器,現在要寫一個函數用來清除瀏覽器的高速緩存區、URLscookies。請問是使用member函數好,還是使用non-member函數好?

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

  1. class WebBrowser
  2. {
  3. public:
  4.     void clearCache();
  5.     void clearHistory();
  6.     void removeCookies();
  7. };
  8. //member實現方式
  9. class WebBrowser
  10. {
  11. public:
  12.     void clearEverything();
  13. };
  14. //non-member實現方式
  15. void clearBrowser(WebBrowser& wb)
  16. {
  17.     wb.clearCache();
  18.     wb.clearHistory();
  19.     wb.removeCookies();
  20. }

面向對象守則要求數據應該儘可能被封裝,

member函數帶來的封裝型比non-member函數低[1]。此外,提供non-member函數可允許對WebBrowser相關機能有較大的包裹彈性,而那最終導致較低的編譯相依度,因此,在許多方面non-member做法比member做法好。

封裝:意味着不可見。愈多東西被封裝,愈少人看到,愈大的彈性去變化,因爲我們的改變僅僅直接影響到改變的那些人事物。愈多東西被封裝,我們改變那些東西的能力就愈大。這就是我們推崇封裝的原因:它使我們能夠改變事物而隻影響有限客戶[2]

讓函數成爲non-member,並不意味着它不可以是另一個classmember[3]。在C++中,可以使用namespacenon-memberclass[4]進行包含,除了看上去更自然以外,namespace[5]還能夠跨越多個源碼文件[6]


[1]

non-member使用WebBrowser對象的引用,也就是隻使用class提供的接口完成功能;member在類內部,當然可以涉及到類內部的使用細節(比如說,它能夠看到類內部的數據)——這是“封裝性不強”的一個證明。

[2] 作爲一種粗糙的量測:愈多函數可以訪問一個數據,則數據的封裝性愈低。

[3] Java裏面,所有函數必須定義於class中。clearBrowser很可能成爲一個工具類(utility class)的static member函數。

[4] Class定義式對客戶而言是不能擴展的,你可以繼承它,但是class內部的private成員仍然不能訪問。所以,我們寧可使用non-member函數,增加封裝性、機能擴充性。

[5] Class是不能分割的,而將所有便利函數放在多個文件、一個namespace中,意味着客戶可以輕鬆擴展它們:他們只需在namespace中建立文件、包含函數聲明,新函數就像其它舊有的便利函數那樣整合一體。

[6] 因爲你在實現的時候,可能將cookie相關類放在一個文件中,將bookmark相關類放在另一個文件中,而namespace可以組織它們。在stl中,每個頭文件聲明std的某些機能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章