OOP设计 - 性能与松散耦合

时间:2013-01-20 01:06:18

标签: php performance

我希望尽可能地改进我的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,为每个朋友ID创建一个Profile对象,然后调用运行查询($profile->getProfile($friendid))的SELECT * FROM Profiles WHERE userId = $friendid来获取朋友的个人资料。然后返回所有朋友的Profile对象的集合。

  3. 选项1缺点:我的友谊课了解个人资料。当我需要对返回配置文件的方式进行更改时(例如,我想为每个配置文件对象添加另一个属性),我需要在两个不同的位置更改它。

    选项2缺点:而不是进行1次查询(我认为应该在O(1)中运行?),现在是O(n),其中n是用户朋友的号码。

    但是选项2更清晰,松散耦合。我应该选择哪个选项?

2 个答案:

答案 0 :(得分:1)

  

选项1缺点:我的友谊课了解个人资料。和   当我需要改变一个简档的方式(例如我   想要为每个配置文件对象添加另一个属性),我需要更改   它分布在两个不同的地方。

域对象自然会有一些耦合。这只是您正在建模的系统的现实。这不是友谊和概况之间的耦合问题,而是业务层与数据层之间紧密耦合的问题。如果你有一个datamapper,finder类等,并且你的业务对象持久性无知,那么这样的改变应该不会太重要。

如果您使用第二个选项,则会遇到n+1 select problem。在这种情况下,当有更多重要的区域可以考虑去耦时,我不会牺牲性能。

答案 1 :(得分: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开始。