「過分」地追求 OOP 有意義嗎?

題主,不得不說,你還沒有接觸到

【過分】的追求OOP呢……


以你的例子來說,對你設置變數的需求來說是過分的,沒意義的。

但實際遵循這樣的標準是有好處的,比如設置年齡的時候對傳入數字做校驗,比如同時設置相關的其他變數。這可以把一組相關的操作都通過這個?set age來完成。


如果你的提干加上[過分]二字

那麼你其實是在引導別人做出反向選擇...

好了,正式回答一下...

面向對象是一種解題的思路...

就你的問題而言,你們老師教的沒錯...而且,私有化成員變數,使用get/set訪問就是面向對象的封裝,是一種面向對象的思維...

針對你的問題而言,我認為這麼寫是對的...

但是編程界沒有銀彈...

面向對象也不會適用於所有的場景的...

如果題主你認為寫get/set就過分了的話...

那你還沒接觸到千層餅代碼呢...


Scala 來一發 OO

mutable的

case class Person(var age: Int)

immutable 的

final case class Person(age: Int)

寫完了,很OO的,完全符合貴師要求


算是進步,談不上追求OOP,這個算不算OOP還有爭議,更不要說什麼過份。

就題目來說,Person不一定是一個對象,因為我想不出它能有什麼行為。

setAge()當然更規範一點,但並不見得是OOP的需要。

硬要就這點需求追求OOP考慮這樣吧。

class Person {

public:

void born(Date date);

int age() const;

void die(Date date);

bool isDead() const;

};


get set也叫追求oop?


在Java里這麼寫還是有必要的。因為Java語法糖不支持getter/setter方法。

為了封裝以及以後的擴展。最好還是這樣寫。

如果你用c#就不用考慮這些了


訓練oop習慣不就是最大的目的和好處么,要啥自行車。

覺得麻煩是因為站的高度不一樣,老師是為了你將來在實際項目里少犯錯啊,不按規範寫的話qa看了都忍不住要報defect了啊

setter()getter()是封裝里常用的,裡面可以限定data type,設置range,列印warning,甩exception,設定default,想加啥功能就加啥功能,而且還最大可能保證數據的正確性。

想省事直接賦值,確實能節省幾秒鐘,但後面很可能會付出幾十分鐘到幾天時間來彌補

隨便寫幾個會出現幾種情況

1.age=-1,age=3.1415926,age=1024,age=「」,age=Dog(),即使你不會犯這種錯誤,那換成用戶輸入呢?

2.項目里一個class開頭幾百個公共變數眼花繚亂,寫到後來為了不重名愣是編了一堆奇葩變數名

3.倆class里變數名一樣,沒注意選錯class,編譯通過後花了半小時找bug

4.沒有封裝,內部數據被外部隨意修改,各個方法進進出出call來call去,成何體統

5.沒有可讀性,半年後要重構一部分代碼,握著自己當初寫的東西淚牛滿面一行一行猜邏輯

不過,要是只是寫個scripe或algorithm,不考慮oop的話,確實不用

java換python想怎麼爽就怎麼爽@。@


寫這麼多行,又不是按行收費的。

java的規範把一些c++同事也帶壞了。

過度設計,煩


個人覺得每種設計都是面對一種特定問題, 但是這個特定問題一般有一定局限性.

例如你的例子中, setter and getter 可能是為了方便拓展的原因設計成這個樣子. 設計 class member 的時候, 常見的就是如下幾種:

1.

public int Age;

2.

public void setAge(int age) { ... }; public int getAge() { ... };

部分習慣 Procedural Programming 的 C/C++ 程序員特別反對 2 這種形式 -- 既醜陋又沒有帶來直接的價值. 他們的觀點是基於 message 傳值的, 反對 OOP 的 mutable shared state 的設計方法. 所以部分人比較認同 1 這種形式.

另一方面, 對於習慣按照 OOP 思維, 經過了一系列的工程經驗, 為了插入各種特殊的構造 (為了構造出類似 magic 的效果), 例如 Dependency Injection, Duck Typing, ... 總之設計變得異常複雜, 這時候為了保持 encapsulation (一定程度上隱藏了很多複雜的邏輯, 使得程序的行為變得十分難理解), 就將邏輯封裝在這個 setter and getter 下面. 這種做法是很多人爭論的焦點 (代碼複雜度和使用場景的矛盾), 也是 OOP 的問題之一 (或者是常見的錯誤設計).

總之, 每種風格都有特定的使用領域和背景, 所謂過分追求本身就是一件自己絆自己腳的做法, 僅僅為了維護程序的 "美觀和一致性" 往往得不償失.


首先,都說了「過分」,過分了當然沒有意義,你這問題就有謬誤。

其次,一方面老師是在教學,如果是你的項目經理逼著你一定要用OOP來解決問題,那你大可當他不存在,但是老師在教授課程,一定需要一定的練習。

總結來說,老師的教學中如此作為並不「過分」,因此也有其意義。


get和set裡面能做很多事情。

比如返回默認值,根據其他變數計算一個新的get結果等。

如果直接使用變數,將來修改代碼的時候你就會蛋疼了


典型的「思而不學」。學的太少的時候,知識廣度不夠,沒有全局觀,自然看不出這麼做的用意。這個例子本身,自然不用 getter setter 沒有問題。但是 Java Bean 規範要求這樣的 setter getter,很多技術是圍繞 Java Bean 來的,不用不行。舉個例子,EL 表達式從對象里取值,不是根據變數名,而是根據 getter 的寫法。所以這個不是過分 OOP 的問題,你想多了。


先回答題主的問題,*過分*追求當然是無意義的。

請題主先注意下這句話(然後自己慢慢去驗證對不對),程序世界一切反直覺現象的原因就三個字:被逼的。包括面向對象、設計模式,代碼風格、命名規範等等。越是聰明的工程師越會為自己偷懶,他們抽風了也不一定會給自己設計一籮筐枷鎖。

具體到這個例子上,形如set/get這樣的方法的意義在於:他們供了一個訪問類的成員數據的唯一的必經之路。如果有一天你發現數據不對了,靜態的分析可以直接搜這個方法名字,動態的分析可以直接在這裡設斷點(肯定能抓住臭蟲)。但是如果把數據完全暴露給用戶,設計者就再也不能預測這一數據是怎樣被修改的。直接賦值、前/後增量操作、按引用傳遞……這些都是犯罪嫌疑人。調試難度就比較大。

如果懷疑性能的話可以把這些inline了。如果是小項目,或者小作業的話,或者團隊水平十分出眾的話則完全沒必要這樣搞(linus大神不是很排斥類似c++的這一套嗎?),但是如果遇上這樣的老師還是給他點個贊吧。這樣的課程不知道比以a, aa, aaa命名變數的課程高到哪裡去了。


這樣做的好處是,當一個對象的參數設為私有屬性時,我們依然可以通過外接的函數來進行訪問和改寫。而如果不設置私有屬性,那麼就容易與其它類的對象混淆。


你們老濕的例子舉得不好。

樓上的大神都把作用說的很清楚了,不過我想題主並不是不理解oop到底是個啥,而是被get()/set()的名字迷惑了。你老濕的例子里,get()是一個取值的方法,set()是一個設值的方法。所以題主覺得一個簡單的取值和設值根本不需要搞這麼複雜,這是對的。

這個對,是建立在整個系統里,你永遠只需要用到:

age = a ;

那我們現在來換個名字:

jack.setAgeToTemplate(a) ;

這個方法現在的作用是將a賦值到jack並變成某一個template,那麼,這個template是什麼呢?作為這個方法的使用者我並不需要知道。這樣就有點oop了吧。

如果這時候再用age = a ;那你就得額外再來一把:

public void ageToTemplate(jack.a) ;

這個故事告訴我們:命名真的很重要啊。。。


我倒覺得主要是讓你們養成oop這種思想,試想一種場景,在別的類中需要修改及讀取age變數的值,如果不用get,set讀取、修改變數,必須把變數設為public,才可以對變數進行操作。這樣隨意修改的後果就是程序結構非常亂。而且這樣修改之後,私有變數和函數還有啥用。


分頁阅读: 1 2 3