2013-05-04 13 views
4

使用類作爲方法集合開始使用面向對象的PHP是明智的嗎?這種方法有什麼缺點嗎?通過使用類作爲方法的集合OOP開始?

我知道OOP遠不止這些,但是我的PHP項目太小,無法利用OOP所提供的所有功能。另一方面,我的項目變得太大而無法通過程序編程來更新/維護。

我看了一下OOP很多話題和偶爾有人說「面向對象不僅僅是一種收藏功能多」(或東西沿着這些路線)。這讓我想:這可能是事實,但也可能是我通過這樣做最終進入OO編程世界的機會。

所以,這是一個聰明的第一步,真正開始使用和學習OOP?還是有我需要知道的嚴重缺點?

+2

如果它可以幫助你編寫更好的代碼,爲什麼不呢? – phant0m 2013-05-04 11:47:58

+1

這不是面向對象的編程(完全),即基於調用的編程。您可能想了解[實用模式](http://c2.com/cgi/wiki?UtilityPattern)並查看[實用程序類是邪惡的?](http://stackoverflow.com/q/3340032/367456) - 請記住,不同的編程語言有不同的需求。在PHP中,您應該瞭解靜態和動態方法調用的不同之處。 – hakre 2013-05-04 12:01:24

+2

如果你想採用這種方法,只需獲得一本[關於重構的好書](http://martinfowler.com/books/refactoring.html),並應用你學到的東西。你最終會寫出更好的代碼。 – Yoshi 2013-05-04 12:09:44

回答

1

OOP基本上只是一套方法。但是在編程中思考是不同的。在類中,你封裝了類似的funcionality。代碼更具可讀性,您不需要一遍又一遍地寫入相同的功能。它也更安全(私人成員),如果你正在編寫圖書館,最終用戶只能改變你想要的東西等。 因此,我不會建議嘗試繞過使用功能集的OOP,而是使用真正的OOP。沒有理由不。

1

我不建議,你會習慣寫掩蔽爲OOP,這是不是真的,你想要的程序代碼。開始時可能很難,但要學習面向對象的所有功能,閱讀模式,強調編碼標準,最重要的是使用面向對象體系結構研究應用程序。

2

你的問題真廣,但它值得一個簡單的答案,你可以記住並保持與你,而你繼續你的旅程到面向對象的分析和設計(OOAD)的世界。

那麼,這是真正開始使用和學習OOP的第一步嗎?還是有我需要知道的嚴重缺點?

你可以想象,我們不可能直接回答這個問題。什麼是聰明的,什麼不取決於我們自己的許多能力。例如。對於某些人來說,它可能很聰明,因爲它可以幫助他們儘早地制止錯誤,這是一條路。對於其他人來說,這可能是徹頭徹尾的災難,因爲他們沒有發現任何錯誤,繼續開發軟件,因爲他們認爲:如果我沒有發現錯誤,這是完全正確的。

那麼如何解決這個困境呢?很簡單,我們在OOP中有兩個部分,您可以輕鬆瞭解並與您保持聯繫。第一種叫做S.T.U.P.I.D. - 你可以想象這是什麼意思,如果事情屬於這一類,第二個被稱爲S.O.L.I.D.它同樣是自言自語,如何對待那裏的一些東西。

+0

我的廣泛的問題值得「它取決於」--answer。感謝您與易記的指南鏈接。 – Abe1984 2013-05-04 12:55:29

2

聲明:我還沒有處理過的,而PHP的,所以我的語法可能是錯誤的。

術語OOP有點模糊imo,這意味着不同的人在聽到它時會想到稍微不同的東西,所以當你聽到矛盾的事情時不要混淆。

使用類一起構造類似的函數不會損害你的代碼,但是你基本上只是使用類作爲函數的名稱空間。通常情況下,您需要以某種方式定義類,以便您的系統的某個方面進行封裝,這意味着只有該類的代碼纔會直接處理該方面,而其他人則只使用該類。

例如,您可以有一個管理打印作業隊列的類。如果您有一些想要打印文檔的代碼,則它不必知道作業排隊或如何發送到打印機,它只需知道打印作業隊列對象(我們稱之爲$jobQueue ),它可能有一個像$jobQueue->enqueue($document)這樣的方法。

現在你可能會說:「那代碼也可以同樣使用全局函數enqueueJob($document),」直到你想有一個以上的隊列(對於不同的打印機)是真的,並以不同的方式工作隊列(將作業存儲在數據庫中,存儲在內存中或根本不存在 - 想象一下直接進入回收站的隊列:))。使用OOP,這種場景是沒有問題的,並且這些細節完全隱藏在想要打印文檔的代碼中 - 所有它必須關心的是它有一個帶有enqueue方法的作業隊列對象。

爲了獲得這種作業隊列的「互換性」,他們需要有一個通用的接口(在這種情況下,這種方法是enqueue方法),必須仔細選擇它以涵蓋想要打印的代碼的所有需求的東西,但沒有對打印隊列的工作方式做太多的假設。例如,您可以想象enqueue方法將文件路徑作爲參數告訴隊列將文件存儲到哪裏 - 但該接口對於在數據庫上運行的隊列無用。這是找到好的抽象藝術

現在回到你原來的問題,只要沒有考慮到新類應該提供哪些抽象/接口,就把相關函數組合到一個類中,並不是真正的OOP。沒有這一點,所有使用這個新類的代碼將被硬連線使用,如果您決定需要不同類型的打印機隊列,則需要更改/重新檢查。 :)

但是,「不是OOP」是不一樣的「不是一個好主意」。我說去做,重新安排你的功能。在我看來,重要的是要記住,並非每件事都需要成爲一個對象或適合某種抽象。但是也許你會發現你確實有一些功能可以完成類似的功能(文件隊列,數據庫隊列),這些功能可以抽象成一個通用接口。

+0

非常感謝。你的回答不僅爲我闡明瞭「抽象」和「界面」,而且也使我確信自己的方法正確。 – Abe1984 2013-05-04 13:32:12

0

有些東西是功能性的,程序性的和基於對象的。使用最適合這種情況的那種。這個哲學你不會有太大的錯誤。

0

由於這個問題是不是真的有關的PHP,但一般的面向對象,這個答案應該是有效的許多語言。

OOP中存在不同的模式。我建議閱讀關於「四人幫」的文章。這是一本非常好的書,它解釋了在做OOP時可以使用的一些最基本的模式。

您應該考慮將所有函數存儲在命名空間中,而不是使用類來保留一組靜態函數。

類通常定義對象(如物理對象)。任何物理對象都有一組屬性和行爲。

當設計一個類時,你試圖定義這些行爲和屬性。例如,一個包。

class Bag: 
    // Methods 
    function open: ... 
    function close: ... 
    function empty: ... 
    function add(item): ... 
    // Properties 
    array items: [] 
    bool is_open: false 

某些屬性或方法可以隱藏或可見的世界。在我的例子中,當你嘗試清空或添加一個對象到一個封閉的包裏時,你可以使函數add拋出一個異常。很顯然,這裏的所有方法都與實際對象有關。

添加與包無關的方法或屬性應該屬於不同的名稱空間或類。這真的取決於你想要做什麼。