将变量与实例传递给构造函数

passing variables vs instances to constructor

我有一个名为 Locations 的 class,它应该接受 3 个参数名称,city_id、country_id。

传递这些值的最佳解决方案是什么,我应该传递变量或其 classes 的实例吗?

$location = new Locations('Dubai, UAE', 1, 2);
$location = new Locations('Dubai, UAE', $cityId, $countryId);

我认为为了清晰和单一责任,我应该使用依赖注入

$location = new Locations('Dubai, UAE', new City('Dubai'), new Country('UAE'));

何时以及为什么我应该使用变量 (ID) 而不是实例?

我更喜欢第二种。

使用 OOP 就是处理对象。通过传递对象,您可以询问传递的对象。

如果你传递像整数这样的基元,它是没有上下文的。传递的对象有自己的数据和逻辑,所以他自己知道最好。 int 还没有。

在你的例子中,$cityIdCity 对象的 裸数据 :你不尊重 City 对象,因为你完全传递了一个上下文无关的值。

When and why should i use variables (IDs) instead of instances?

这是您的应用程序设计的问题,您所在的层可能会有很大差异。

例如,在数据库中操作记录集,您可能只需要 id 值(非零,正整数)来对特定记录集执行操作。在这种情况下,您需要 ID。

A Location 另一方面,可能甚至不需要 ID 即可操作。

作为一个设计目标可能(应该)是,尽可能少地做必要的事情,我会说你不会将 ID 值传递给 Location 构造函数,因为否则它将依赖于这些 ID 来自的整个系统(例如数据库)。这会将数据库层甚至数据库本身耦合到 Location class.

但是 Location class 应该可以在根本不关心数据库的情况下工作。至少这样的话,你可以更灵活地利用它,让你有更进一步的发展。

这只是一些通用指针。它甚至可以更具体地实现,例如在创建类似于 Flyweight Pattern.

中概述的内容时

因此,您最好询问并测试您的设计,确保它尽可能少地完成工作。

可能有性能原因,例如,创建和传递整数值 (ID) 比实例化和传递对象值 (对象) 快得多,但并非总是如此,甚至可以忽略不计。

我想根据你的问题和我的回答澄清和评论一些事情:

  1. 变量可以是 ID(值)或实例。从技术上讲,PHP 中的对象变量就像一个 ID,它包含内存中实际对象的 ID(引用)。

  2. 您可以将构造函数视为实现细节。完成后,稍后更改它很容易,这允许您推迟细节。

  3. 我将它命名为 Location class 因为它是单数的。 class 的名称应该具有代表性,而不是误导。 Locations 听起来像是零个或多个 Location 个对象的集合。

  4. 这个问题不能完全回答,因为它取决于很多事情。为了更好地做出决定,还可以考虑 ,它显示了更多决策点。

PHP 的主要问题是假设您的参数是 City 对象,您现在依赖应用程序的其余部分来正确执行此操作。您可以在构造函数中检查正确的类型,但这不会从函数头中立即显而易见。

您正在以一种或另一种方式添加依赖性。问题是哪种形式的依赖关系最合适:

  1. 使用整数并在构造函数中构建 City 对象会导致实体 class 中与数据源(如数据库)的依赖关系,这可能会产生问题
  2. 保存整数,并包含一个接受数据库对象的函数 getCity,将创建相同的依赖关系,但更易于管理,但这意味着您现在正在传递数据库对象。
  3. 传递 city 对象意味着它必须检查或假设参数的值,因为 PHP 使用动态类型,这增加了混淆的要求,除非您有良好的文档,否则这可能很烦人。
  4. 通过城市并在 Location 中以任何方式更改它会导致问题(如果事情变得复杂,您将来很难找到错误),这意味着您的对象确实应该是不可变的。
  5. 你的位置甚至需要一个城市吗?它是用于任何操作,还是仅用于显示?在我见过的许多情况下,实际用例中对象的唯一用途是检索传递的对象的 id,这可能更容易阅读,但效率低下并且如果对象不是不可变的则容易出现问题