不知不覺就第30天了~
有始有終地來看看今天的守則吧!
今天要介紹的是第22條守則~ 相對來說簡單明瞭好實踐,就抱著輕鬆的心情來看看背後的道理吧!
今天的守則是:
Declare data members private
重點有兩個: 1. 為什麼不該宣告為public; 2. protected data也跟public也同等
就可以得到結論─ 請宣告為 private。
那為什麼不該宣告為 public 呢?如果不宣告為public,那這些data members就只能藉由member functions來access,這樣clients就不用記得要怎麼去取得那些members,更能達到 "權限控制" 的功效,可以利用 "getter"、"setter" 去分別賦予read/ write權限,讓需要被 隱藏的data members不會隨便暴露。
更有甚者,這也達到了 "封裝" 的效果;如果是藉由function來讓別的人碰到data member,就可以隨時把clientes取到的data member取代為新的計算方式或其他值,而不需要別的改動。這提供了實作上的 "彈性"。
所以 封裝有哪些好處呢?第一個,可以確保data members 不會被隨意亂改,因為只有member function可以改動;第二個,保留了可以改動 實作變化的空間。如果沒有封裝起來,你要改動會無比困難,因為跟它有所互動的clients都可能會受影響,所以你不能亂改,否則可能整個程式就無法運作。換句話說,沒有被封裝起來的code== unchangeable,尤其太多人用的,會直接改不動。反過來說,被廣泛使用的classes 最需要封裝,因為如果它的實作可以被替換優化,效益會最大!
而不該被宣告為 protected的理由跟上面public完全一樣。
第一反應可能會覺得:沒有吧!protected應該有比public更保護data才對。但其實答案是:沒有!
以 封裝的角度來看,"封裝程度"是與"改動後會破換的code數量"成反比,例如把這個data member拿掉之後要改動到多少的code才能動。而public data members改動後的受影響程度是: "所有有用到它的code"=無限大;那protected呢? "所有有用到它的derived class",一樣也是 無限大。所以兩者是一樣的。只要你將data member宣告為public
或protectd
,而clients也開始使用它了,你就很難再去改它了。
所以從封裝角度來看,沒有什麼 pulic, protected, private三等的保護程度,只有private以及其他而已~
貼心重點提醒:
- Declare data members private. It gives clients syntactically uniform access to data, affords fine-grained access control, allows invariants to be enforced, and offers class authors implementation flexibility.
- protected is no more encapsulated than public
簡而言之,將data members宣告為private有以下好處:1. 存取data的統一介面 2. 提供access control 3. 保護data不受變化 4. 提供實作彈性空間;而protected沒有比public有多受到封裝,論這些特性,只有 private,與private以外這兩種。
終於完賽啦!不過還到本書的一半不到QQ 希望接下來可以看完。
也歡迎再把目前有提到的這些守則再回來查閱一番─[Day 1] 前言。
這本書也很久了,作者後面還有其他也是近10年前XD "More Effective C++", "Effective Modern C++"...等等,有機會就再繼續看下去,不過另外一個經典"Code complete"更優先~
明年見(?)