2014-02-25 38 views
10

如果我可以通過吸氣劑返回參考改變私有變量的值,然後是不是繞過setter方法?它不是打敗了吸氣定型者和私人變量的目的嗎?吸氣-setter和私有變量

public class Test{ 

private Dimension cannotBeChanged; 

public Test(int height, int width) 
{ 
    if(height!=3) 
     cannotBeChanged.height = height; 
    if(width!=3) 
     cannotBeChanged.width = width; 
} 

public Dimension getDimension() 
{ 
    return cannotBeChanged; 
} 


public void setDimension(int height, int width) 
{ 
    if(height!=3) 
     cannotBeChanged.height = height; 
    if(width!=3) 
     cannotBeChanged.width = width;  
} 

public static void main(String [] args) 
{ 
    Test testOne = new Test(5,5); 
    Dimension testSecond = testOne.getDimension(); 
    testSecond.height = 3; //Changed height and width to unwanted values 
    testSecond.width= 3; 
} 
+0

以及..如果你不希望別人改變實際的數據,你必須使用防守副本.. 。返回新維(cannotBeChanged); (複製構造函數....) – TheLostMind

+2

我希望我的問題能爲這樣一個愚蠢/簡單的問題得到很多upvotes。 –

回答

12

是的,它的確如此。我從Clean Code一書中得到以下結論:如果你真的接受它,你可以使用它。

  1. 很邪惡:公共領域。
  2. 有點噁心:吸氣劑和吸附劑不需要它們。
  3. 好:getter和setter方法只有當他們真正需要 - 使 類型揭露「較大」的行爲恰好使用它的狀態, 而不僅僅是治療類型狀態的存儲庫是 操縱由其他類型。
+0

我討厭「邪惡」這個詞。在編程中沒有什麼是邪惡的(除了可能從C中飛出你的鼻子中的惡魔))。但是,如果默認使用,有些情況可能會導致問題。 – immibis

1

程序員應該設計爲外部實體摸他的節目的安全變量的方式。

  1. 絕對不要爲您的對象的安全屬性創建任何setter。只能提供吸氣劑。
  2. 只對那些性能,這可以在程序的過程期間改變創建setter方法。
  3. 如果您想對某些屬性應用某些限制,請使用setter。應用無效值檢查,預填充,邏輯分析,填充另一個依賴屬性,防禦性複製等。
  4. 獲取者/設置者有助於維護系統的軟件熵。閱讀軟件entropy
  5. 不要創建它不需要爲它導致Boilerplate代碼getter/setter方法。
  6. getter/setter方法有助於改的程序例如未來擴展的底層實現升級日誌庫等
1

正確的方法實際上是爲維度的所需部分提供一個setter。像這樣:

public int getDimensionX() 
{ 
    return cannotBeChanged.getX(); 
} 

public int getDimensionY() 
{ 
    return cannotBeChanged.getY(); 
} 
0

這裏有一個簡單的Testcase from me。 正如你所看到的,你可以改變Dimension的高度,因爲它是一個參考,但是你不能設置一個新的Dimension。

import java.awt.Dimension; 


public class TestProperty 
{ 
    private String testy; 
    private Dimension testDim = new Dimension(2,2); 

    TestProperty(String testy) 
    { 
     this.testy = testy; 
    } 

    public String getTesty() 
    { 
     return testy; 
    } 

    public void setTesty(String testy) 
    { 
     this.testy = testy; 
    } 

    public Dimension getTestDim() 
    { 
     return testDim; 
    } 

    public void setTestDim(Dimension testDim) 
    { 
     this.testDim = testDim; 
    } 
} 

我的main() - 方法:

import java.awt.Dimension; 

public class Test 
{ 

    public static void main(String[] ARGS) 
    { 
     TestProperty testy = new TestProperty("Testy"); 

     String myString = testy.getTesty(); 
     Dimension myDimension = testy.getTestDim(); 
     myDimension.height = 5; //Changes the height of the private Dimension 
     myDimension = new Dimension(5,3); //Does not set a new Instance of Dimension to my TestProperty. 

     myString = "Test"; 
     System.out.println(myString+"|"+testy.getTesty()); 
     System.out.println(myDimension.height+"|"+testy.getTestDim().height); 
    } 
} 

輸出:

Test|Testy 
3|5 
0

私有變量是指從它聲明的類只訪問。當您創建返回私有變量值的getter方法時,您沒有獲取地址,而是創建一個臨時副本來保存返回值的值。setter方法爲私有變量設置一個值,當它來自另一個類時,該變量不能完成。

因此,基本上,getter-setter方法適用於當您試圖從另一個類訪問或修改私有變量時。

注意:您正在修改的寬度和高度值是Dimension類中的變量,因此它們是公共的而不是私有的。

這個例子看看:

public class Test { 

private double width, height; 

public Test(int height, int width) 
{ 
    setDimension(height, width); 
} 

public double getWidth() { return width; } 
public double getHeight() { return height; } 


public void setDimension(int height, int width) 
{ 
    if(height!=3) 
     this.height = height; 
    if(width!=3) 
     this.width = width; 
} 

public static void main(String [] args) 
{ 
    Test test = new Test(5,5); 
    double testW = test.getWidth(); 

    testW = 3; 

    System.out.println(testW); 
    System.out.println(test.getWidth()); 
} 
} 

返回:

3.0 
5.0