今天在Stackoverflow上讀到了一篇文章 Are Getters and Setters evil? (getter跟setter真的那麼邪惡嗎?)
把一些重點摘錄如下,有習慣看英文的可以直接去看這邊: http://stackoverflow.com/questions/565095/are-getters-and-setters-evil
其中一個大原則是,針對private field, 不使用public setter去直接改值, 用其他有意義且必要的metohd去改變值
範例: 使用kill()或者是damaget()這兩個method去對private的hp欄位進行值的更改,而不使用setHp()來修改
(發表者Zarkonnen)
private int hp; // Set in constructor.
public boolean isAlive() { return hp > 0; } // Same method signature.
public void kill() { hp = 0; } // Same method signature.
public void damage(int damage) { hp -= damage; }
而另一位Jon Skeet網友則如此定義邪惡的等級 (或者說是code的好壞/安全性/OO觀念):
Very evil: public fields.
Somewhat evil: Getters and setters where they're not required.
Good: Getters and setters only where they're really required - make the type expose "larger" behaviour which happens to use its state, rather than just treating the type as a repository of state to be manipulated by other types.
不確定我是否理解正確,他覺得最糟的狀況是直接使用public field (比不必要的getter/setter還糟),好的狀況則是在必要的狀況下使用getter及setter,而所謂必要的狀況,應該是有一些額外的行為想要在getter及setter裡面做,而非僅僅取值/設值.
那除了取值/設值外,會有什麼"額外的行為"是需要在getter和setter裡面做的呢?
coobird網友提供了兩個例子:
範例1: 計算值遭到修改的次數 (更常見的狀況可能是驗證使用者所輸入的資料)
public void setValue(int value)
{
this.value = value;
count++;
}
範例2: 保護原值不任意遭到修改
public int[] getArray()
{
return myArray.clone();
}
ImmutableArray a = new ImmutableArray();
int[] b = a.getArray();
b[0] = 10; // 不會真正更改到myArray本身
而也有人提出 (網友nathan),如果在setter裡面做了許多多餘的動作,別人在使用此API時並無法得知, 如果每個setter使用者都要去確認相當麻煩。
像是這樣的method會是個壞例子
public void setAlive(boolean isAlive){
this.isAlive = isAlive;
if (isAlive)
addToWorld(this);
else
removeFromWorld(this);
}
建議改成在setter外的method做,如:
public void kill(){
isAlive = false;
removeFromWorld(this);
}
http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html