我有一些關於封裝的常見問題,因爲它涉及到可維護性。這是一個我用來協助構建分析樹的示例類。 (爲了教育的緣故,我避開了STL。)構建C++類層次結構以實現可維護性和封裝
Node
類描述了樹中的一個節點。管理類ParseTree
(未顯示)負責以有意義的樹狀方式構建和維護對象的集合Node
。
// contents of node.h, not including header guard or namespace
class Token;
class Node {
public:
static const Node* FindParent(const Node* p_root, const Node* p_node);
static int Height(const Node* p_root);
static void Print(const Node* p_root);
Node(const Token * p_tok=0) : p_left_(0), p_right_(0), p_tok_(p_tok) {}
~Node() { delete p_left_; delete p_right_; }
const Node* p_left(void) const { return p_left_; }
const Node* p_right(void) const { return p_right_; }
const Token* p_tok(void) const { return p_tok_; }
private:
friend class ParseTree;
Node* p_left_;
Node* p_right_;
Token* p_tok_;
};
以下四個主題與封裝有關。
在
Node
類的靜態方法聲明爲靜態的,因爲它們可以在不使用任何私有成員來表述。我想知道他們是否應該在Node
以外的公共命名空間中生存,或者可能是ParseTree
以內的靜態成員。如果我的決定被ParseTree
負責樹木的事實所支配,並且通過該邏輯,函數應該存在於ParseTree
?在相關說明中,靜態方法在
Node
而不是ParseTree
的原因是因爲ParseTree
已填滿了大量成員。我已經讀過,保持小班和敏捷更適合可維護性。我是否應該去尋找不依賴私人成員訪問的方法,並將它們從我的類定義中提取出來,並將它們放入與類相同的名稱空間中分組的函數中?我還曾讀到避免對私有成員的存取器,因爲它往往會破壞封裝一些建議,所以我最終只具有存取,讓
ParseTree
使用帶有Node
的友誼處理任何修改。這真的比擁有變種者更好,只是結束與ParseTree
的友誼?如果我添加mutators,那麼Node
可以在其他上下文中重用,而不會增加另一種友誼。如果我添加mutators並從
Node
中刪除靜態函數,我覺得我可以公開數據成員,並刪除所有訪問器/ mutators/friend聲明。我有這樣的印象,這種做法是不好的形式。我應該對我的設計持懷疑態度,如果我對每個私人成員都有訪問器/增變器對?如果還有什麼其他明顯和錯誤的方法,我不認爲問,我會很感激聽到它。
你的論點是圍繞着圈子發生的,當我想到這些問題時,就會發生在我身上。我不會太擔心,你看起來像你知道你在做什麼。但非常快1)我不認爲他們應該在節點。 2)是,全球職能。 3)在重用Node方面,我看不出有什麼優勢,它不像有任何重要的價值,將它與ParseTree綁定在一起。 4)不,因爲像Node這樣簡單的事情,一切公開都是可能的。 – john
'Mutator',耶穌安士特和吸氣者有什麼問題? – James
我在過去幾年中大部分時間都在做低層次的工作(IC設計,hdl,嵌入式C)。當我向我描述面向對象的設計時,我的一位密友一直用它來指代訪問者和變種者,當我想到與私人成員進行交互的公共成員函數時,這就是我的頭腦。 –