在我看來,最好爲每個類創建一個文件,其中文件以該類的名字命名。我使用與乍得樺樹略有不同的符號,即Classname.class.php
。類自動加載是一個很好的功能,但我不經常使用它(只有在某些情況下,如MVC,經常添加或刪除相同類型的類)。
關於對象建模:開始爲名詞創建類。確定應用程序中的角色。這樣做的一個方法是記下你的應用程序應該做什麼,然後掃描它的名詞並在這些之後爲你的類建模。因爲一個類代表一個單獨的對象,所以大部分時候類名都是單數。如果有多個對象,你應該把它命名爲ObjectCollection或類似的東西(例如「BookCollection」)。
讓我們試試吧:
我想創建一個小本子庫的應用程序來跟蹤我的藏書。它應該跟蹤我擁有的書籍,流派,作者和我借給他們的朋友。另外,對於每個朋友都應該存儲電話號碼,所以我可以給他打電話。所有的信息都存儲在數據庫中。
Book
:代表一本書( 「教父」, 「Cryptonomicon」)
Library
:代表書籍 集合
Collection
:已經涵蓋圖書
Genre
(「Sci- 「」恐怖片「,」...「)
Author
(」Neal Stephenson「,」Mario Puzo「)
Friend
( 「喬」, 「吉爾」, 「傑克」)
PhoneNumber
(朋友的屬性)
Database
(杜)
然後你建立層次結構。哪些對象包含其他對象,它們之間的關係是怎樣的?
Library
包含0,1或更多Book
小號
- 甲
Book
屬於一個Genre
- 甲
Book
被1個或多個Author
小號
- 我可以借一
Book
爲0或1寫入Friend
並且一次只有一個Friend
- A
Friend
有一個PhoneNumber
(這也會告訴你一兩件關於你的數據庫應該如何)。
並非一切都很明顯。你真的需要電話號碼課嗎?這只是一個字符串。在這種情況下,你應該把它變成財產。此外,電話號碼並不是真的在Friend對象之間共享的(如果有幾個朋友住在一起,並且它們經常改變,但是現在這會有點矯枉過正)。如果名詞可以用一個標量值(一個字符串,整數,浮點數)表示,並且沒有其他值連接到它們,那麼創建類可能會過度。
因此,隨着時間的推移,你擴展你的應用程序。你決定不僅存儲電話號碼,而且還存儲地址。地址和電話號碼是非常相似的信息類型,因此您可以爲街道,城市,郵政編碼等添加其他變量。在某個時候,你會感到沮喪,因爲Friend
類增長巨大,有很多屬性,getters-和setters-方法,其中一些前綴將它們組合在一起(Friend->addressStreet
,Friend>addressPostCode
等)。因此,您可能決定將其重新定位到自己的類,稱爲Address
(如果您將電話號碼保留爲Friend
)或Contact
,只是爲了保持代碼清潔(沒有錯誤,但要小心)。
類層次結構和對象層次結構如何?不要混淆它們,它們是完全不同的東西!如果類似的類共享某些屬性,但是在其他屬性上不同,則會出現類層次結構。因此,您可以使用它們共享的屬性和方法以及繼承父級的屬性和方法的子類創建一個類,並添加它們自己來處理差異。
在我們的圖書館例子中,那可能是什麼?說實話,除了一件有點無意義的事情之外,我想不出任何東西,但我們不妨去想它... Friend
s和Author
s都是Person
s!都有姓名,電話號碼和地址。但他們也不同,因爲作者寫書和朋友不寫(作者通常不借你的書)。因此,您可能會定義和Address
- Person
類中的對象,但getUnreturnedBooks()
明確屬於Friend
,而getBooksWritten()
屬於Author
。
它沒有意義,因爲你永遠不會在同一運行中處理Author
s和Friend
s。但讓我們說你需要存儲在你的圖書館中的所有地址列表,你可以循環你的收藏人員,並致電getAddress()
。說實話,即使PHP是一個不好的例子,因爲你可以將任何你想要的類型一起存儲在一個數組中,並以任何你想要的方式訪問它們,但是在強類型語言中是不可能的。在Java中,你必須爲一個數組定義一個數據類型,如果它們有一個公共繼承(但你僅限於原始類的方法),則可以存儲不同的類型。足夠的那個類繼承巫術。
對象層次結構只是說明哪些對象應該包含其他對象。 A library
包含book
對象。 A book
包含一個author
對象。
的其他建議:
嘗試是描述性的。不要使用像Library->retrieveValues()
這樣的名稱,將它命名爲Library->getBooks()
,因爲Book
對象就是您所得到的。
有時最好在數據類型返回後命名方法。如果他們返回布爾值,這很常見。良好的命名約定可能是has
或is
,如Friend->hasBook($book)
或Book->isInLibraryCurrently()
。
對於某個類的所有對象來說總是相同的值可能是類常量。比方說,如果一個Person
可以是男性或女性,並且您將其存儲爲數據庫中的「m」或「f」,則可以定義類常量Person::GENDER_MALE = 'm'
和Person::GENDER_FEMALE = 'f'
,因此您沒有「m」s和「f」分散在你遍歷的SQL查詢中。
只生成單個實例的類可以建模爲單例。一個很好的例子可能是數據庫類 - 它不太可能需要一次打開多個事務。閱讀更多關於維基百科的單身人士(http://en.wikipedia.org/wiki/Singleton_pattern),但可能有點早。
更新:有些人認爲單身人士一個壞主意,因爲他們或多或少「刻在石頭上,」一旦他們實現這種方式。因此,如果您將Database類作爲單例建模,但後來決定需要多個數據庫連接(不太可能,但可能),則會出現問題。如果你冒險,單身人士可能會很方便。
類和邏輯是分開的嗎?你什麼意思? – 2009-04-17 09:30:46