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

时间:2017-05-18 11:41:13

标签: php oop design-patterns solid-principles

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

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

$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)而不是实例?

3 个答案:

答案 0 :(得分:1)

我更喜欢第二种。

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

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

在您的情况下,$cityId是<{1}}对象的裸数据:您不尊重City对象,因为您传递的是完全无上下文的值。

答案 1 :(得分:1)

  

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

这是一个关于应用程序设计的问题,它在你所在的层中会有很大差异。

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

另一方面,位置可能甚至不需要ID来运行。

由于一个设计目标可能(应该),尽可能少地执行,我会说你没有将ID值传递给位置构造函数,因为否则它将依赖在这些ID来自的整个系统上(例如数据库)。这会将数据库层甚至数据库本身耦合到位置类。

但是位置类应该可以在不关心数据库的情况下工作。至少如果是这样,你可以更灵活地使用它,这可以让你进一步发展。

这只是一些通用指针。它可以更具体地实现,例如在创建类似于Flyweight Pattern中概述的内容时。

因此,您应该更好地询问并测试您的设计,尽可能少地完成工作。

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

我想在你的问题和答案的背景下澄清和评论一些事情:

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

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

  3. 我将其命名为位置类,因为它是单数。班级名称应具有代表性,不得误导。 地理位置听起来像零个或多个位置对象的集合。

  4. 这个问题无法完全回答,因为它取决于很多事情。为了更好地下定决心,还要考虑the other answer,它会显示更多的决策点。

答案 2 :(得分:1)

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

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

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