簡體   English   中英

封裝的“巔峰” - 關於有效C ++建議的問題

[英]“Pinnacle” of Encapsulation - Question Regarding Advice from Effective C++

有效C ++的第23項規定:首選非成員非友元函數到成員函數。

該項目的整個目的是鼓勵封裝,以及封裝靈活性和功能擴展性,但我的問題是,在采取這些建議時你走了多遠?

例如,您可以擁有自己的類,私有數據成員,然后通過將公共函數僅減少為私有數據成員的訪問者和/或更改者來采用極簡主義方法。 然后,每個其他功能都可以是非成員功能。

但是,您是否願意在可能犧牲代碼清晰度的情況下增加封裝,並使用訪問器和變換器? 畫線在哪里?

首先,並非所有人都同意這一建議。 我不認為我見過任何人,只有Meyers( 編輯:Herb Sutter )給出了這個建議,我只是在C ++的上下文中看到它。 例如,在Java或C#中創建“非成員非朋友函數”實際上是不可能的,因為Java和C#沒有自由函數,而Ruby開發人員(例如)更喜歡有意創建成員函數的“人性化接口”非成員可以做同樣的事情,只是為了讓那些功能的來電者的生活更輕松。

即使你接受了邁耶斯的建議,你也應該更喜歡非會員的非朋友功能到會員功能(我認為這是一個很好的建議,它確實幫助我更好地應用封裝來考慮封裝類的實現,即使是從其成員功能),這只是一個需要考慮的設計軸。

. 面向對象設計的關鍵概念是對象 對象不僅僅是其他代碼所做的一組setter和getter。 相反,它應該附加行為 - 也就是說,它應該有做事情的方法 - 它應該封裝它們如何做這些事情的細節。 on behalf of the class, which is the only reason you have a class to begin with) can get to it. 如果你按照這種方法使用OO,那么將Meyers的建議推向極致,因為你確實傷害了封裝而不是幫助它:你最終通過getter和setter暴露所有類的內部實現變量而不是隱藏它們以便只有類的方法(負責代表類創建的代碼,這是你開始使用類的唯一原因)可以實現它。

turn functions into member functions if they could reasonably be implemented as non-friend non-member functions using a class's public interface, but don't damage a class's public interface and violate its encapsulation by exposing implementation avoid making something a member. 那么回答你關於邁爾斯的建議還有多遠的問題:如果可以使用類的公共接口合理將函數實現為非朋友非成員函數,那么不要將函數轉換為成員函數,但不要損壞類的公共接口並通過暴露實現違反其封裝, 避免使某些成員成為某個東西。 並確保你平衡封裝與其他問題和其他方法(包括,如果你的團隊決定走這條路線,一個完整的人性化界面的利弊)。

退后一步,考慮一下課程的目的一項工作是做什么的? 什么類不變量必須確保以最佳方式完成這項工作? 子類化和覆蓋在類的目的中扮演什么角色?

根據訪問器和變換器來構建所有內容絕對不合適:這幾乎會將OOP根源的狀態和行為的結合分離出來,或者掩蓋行為,而這種行為在沒有明智的問題框架中是關於獲取或設置屬性這種“假裝”變異器和存取器的面紗。

只有訪問器和mutator的類是一個特殊情況 - 可能是傳統C類struct的一步,能夠保留一些不變量,但“只是勉強”;-)。

良好的OOP設計中的大多數類都會有行為 - 就像我喜歡泛型編程一樣,使用C ++的一個原因是它的多種范例的強大組合,其中OOP不能被刪除! - )

實際上,只為你的類的私有變量提供訪問器和變換器實際上不是極簡主義(或者在某種意義上可能是極簡主義但不是“最相關”的意義),因為你現在正在向世界展示一個更通用的界面。 封裝的想法是,您的類的接口應盡可能地受到限制,同時允許客戶端代碼完成工作。

遵循這種方法使得將來更容易更改底層實現,這首先是封裝的重點。

一般來說,訪問者背后的想法是變異器,需要以某種方式保護變量。 如果變量具有應該僅由一個實體更新的敏感信息,則可以在mutator中包含該檢查。 一個簡單的事實是,大多數訪問器和更改器只是一種形式(以至於C#現在具有自動屬性)並且不是必需的。 底線是,用你的判斷。 如果它需要限制訪問,那么添加一個mutator。 如果獲取/設置變量無關緊要,則不需要訪問器和增變器。

研究如何將東西打包成合適尺寸的單元是一種主觀藝術。

我制作非成員非朋友的問題之一是,如果內部結構的變化要求添加新的公共接口以支持現有的非成員,或者非成員現在被承認為朋友,那么顯示出比之前設計的更緊密的聯系。 現在做出任何改變都可能成本很高。

雖然可以說在邏輯層面上非成員函數可以與類打包並組成類的接口,但是如果方法的位置發生變化,開發人員將需要進行一些代碼更改,因此執行在它的使用中,界面不是,錯誤的,透明的。

關於Eiffel的一個好處是,一個沒有參數的方法以與變量相同的方式訪問,因此在這些元素之間進行更改是透明的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM