2013年10月9日 星期三

[OOP] Are getter and setter methods evil?

[OOP] Are getter and setter methods evil?

Question: 如果 class O 含有屬性 foo,該如何提供存取的方式?

class O {
    private int foo;
}

Answer: 以下提供各種從具體(concrete)到抽象(abstract)的做法與觀點

 * A1 直接將屬性的可見度提昇到 public
class O {
    public int foo;
}

破壞物件導向的基本原則:封裝
物件的狀態失去控制(如果需要檢查foo的值則要在所有客戶端檢查)
最高的耦合度(一旦class O的實作改變會影響到所有客戶端)


*A2 提供存取子(accessors) getter 與 setter 來存取屬性
class O {
    private int foo;
    public void setFoo(int foo) { this.foo = foo; }
    public int getFoo() { return foo; }
}

很好的維持資料抽象的原則(封裝資料的細節不需要客戶端操心)
物件的狀態會受到客戶端的影響
高耦合度(客戶端依賴物件的狀態)
所有的屬性都要提供存取子造成介面失控(存取子並非物件的責任)


*A3-1 只提供 getter 來詢問物件的狀態
class O {
    private int foo;
    private void setFoo(int foo) { this.foo = foo; }
    public int getFoo() { return foo; }
}

將處理屬性的細節封裝在物件之中
低耦合度(客戶端可能依賴物件的狀態)

*A3-2 某些屬性不提供存取子

class O {
    private int foo;
    private void setFoo(int foo) { this.foo = foo; }
    private int getFoo() { return foo; }
}

將處理屬性的細節封裝在物件之中,客戶端無須關心物件的狀態

A3的重點在於檢查每個屬性是否需要存取子,避免存取子的過度使用


*A4 不提供存取子
class O {
    private int foo;
}

請擁有該屬性的物件完成工作,而不是取得所有所需的狀態來完成工作。
(Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.)
如果有碰到無法使用這個規則的情況,請仔細思考物件的責任到底是什麼。
(from procedural programming to object-oriented programming)

結論

以物件導向的觀點,是否需要存取子?
存取子並非絕對邪惡的存在,但是濫用存取子存取物件的狀態很容易影響程式的彈性與易維護性。
因此最好的方式是盡可能的避免使用存取子。(仍然有例外情況:與使用者介面互動或與資料庫互動的物件)

使用的關鍵是決定於設計的抽象程度,如果想要以完成任務為優先的話是可以省略抽象化的過程(隨性的使用存取子)。
至於因為耦合度增加而造成的痛苦的維護工作就交給後人去煩惱囉:)

延伸閱讀
Tell, don't ask
http://robots.thoughtbot.com/post/27572137956/tell-dont-ask
http://pragprog.com/articles/tell-dont-ask

programming to an interface
http://www.fatagnus.com/program-to-an-interface-not-an-implementation/

Reference:

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html

http://stackoverflow.com/questions/996179/allen-holub-wrote-you-should-never-use-get-set-functions-is-he-correct
http://stackoverflow.com/questions/9212861/proper-way-of-getting-variable-from-another-class

2012年11月28日 星期三


距離被稱作"審判日"已有100個世紀
僅有少數殘存的人類生活下來
由於人類文明遭受毀滅性的打擊
世界彷彿回到蠻荒的黑暗時代

時序12012
人類文明以非常緩慢的速度在恢復
但是對於審判日前發生的事仍有許多不解之謎
考古學家挖掘出了一個不明物體
外型相當完整 造型非常精巧
上面還隱隱約約的看得見奇怪的符號"3..3..1..0.."
這次發現被當作是重要的里程碑
據悉這是在審判日前人類用來傳遞訊息的工具
學者得以藉此窺探當時人類的生活樣貌與科技文明

透過儀器分析這個重要遺產所記載的訊息:
"曾經...真愛情在我眼前 我...惜 ...悔莫及 ...最痛苦...
..上天...再來一次的機會 ...說我愛你
如果非...加一個期限的話
我希望是一萬年"

如今這個訊息穿越時空來到的一萬年後
故事中的主角早已化為塵煙
只是人生終究沒有再來一次的機會
當時的約定也來到最後期限
也許在這真愛過期之時才會發現
心痛是承認沒有人犯了不可原諒的錯誤
而這結局總不能盡如人意

這考古學家也是性情中人
只道是: 問世間情是何物 直教生死相許!

2011年12月23日 星期五

過猶不及

剛去便利商店聽到一位媽媽在聊說
她都會帶小孩去高級西餐義大利法式料理等等
學習用餐禮儀 不夠高級味道不好還不行!
(好熟悉的劇情)

感想1.
我會而且也有能力做同樣的事

感想2.
不只帶小孩吃山珍海味
也帶他去吃山間野味
可以自己摘 動手做些料理
全身弄的髒兮兮
又有什麼關係

有錢何必自以為上流瞧不起庶民生活
沒錢又何必妄自菲薄怨朱門酒肉?

世界真的不平衡嗎
其實 是不平衡的心發想 才把世界歪斜了

2011年7月16日 星期六

被生活所迫

今天洗完衣服在掛衣服時
突然想到
人的一生
大部分的時間都在為生活的細小瑣事而煩惱
即使你可能以為這些是理所當然的事
在某些人的世界裡
他們已經跳脫這個階段到達另一個層次了
除非你身旁有這樣的人
不然這件事情肯定是一個秘密

如果不努力成為有錢人
那麼這一生將一輩子"被生活所迫"
永遠處理不完的生活瑣事
沒有時間 也沒有精力 享受這人生的美好

你願意付出多少努力換取未來的幸福人生?

2011年5月11日 星期三

末日進行式

今天是511
本來是個在普通不過的日子
卻因為一場騷動而成為是芥末日
當預言的時間一過
眾人發現殘酷的現況仍在
即清醒回到現實

大地震 海嘯 隕石 傳染病 etc..
"末日"是一個單一事件嗎?
天災人禍不間斷的在世界各地發生
這一連串的影響最終才可能導致末日的來臨

但在這之前 對許多經歷災難的人而言 末日早已來到

那還沒經歷災難的人呢
做些善事 向在乎的人表達自己的愛 都不錯
請好好珍惜這短暫的時光

2011年2月12日 星期六

長大

過年時外甥跟外甥女來玩(暱稱小惡魔XD)
在UNO牌的歡笑聲中
妹妹問我 "你長大後想做什麼?"
我笑了笑想說我已經長大了啊
怎麼會問我這個 真的好可愛
妹妹好像知道了什麼又問我 "你是大人喔?"
完全沒意識到我是大人XD

但是
曾幾何時
這個問題在每個人的心中
或多或少都有不同的想法
可是隨著年齡漸長
當初純真的想法
可能早已被冷酷的現實淹沒

你還記得"你長大後想做什麼"嗎?

2010年12月11日 星期六

維夢

12/2
今天上班很沒精神
但是隔天是星期五還要上班
回到家馬上就去洗澡睡覺
睡得很熟一覺到天亮
但是在這之前做了兩個夢

第一個夢是在某個大樓等電梯的地方
在夢境中沒多久我就覺得空氣稀薄
即使打開窗戶也感覺不到任何空氣流動
就在要窒息的時候就醒了

然後買上又做了第二個夢
場景跟第一個夢一樣
在夢境中沒多久我就覺得天搖地動
晃到後來房子撐不住整個垮下來
在失去重心的那一瞬間就醒了

這麼久沒做夢
一次就兩個惡夢連發
沒什麼劇情所以記得很清楚
醒來之後餘悸猶存
有點被嚇到快哭了
躺下去後醒來就是隔天早上

難不成是演Inception?!
那我現在可能已經在limbo了吧...

熱門文章