2013-01-20 128 views
1

我期待儘可能地改進我的OOP代碼設計,但我在這個問題上停滯不前。OOP設計 - 性能與鬆散耦合

例如,我想要獲取社交網站中用戶的所有朋友的個人資料。所以我有表FriendshipsProfiles。我有類FriendsProfile

Friends成爲處理用戶友誼的類,Friends::getFriendsProfiles()成爲獲取並返回所有用戶朋友的配置文件的函數。

所以我的功能Friends::getFriendsProfiles()裏我可以做一個

  1. 一個表連接 (例如SELECT * FROM Friends LEFT JOIN Profiles ON Friends.user2 = Profile.userId WHERE Friends.user1 = :userid),或

  2. 我就可以獲取的朋友的用戶ID,創建一個Profile對象爲每個朋友ID,並且呼叫$profile->getProfile($friendid)運行查詢(SELECT * FROM Profiles WHERE userId = $friendid)以獲取朋友的個人資料。然後返回所有朋友的集合Profile對象。

選項1缺點:我的友誼類知道配置文件。當我需要在返回配置文件的方式上進行更改(例如,我想向每個配置文件對象添加另一個屬性)時,我需要在兩個不同的位置對其進行更改。

選項2缺點:而不是做1個查詢(我認爲應該運行在O(1)?),現在是O(n),其中n是用戶的朋友的數量。

但是選項2非常乾淨和鬆散耦合。我應該選哪個選項?

+1

你不是在編寫獨立服務的框架或庫。你正在編寫一個模擬緊密耦合的真實世界情況的應用程序。現實世界如何更緊密地耦合在一起? – markus

+0

這個問題是關於SQL,與OOP或應用程序設計完全無關。 –

+1

從我的觀點來看,有兩個建議:* 1)*我猜你先創建了數據庫表,然後建立了模型,不是嗎?雖然這種方法是有效的,但它通常會導致一個模型,其責任不明確,就像你的情況一樣。也許你應該嘗試先創建模型。然後我很難看到一個「朋友」班,因爲什麼是朋友?我相信一個朋友不是別的'User',所以'friends'是一個(可能是* n:m *)關聯,並且沒有任何類。 * 2)*您應該評估一個ORM(對象關係映射器)的用法,以便您不必擔心SQL。 – Desty

回答

1

選項1缺點:我的友誼班知道配置文件。並且 當我需要在返回配置文件的方式上進行更改(例如,我想要爲每個配置文件對象添加另一個屬性時,我需要在2個不同的位置更改 )。

域對象自然會有一些耦合。這只是您正在建模的系統的實際情況。這不是友誼和簡介之間的耦合問題,它是業務層和數據層之間緊密耦合的問題。如果你有一個數據映射器,查找器類等,並讓你的業務對象永遠無知,那麼這樣的變化應該不會太重要。

如果您使用第二個選項,則會遇到n+1 select problem。在這種情況下,當有更重要的領域可以考慮解耦時,我不會犧牲性能。

1

我一定會選擇1,只使用1查詢。 如果構造函數可以使用數組,則Friends類必須對Profiles不太瞭解。 你可以這樣做:

SELECT Profiles.* 
FROM Friends 
LEFT JOIN Profiles ON Friends.user2 = Profile.userId 
WHERE Friends.user1 = :userid 

然後在循環:

$profiles = array() 
while ($data = mysqli_fetch_assoc($result)){ 
    $profiles[] = new Profile($data); 
} 

一個也許更清潔的解決方案是使之成爲Profile類的方法。

Profile::getFriendsProfiles() 

循環:

$profiles = array() 
while ($data = mysqli_fetch_assoc($result)){ 
    $profiles[] = new self($data); 
} 

Profile的構造可能是:

function __constructor(array $data = null) 
{ 
    if (null !== $data) { 
     // fill properties 
     $this->id_profile = $data['id_profile']; // example 
     ... 
    } 
} 

這將是更好,如果SQL代碼將是另一個對象Table Data Gateway。 如果你真的想改善你的OOP,那麼請閱讀軟件設計模式。 您可以從Martin Fowlers的網站here開始。