【问题标题】:PHP model with too many constructor arguments具有太多构造函数参数的 PHP 模型
【发布时间】:2018-06-29 11:18:56
【问题描述】:

在我当前的项目中,我正在实现模型-视图-演示者模式。我的大多数代表域对象的类都有太多的构造函数参数。以这个为例(注意:这只是一个虚构的类,只是假设模型需要太多参数):

class Person {
    private $id;
    private $first_name;
    private $middle_name;
    private $last_name;
    private $birthdate;

    private $school_name;
    private $school_year_level;

    ... more properties

    public function __constructor($id, $first_name, $middle_name, $last_name, .. etc){
        ... some code to set the properties
    }
}

假设这个类有许多构造所需的独立值(7+ 值),我可以使用什么好的设计?这些值是从数据库中提取的行。

编辑:为了提供更多信息,我的模型有三层:

  • 模型(值对象):只是一个具有属性的域对象,可能还有一些用于最小化数据处理的方法。
  • 数据访问对象:与数据库通信。增删改查。根据获取的数据创建模型对象。
  • 服务对象:为其余业务逻辑与数据库中的数据交互提供接口。

【问题讨论】:

  • 在构造函数中使用你的对象在实例化时立即需要的参数。为其他参数使用设置器
  • 传递一个关联数组?转换所说的关联。数组 ot 一个 JSON 字符串并传递它?只传一个ID号或者类似的,在类里面做sql查询吗?
  • 我正在使用数据访问对象 (Dao) 来获取数据。它只是将其转储到此类中。
  • 到目前为止的答案并不能真正解决您的问题。他们只是把它移到别的地方。如果您使用数组,那么您仍然需要设置数组的所有值。如果你使用一个对象,它是同样的事情。无论哪种情况,您都有相同数量的参数附加到一个数据结构。让我印象深刻的一句话是“太多的构造函数参数”。你是怎么得出这个结论的?门槛是多少,为什么?在我看来,如果一个对象需要定义 7+ 个参数,那么你给它 7+ 个参数。这种结构没有任何问题。
  • 例如,您可以创建一个 Name 对象。然后名字、中间名和姓氏成为一个变量。但你最终还是要解决问题。这需要三个值并将它们组合为一个。但是在其他地方,您将不得不采用那个值并将其分成三个值。那么除了增加不必要的复杂性之外,您真正完成了什么?但我更喜欢程序性而不是 OOP,所以我有偏见。

标签: php design-patterns


【解决方案1】:

你可以使用associative array:

public function __construct($params){
    $this->id = $params['id'];
    // etc ...
}

如果您使用的是PHP 5.6+,则为spread operator

public function __construct(...$params){
    $this->id = $params[0];
    // etc ...
}

如果您使用的是 PHP 5.6,请使用 func_get_args():

public function __construct(){
    $params = func_get_args();

    $this->id = $params[0];
    // etc ...
}

我会使用关联数组解决方案,因为我更喜欢拥有键。请注意,正如@ivanivan 在他的评论中所说,还有许多其他方法可以解决您的“问题”

【讨论】:

  • 我想我可以使用这个解决方案,因为模型只是数据处理程序,实际上是带有一些方法的关联数组。我做的设计不是很糟糕吗?
  • @JuanDelaCruz 构造函数没有最大参数,这更多是关于可读性。我猜在您的情况下,7+ 参数将被视为*“糟糕的设计”,是的。我所有的解决方案都经过测试。如果您认为它回答了您的问题,请随时接受我的回答:-)
  • 对设计有什么建议吗?我有点被糟糕的数据库模式和一些我必须集成的现有代码所困扰。幸运的我:)
  • @JuanDelaCruz 正如我在回答的最后一段中所说,我将使用 associative array 解决方案。如果您编辑问题以显示如何创建此类新对象,我可以为您提供更多帮助。祝你好运;-)
  • 我创建它就像在我的问题中的类构造函数中一样。无论如何,使用数组作为参数似乎是更好的解决方案。
【解决方案2】:

我认为最好的方法是尝试将对象传递给您的构造函数

public function __constructor(User $user)

【讨论】:

  • 您想详细说明为什么这会有所帮助,$user 本身将如何构建?
  • 那么用户类呢?这不就是移动那个类的问题吗?
  • 将用户对象传递给人员对象?这真的有意义吗? ;)
  • 在 Person 和 User 的情况下,这并没有什么意义,但它可以帮助您将对象分散到许多对象上,例如 Address / User (auth properties) ...
  • 我的第一个想法是将相似的属性组合在一起作为一个单独的类。它确实在一定程度上提供了抽象并提高了可读性。但在某些情况下,别无选择,只能将数据转储到构造函数中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多