- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我回答了一个问题(link),我在另一个类的构造函数中使用了新对象的创建,这里是示例:
class Person {
public $mother_language;
function __construct(){ // just to initialize $mother_language
$this->mother_language = new Language('English');
}
我得到了用户“Matija”(his profile)的评论,他写道:你不应该在对象构造函数中实例化一个新对象,依赖关系应该从外部推送,所以任何使用这个类的人都知道这个类依赖什么!
总的来说,我可以同意这一点,并且我理解他的观点。
不过,我以前经常这样做,例如:
ArrayAccess
接口(interface)的类),这个类将是在另一个类中使用,具有这样的对象列表,DateTime
对象,include
(或自动加载)依赖类,应该没有错误的问题,因为依赖对象的数量可能很大,将它们全部传递给类构造函数可能会很长而且不清楚,例如
$color = new TColor('red'); // do we really need these lines?
$vin_number = new TVinNumber('xxx');
$production_date = new TDate(...);
...
$my_car = new TCar($color, $vin_number, $production_date, ...............);
当我在 Pascal 中“出生”,然后在 Delphi 中,我从那里就有了一些习惯。在 Delphi(以及 FreePascal 作为其竞争对手)中,这种做法非常常见。例如,有一个处理字符串数组的 TStrings
类,为了存储它们,它不使用 array
,而是使用另一个类 TList
,它提供了一些有用的方法,而 TStrings
只是某种接口(interface)。 TList
对象是私有(private)声明的,除了 TStrings
的 getter 和 setter 之外,无法从外部访问。
请解释一下,避免在构造函数中创建对象真的很重要吗?
我已阅读 this discussion但脑子里还不清楚。
最佳答案
是的,确实如此。然后,您就清楚了构建对象需要什么。传入的大量依赖对象是一种代码异味,可能是您的类做得太多,应该分解为多个较小的类。
如果你想测试你的代码,传入依赖对象的主要优势就来了。在您的示例中,我不能使用假语言类。我必须使用实际的类来测试 Person。我现在无法控制 Language 的行为来确保 Person 正常工作。
这篇文章有助于解释为什么这是一件坏事以及它导致的潜在问题。 http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
更新
除了测试之外,传递依赖对象还可以使您的代码更加明确、灵活和可扩展。引用我链接到的博客文章:
When collaborator construction is mixed with initialization, it suggests that there is only one way to configure the class, which closes off reuse opportunities that might otherwise be available.
在您的示例中,您只能创建以“英语”为语言的人。但是当你想创造一个说“法语”的人时呢?我无法定义。
至于创建对象并将它们传入,这就是Factory
模式的全部目的http://www.oodesign.com/factory-pattern.html .它将创建依赖项并为您注入(inject)它们。因此,您可以向它询问将以您想要的方式初始化的对象。 Person 对象不必决定它需要是什么。
关于php - 为什么不是 "instantiate a new object inside object constructor"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15901861/
我想在我的单元测试中模拟一个遗留对象。这是构造函数: public Class LegacyClass{ public LegacyClass(Object... obj) {
此处说明https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function函数对象实例的构造函数属性“指定创建对
有没有办法从子类中的构造函数分配在父类(super class)中声明的实例变量?我已经习惯使用 BUILD() 作为构造函数,但我想知道这是否是个好主意。 IE: use v6; clas
鉴于以下情况: type AStruct struct { m_Map map[int]bool } 在这种情况下,AStruct的实例在AStruct.m_Map初始化之前不能使用: m_M
我是 Android 新手,我正在尝试学习如何使用 Gson 解析 API 调用。我已经阅读了一些内容,我正在尝试遵循这个示例:http://www.javacodegeeks.com/2011/01
我正在阅读 this文章,我不知道下面这行是做什么的。即使我删除了这一行,我也看不出有什么不同。 this.constructor.prototype.constructor.apply(this,A
这个问题已经有答案了: JsonMappingException: No suitable constructor found for type [simple type, class ]: can
我正在处理我的第一个 Flutter 项目,我正在构建一个登录页面,我创建了一个变量来存储一个 TextFormFieldController,但我收到了上面的错误,因为我删除了构造函数。当我返回这个
假设我们有以下主要和次要构造函数: open class Animal(val name:String){ internal constructor(message:InputStream): t
为什么默认复制构造函数不调用 monster 的基构造函数,但是当我在 troll 中包含一个用户定义的复制构造函数时,它会调用父级(即: 怪物) 构造函数? 我认为它的工作原理如下:创建基础对象,然
这个问题在这里已经有了答案: Is there a difference between foo(void) and foo() in C++ or C? (4 个答案) 关闭 8 年前。 我注意到
我将 T4MVC 与 MVC2 一起使用。 我有以下构建 block : 一个简单的实体接口(interface),它定义了每个 POCO 实体必须有一个 long Id属性(property): p
以下代码返回一个错误: “构造函数调用必须是构造函数中的第一个语句。” 我不明白。我的代码中的构造函数是第一条语句。我究竟做错了什么? public class labelsAndIcons exte
我是 kotlin 的新手,对它包含的所有有用的语法糖和功能感到惊讶。 但是每当我声明一个构造函数时,我都必须独立地将我的所有字段设为私有(private)。 class Result(private
作为主题,相关代码为: #include class ABC { public: ABC() { std::cout<< "default con
在 Haxe 中,我创建了一个名为 的类。我的类 喜欢: class MyClass { var score: String; public function new (score:
不确定为什么会这样,尝试删除所有 new 实例,从 const ect 切换到 let。可以运行站点,但是当我通过 html 表单运行发布请求时,在“const user = new UserSche
我是 Javascript 的新手,我正在尝试深入挖掘并理解继承、构造函数和原型(prototype)链。所以,我创建了一个构造函数, var a = function(){this.integer=
我知道 JavaScript 中的函数有双重生命,第一个是函数(作为创建实例的第一类事物),第二个是普通对象。 但是我很惊讶地看到下面控制台的输出。 function A() { consol
这个问题在这里已经有了答案: Why can't I access a property of an integer with a single dot? (5 个答案) 关闭 5 年前。 为什么
我是一名优秀的程序员,十分优秀!