2013-10-18 61 views
0

doJob()方法中,B通過getter來引用。我個人不贊成這個想法,寧願只是b.execute(),因爲我確信getB()將永遠不會被修改。工程封裝

我知道,通過這樣做,會離開封裝,但不是封裝B對象在這裏矯枉過正?

class A{ 
    private B b; 

    public void setB(B b){ 
     this.b = b; 
    } 

    public B getB(){ 
     return b; 
    } 

    public void doJob(){ 
     getB().execute(); 
    } 
} 
+1

在類內部,您不必擔心使用'getB()',因爲'b'是在您的類中定義的'private'變量。但是,一旦你嘗試從另一個類訪問它,你將需要使用getter。 – Bucket

+0

http://programmers.stackexchange.com/questions/181567/should-the-methods-of-a-class-call-its-own-getters-and-setters – Habib

+1

當你聲明「*'getB()'會永遠不要修改*「,通過在代碼中寫入」final「來強制執行。 – hyde

回答

3

難道真如屬性仍然private不一樣,如果你訪問B通過它的屬性,長吸氣劑物質(所以是的,呼籲getB()是矯枉過正,它肯定不會打破任何的設計模式)。

1

只有當你讓整個班級,或至少讓制定者和獲得者,final,這是正常的。

否則這打破:

class A2 extends A { 

    private B2 b; 

    @override 
    public void setB(B b){ 
     this.b = new B2(b); 
    } 

    @override 
    public B getB(){ 
     return b.toB(); 
    } 
} 

現在調用非重寫doJob()會使用錯誤的成員變量。

3

在這種情況下,它可能是矯枉過正,因爲它是一個簡單的對象。但是,如果有懶加載和你的對象看起來是這樣..

class A{ 
    private B b; 

    public void setB(B b){ 
     this.b = b; 
    } 

    public B getB(){ 
     this.b = this.b ?? new B(); 
     return this.b; 
    } 

    public void doJob(){ 
     getB().execute(); 
    } 
} 

那就不是矯枉過正通過屬性來訪問您的私有成員。

我不知道這是否會對你有幫助,但是如果B是一個依賴項,那麼你的對象應該像這樣設置,其中IB是具體對象B的接口。它是一個控制模式的反轉,從A.對象B但是,這是矯枉過正簡單對象圖以及

class A{ 
    private IB b; 

    // Use inversion of control 
    public A(IB b){ 
     this.b = b; 
    } 

    public IB getB(){ 
     return this.b; 
    } 

    public void doJob(){ 
     getB().execute(); 
    } 
} 
+0

我發現這個懶惰的加載程序模式特別有用,當信息重新創建昂貴時,經常失效並偶爾使用。如果它失效,我只是翻轉一個布爾值來表示它的髒,下一次它需要重新計算。但在此之前它可能會失效很多次,儘管如此,將所有這些unnsisary recalcs節省給我 –

+0

當創建對象時,它們應該是有效狀態下99%的時間。儘管這是一個激烈的爭論。我傾向於傾向於保持我的對象處於有效狀態,但其他人則認爲對象應該能夠保存在無效狀態。例如,如果用戶正在填寫用戶配置文件,則他們應該能夠將該用戶配置文件保存在任何狀態並在稍後繼續。我認爲,如果域模型暴露在客戶端,他們的設計就有一個基本缺陷。有特殊的對象暴露給客戶端(DTO或ViewModels)。 –

+0

我會說他們必須始終處於**外部**有效狀態 –

1

提供了訪問/ mutator方法的私有成員,可以添加錯誤檢查,更換部件的存儲,並做內部其他的事情去上課。你如何訪問班上的成員是你的選擇。

如果您發現以後需要更改類內部,則可以切換到訪問器/增變器。當然,這個簡單的例子不需要accessor(getter)方法。但要認識到,使用吸氣劑可能會使更復雜的情況受益。

2

您正在通過使用吸氣劑來降低風險。如果在一種使用情況下結果爲Bnull,或者由於新要求您需要初始化B。該模式允許您更新getB(),而無需更改A中的任何其他內容。

public B getB(){ 
    if(b == null) { 
     b = getEntityManger().findB(); // or wherever you wanted to get B from 
    } 

    return b; 
}