The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
实例化对象,在大多数面向对象的语言中,包括Java、Ruby和C++,我们使用操作符new()
。嗯,除非我们使用静态工厂方法,但我们不使用它们,因为它们是邪恶的。尽管在我们需要时创建一个新对象看起来很容易,但我建议对这个有毒的操作符更加小心。
我相信你明白这个操作符的问题在于它耦合了对象,使得测试和重用变得非常困难甚至不可能。假设有一个文件中的故事,我们需要将其作为UTF-8文本读取(我正在使用Cactoos的TextOf
):
这个问题似乎非常简单,但问题显而易见:类Story
无法被重复使用。它只能读取一个特定的文件。此外,测试它将会非常困难,因为它只能从一个固定的位置读取内容,无法改变。更正式地说,这个问题被称为不可打破的依赖—我们无法打破Story
和/tmp/story.txt
之间的连接—它们永远在一起。
为了解决这个问题,我们需要引入一个构造函数,让Story
接受内容的位置作为参数。
现在,每个Story
的用户都必须知道文件的名称:
这并不是很方便,特别是对于之前使用“Story”的用户来说,他们对文件路径一无所知。为了帮助他们,我们引入了一个辅助构造函数:
现在我们只需要通过一个无参数的构造函数创建一个实例,就像我们之前做的那样。
我相信你对这个技术已经非常了解了,它也被称为依赖注入。我实际上并没有说什么新的东西。我想让你注意的是这三个代码片段中的new
操作符的位置和数量。
在第一个代码片段中,new
操作符都在text()
方法中。在第二个代码片段中,我们失去了其中一个。在第三个代码片段中,一个操作符在方法中,而第二个操作符则移到了构造函数中。
记住这个事实,让我们继续。
如果文件不是以UTF-8编码而是KOI8-R编码,类TextOf
和方法Story.text()
将会抛出异常。然而,TextOf
类能够读取任何编码,只需要在构造函数中有一个附加参数:
为了使Story
能够使用不同的编码方式,我们需要引入一些额外的次要构造函数并修改其主要构造函数:
这只是依赖注入,但请注意new
操作符的位置。它们现在都在构造函数中,而没有留在text()
方法中。
在我看来,这里的趋势是明显的:new
操作符在方法中停留得越久,类的可重用性和可测试性就越差。
换句话说,new
操作符是一件相当有害的事情,所以请尽量在方法中最小化使用它。确保在您的次要构造函数中实例化所有或几乎所有内容。
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-16 at 15:19