2013-03-14 45 views
8

目前,我有完全符合程序PHP寫了一個相當大的應用程序。我正在尋求進一步提升我的PHP體驗,並使用面向對象技術重新編寫我的大部分應用程序。程序轉換成PHP的面向對象的PHP

OOP有很多領域可以幫助減少代碼量並使其更易於閱讀。但是,我有幾個問題。

1)這是我的理解,一個類被用作任何數量的對象的藍圖,但任何一個類只代表一個對象,從不超過一個。所以一個班級可以代表一個球員,但不會有多個球員。

2)因爲我有好幾個不同的類別,包括,是否使用「裝載機」類使用spl_autoload_register加載它們都還是我只是用在程序文件spl_autoload_register我的應用程序?

編輯:所以我的自動加載磁帶機將是一個類,我再創建一個實例來啓動自動加載或只是功能和spl_autoload_register,我想納入爲避免重複在多個文件中相同的代碼的PHP文件?

3)我的一些類依賴於其他類。我從來沒有遇到過這個,所以我真的不知道答案。如果我包括我的主程序文件中的所有類,但我的播放器類並沒有包括它需要的功能,會因爲主程序球員類的工作包括哪些球員依賴於類的類?

編輯:因此,即使一個類可以實例類型的球員的對象,Player類不是直接由這個類包括,它仍然會正常工作,因爲控制器類包括Player類?

4)有多種情況下我需要處理我創建的對象。我想知道我該怎麼做。例如,在我的Player類中,我有時需要從一個Player發送一些東西給另一個Player。那麼,我是否需要在Player類中實現一個靜態方法,該方法以兩個參與者作爲參數進行傳輸,或者執行其他操作?

編輯:好的,所以避免靜態方法。現在我遇到了一個嚴重的問題:我的應用程序中有多次運行的方法,但我無法將它們作爲靜態方法實現。我是否應該將它們實現爲實例方法?例如,從一個玩家發送到另一個玩家。我會創建一個實例方法,它需要一個Player對象併發送它或呢?

5)我有很多方法不屬於某個類的任何一個實例,它們也不適合作爲靜態方法。這些應該作爲普通還是類似的靜態方法在自己的類中聲明?在這種情況下在實踐中做了什麼?

編輯:是將這些方法都屬於在其中使用它們或者是存儲在自己的「的functions.php」文件中的特定應用程序文件?

6)我想學習如何使用名稱空間,但我的代碼永遠不會被別人使用,我永遠不會在我的應用程序中使用其他人的代碼。名稱空間在我的應用程序中是不是一個無意義的添加,或者學習如何使用它們會是一個好主意嗎?無論如何,一個應用程序是否有一個名稱空間(應用程序名稱?),還是每個類都屬於它自己的名稱空間?

7)最後,是它通常具有數據庫連接一類,也爲網絡方法的類?我的應用程序需要。我認爲我將代碼轉換爲使用面向對象技術的主要問題是確定將哪些方法放在哪裏,因爲目前它們都放在一個整體文件中。

感謝您提供的任何幫助和見解。

回答

2

1)這是我的理解是一類被用作任意數量的對象的藍圖,但任何一類代表了一個對象,絕對不會超過一個。所以一個班級可以代表一個球員,但不會有多個球員。

通常情況下,你也將有代表集合對象類,例如可以使用的一類「玩家」來檢索所有玩家的收集單個玩家:

$players = new Players(); 
$john = $players->findByName("john"); 

2)由於我有好幾個不同的類別,包括,我用一個「裝載機「類使用spl_autoload_register加載它們,或者我只是在我的應用程序的程序文件中使用spl_autoload_register?

這幾乎取決於您的項目的複雜性。一個簡單的自動加載器功能通常會很好,但你可以看看Zend Framework Autoloader class

3)我的一些類依賴於其他類。我從來沒有遇到過這個,所以我真的不知道答案。如果我在主程序文件中包含了所有的類,但是我的玩家類不包括它需要運行的類,那麼由於主程序包含了玩家依賴的類,所以玩家類會工作嗎?

是的。但是,通過自動加載,您無需擔心這一點。如果不使用自動加載,最好在定義類的文件中包含所需的類(使用require_once()避免多次包含同一文件)。

4)有多種情況需要處理我創建的對象。我想知道我該怎麼做。例如,在我的Player類中,我有時需要從一個Player發送一些東西給另一個Player。那麼,我是否需要在Player類中實現一個靜態方法,該方法以兩個參與者作爲參數進行傳輸,或者執行其他操作?

靜態方法幾乎都是錯誤的做法。普通方法屬於一個實例(即特定的玩家),靜態方法屬於該類,即玩家的一般「想法」。如果你需要從一個球員轉會的東西到另一個,爲什麼不實現這個是這樣的:

class Player { 
    public function transferMoney(Player $recipient, $amount) { ... } 
} 

$tom = new Player("tom"); 
$marc = new Player("marc"); 

$tom->transferMoney($marc, 500); 

5)我有很多並不真正屬於一類的任何一種情況,也沒有方法他們真的適合作爲靜態方法嗎?這些應該作爲普通還是類似的靜態方法在自己的類中聲明?在這種情況下在實踐中做了什麼?

我不能合理地回答這個問題。但是,PHP中仍然有普通的函數,這似乎是這種情況下最好的方法。然而,如果你正確地做OOP,你很可能永遠不會遇到這樣的問題。這通常是你的類設計的一個問題,這使得你的這些方法不屬於任何對象。

6)我想學習如何使用名稱空間,但我的代碼永遠不會被別人使用,我絕不會在我的應用程序中使用其他人的代碼。名稱空間在我的應用程序中是不是一個無意義的添加,或者學習如何使用它們會是一個好主意嗎?無論如何,一個應用程序是否有一個名稱空間(應用程序名稱?),還是每個類都屬於它自己的名稱空間?

命名空間很好,但是如果沒有它們,你的代碼可能會很好。由於名稱空間可以嵌套,因此每個組件通常會有一個頂級名稱空間和子名稱空間。

7)最後,是它通常具有數據庫連接一類,也爲網絡方法的類?我的應用程序需要。我認爲我將代碼轉換爲使用面向對象技術的主要問題是確定將哪些方法放在哪裏,因爲目前它們都放在一個整體文件中。

這取決於你如何模擬你的實際情況。如果數據庫連接和「網絡」對你來說是兩件不同的事情,那麼兩類是要走的路。

+0

感謝您的回覆!你的#1和#4 *真的有助於澄清事情!對於我的應用程序來說,玩家集合絕對有意義,並且使用實例方法傳輸項目也非常有意義。我會聽取大家的意見,遠離靜態方法。 – 2013-03-14 22:51:27

4

1)我的理解是,一個類用作任何數量對象的藍圖,但任何一個類只代表一個對象,不會超過一個。所以一個班級可以代表一個球員,但不會有多個球員。

一個類不表示任何東西,因爲正確地說它只是任何數量的對象的藍圖。您可以擁有多個代表多個玩家的同一類的多個實例(對象)。

2)由於我有好幾個不同的類別,包括,是否使用「裝載機」類加載它們全部採用spl_autoload_register還是我只是用spl_autoload_register在程序文件爲我的應用程序?

不知道你的意思是「我的應用程序的程序文件」我說是的。使用自動加載器,因爲它可以正常工作,您不必擔心require_*

3)我的一些類依賴於其他類。我從來沒有遇到過這個,所以我真的不知道答案。如果我在主程序文件中包含了所有的類,但是我的玩家類不包括它需要運行的類,那麼由於主程序包含了玩家依賴的類,所以玩家類會工作嗎?

你不想加載所有的類,但只是你要使用的類。在使用自動加載器時,您再也不用擔心這一點。但是,一旦加載了一個類,它可以在整個應用程序中實例化。

通常情況下,您會想要啓動bootstrap phase of the application中的自動加載程序。

4)有多種情況需要處理我創建的對象。我想知道我該怎麼做。例如,在我的Player類中,我有時需要從一個Player發送一些東西給另一個Player。那麼,我是否需要在Player類中實現一個靜態方法,該方法以兩個參與者作爲參數進行傳輸,或者執行其他操作?

避免在OOP PHP中使用靜態方法。這幾乎是不需要的。你可以考慮讓另一個類似一羣玩家的類來照顧從一個玩家到另一個玩家的「發送數據」。

因此,只要在嘗試實例化文件之前就已經包含了包含該類的文件就不重要了。

5)我有很多方法不屬於某個類的任何一個實例,它們也不適合作爲靜態方法。這些應該作爲普通還是類似的靜態方法在自己的類中聲明?在這種情況下在實踐中做了什麼?

請再次請勿使用靜態方法。如果你在其他類中使用它們,你只會使單元測試你的類變得很困難,並引入隱藏的依賴關係。在我的經驗幾乎從來沒有碰巧只是有一個方法某處的東西。也許你的方法做得太多了。

但是,通過閱讀您的問題很難說。也許你可以在評論中舉個例子嗎?

6)我想學習如何使用名稱空間,但我的代碼永遠不會被別人使用,我絕不會在我的應用程序中使用其他人的代碼。名稱空間在我的應用程序中是不是一個無意義的添加,或者學習如何使用它們會是一個好主意嗎?

PHP中的命名空間是關於結構化的。雖然沒有人會使用你的代碼,但你不必擔心在某個地方爲某個類使用同一個名字。一旦應用程序變得越來越大,比以後更快,這將會發生。

無論如何,一個應用程序是否只有一個名稱空間(應用程序名?)還是每個類都屬於它自己的名稱空間?

當談到命名空間時,我經常關注PSR-0

7)最後,是它通常具有數據庫連接一類,也爲網絡方法的類?我的應用程序需要。我認爲我將代碼轉換爲使用面向對象技術的主要問題是確定將哪些方法放在哪裏,因爲目前它們都放在一個整體文件中。

只要保留Single Reponsibility Principle記住和一般SOLID

而且我強烈建議看these,並保持觀望,直到你明白。

+0

感謝您的優秀文章。我做了一些修改,以澄清我的問題。你可以看一下嗎? :) – 2013-03-14 22:44:41

+0

這是我目前使用的一種簡單方法。爲一種方法創建一個類沒什麼意義,所以它屬於哪裏? 'public function getCurrentTime(){return round(microtime(true)* 1000); }' – 2013-03-14 22:59:27

+1

我不認爲我會創造這麼簡單,我認爲事情的方法。 – PeeHaa 2013-03-14 23:04:09

1
  1. A PlayerCollection將是一個有效的類。當然它的一個對象是一個集合了多個玩家。

  2. 使用spl_autoload_register,期。最好遵循PSR-0標準,並使用任何符合PSR-0標準的現有自動裝載機(即Symfony Loader

  3. 它將起作用。但是由於您使用自動加載器(請參閱2。)你不必在意,包括在所有

  4. 類從播放器1發送消息給玩家2在播放器。然而調用播放器2的方法是很容易翻譯,「送東西」和「工作對象「可能意味着很多事情,所以答案是:這取決於。但總的來說,這是一個很好的建議避免靜態方法

  5. 這聽起來很像程序性思維。對不起,但我不能在這裏給你一個銀色的子彈答案,你將不得不學習和理解面向對象設計的原則來應用它們。網絡上有一些標準文獻和大量有用的資源。還可以通過示例進行學習(查看其他OO應用程序和開源框架)

  6. 「一個應用程序是否有一個名稱空間(應用程序名稱?)還是每個類都屬於它自己的名稱空間? - 答案介於兩者之間。命名空間對於將一起工作的東西組合在一起非常有用,無論誰將使用或查看代碼,它們都很有用。

  7. 面向對象設計的第一條規則:一個班級,一個責任。

+0

感謝您的發佈。我對我的問題做了一些編輯以反映你的答案。你的#1真的爲我澄清了一些事情。我從來不認爲玩家集合將是非常有用的,但它有一定道理,它可以,如果你有這方面的具體需要來完成。 – 2013-03-14 22:47:53