【问题标题】:Laravel 4 application structure: how to organize User and his Profile models using SOLID principlesLaravel 4 应用程序结构:如何使用 SOLID 原则组织用户和他的 Profile 模型
【发布时间】:2013-11-25 15:20:30
【问题描述】:

阅读许多有关 Laravel 4 的书籍,它是通过 IoC 容器使用接口和实现的结构。 所以现在所有这些信息我什么都不懂。

例如我有这样的结构:

app
-- config
-- database
-- lang
-- ...
-- logic
-- -- MyAPP
-- -- -- Controllers
-- -- -- Interfaces
-- -- -- Libraries

-- -- -- Models
-- -- -- -- User
-- -- -- -- -- Profile.php
-- -- -- -- -- User.php

-- -- -- Repositories
-- -- -- ServiceProviders

我有 User 模型和 Profile 模型,没有 User 模型就不能存在,因为它是一对一的关系。

例如我有用户界面:

interface UserInterface
{
    public function find($userId);

    public function findProfile($userId);

    public function replace($userId, $attributes, $profileAttributes);
}

实现如下:

class UserRepository implements UserInterface
{
    protected $user;

    protected $profile;

    public function __construct(Model $user, Model $profile)
    {
        $this->user = $user;

        $this->profile = $profile;
    }

    public function find($userId)
    {
        return $this->user->find($userId);
    }

    public function findProfile($userId)
    {
        return $this->profile->where('user_id', $userId)->first();
    }   

    public function replace($userId, $attributes, $profileAttributes)
    {
        //
    }
}

所以我的问题是,如果我尝试实现 UserRepository 注入两个模型 User 和 Profile 的 SOLID 原则,这是一种很好的做法,或者创建 ProfileInterface 并将其注入 UserRepository 是正确的方法,所以会有这样的事情:

public function __construct(Model $user, ProfileInterface $profile)

我无法理解的是,组织依赖项的正确方法是什么。因为我认为 ProfileInterface 应该具有所有 Profile 功能,但另一方面它不能没有用户存在,因为我们首先在表中创建用户,然后在第二个 user_profiles 表中添加它的详细信息。

在哪里存储功能会更好。用户和他的 UserProfile 功能在一个界面 - UserInterface 或单独的界面中: UserInterface 和 ProfileInterface 注入 UserInterface ?

如果 ProfileInterface 被注入到 UserInterface 我应该如何创建新用户(使用 Eloquent)?

【问题讨论】:

  • 您是否会在不加载用户个人资料的情况下加载用户?
  • 不,我将始终访问 $user,并将通过这样的关系访问他的个人资料; $user->profile->some_profile_field,其中profile是指向Profile模型的关系方法

标签: php laravel


【解决方案1】:

根据您的评论,我认为不需要ProfileRepository,因为它与User 模型有内在联系。如果您总是用他们的Profile 返回User,那么我会做一些事情-

  1. 确保User 模型与Profile 模型有关系。如belongsTo。见:http://laravel.com/docs/eloquent#relationships
  2. 在存储库中,使用User 预先加载Profile。见:http://laravel.com/docs/eloquent#eager-loading

我也不一定会在构造函数中传递User 模型。最好只将它传递给需要它的方法。

public function find($id)
{
  // returns User with Profile, if you have relationships set up
  return User::with('profile')->find($id);
}

public function save(User $user)
{
  // do some save logic here, like:
  $user->save();
}

...等等。

【讨论】:

  • 我认为,如果您以静态方式使用 User::,您将破坏 SOLID 原则之一,因此存储库的可测试性将降低。但我同意只能使用用户模型的答案。只有我有另一个问题。如何保存新用户?可以这样做: $user = $this->user->create($attributes); $user->profile->somefield = 'somevalue'; ? $user->profile->save() ???
  • Eloquent 就是这样设计静态模型的;如果您不使用该方法,则说明您没有使用 Eloquent,需要进一步设计。
  • 我读过的一本书是“Chris Fidao 的实施 Laravel”。这本书是关于使用接口的 l4 结构的。这是回购示例:github.com/fideloper/Implementing-Laravel/blob/master/app/Impl/… 他没有在他的代码中静态地使用 Eloquent。什么逻辑是对的?你的还是他的?
  • 不确定 - 跳转到 IRC 上的#laravel 并讨论!
  • l4 中的 User::... 只是一种称为 Facade 的语法糖。在幕后,它被拉出 IoC 容器,您可以在其中替换实现。laravel.com/docs/facades
猜你喜欢
  • 2016-09-21
  • 1970-01-01
  • 2015-12-02
  • 2017-08-20
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
相关资源
最近更新 更多