为什么构造器是邪恶的?

本文关键字:邪恶 构造器 为什么 | 更新日期: 2023-09-27 17:54:23

我记得读过一篇关于构造函数是邪恶的文章(但不能确定)。作者提到构造函数是方法的一个特例;但是要有限制(比如不能有返回值)。

构造函数是邪恶的吗?没有构造函数,而是依赖于像Initialize这样的方法,以及成员变量的默认值,这样更好吗?

(如果你必须确定一种语言,你的答案可以是c#或Java)

为什么构造器是邪恶的?

听起来像Allen Holub。有人可能会争辩说构造函数邪恶仅仅是为了驱动网络流量:)它们并不比任何其他语言构造更邪恶。他们有好的和坏的影响。当然,你不能消除它们——没有它们就无法构建对象!

你能做的,不过,这是艾伦正在做的情况下,是你可以限制你的实际调用它们,而不是支持,在合理的情况下,工厂方法,如您的Initialize。这样做的原因很简单:它减少了类之间的耦合,并使得在测试期间或应用程序发展时更容易用一个类替换另一个类。

想象一下如果你的应用程序做了类似

这样的事情
DatabaseConnection dc = new OracleDatabaseConnection(connectionString);
dc.query("...");

,想象这发生在应用程序中的一百个地方。那么,如何对这样做的类进行单元测试呢?当您为了省钱而切换到Mysql时会发生什么呢?

但是如果你这样做:

DatabaseConnection dc = DatabaseConnectionFactory.get(connectionString);
dc.query("...");

然后更新你的应用程序,你只需要改变什么DatabaseConnectionFactory.get()返回,这可以由配置文件控制。避免显式地使用构造函数使你的代码更灵活。

编辑:我找不到一个"构造器"的文章,但这里是他的扩展是邪恶的,这里是他的getter和setter是邪恶的。

它们不是。实际上,有一种称为控制反转的特定模式,它巧妙地使用构造函数来很好地解耦代码并使维护更容易。此外,某些问题只能通过使用非默认构造函数来解决。

邪恶?没有。

调用构造函数确实需要调用"new",这将把您绑定到特定的实现上。工厂和依赖注入允许你更加动态地处理运行时类型,但是它们需要对接口进行编程。

我认为后者更灵活,但构造函数邪恶吗?这太过分了,就像所有东西都有一个界面一样。

构造函数并不坏,但(至少在Java中)通常使用静态工厂方法(当然在内部使用构造函数)更好。

下面是一些引用自Effective Java,条目1:考虑静态工厂方法而不是构造函数:

静态工厂的一个优势方法不同于构造函数,他们有名字。如果参数为构造函数没有,in和of自己,描述对象的存在返回一个静态工厂选择好的名字更容易使用和由此产生的客户端代码更容易阅读。

静态工厂的第二个优势方法不同于构造函数,它们不需要创建一个新的对象。这允许不可变类(第15项使用预先构造的实例,或按原样缓存实例建造,分配它们重复以避免产生不必要的重复对象。

静态工厂的第三个优势方法不同于构造函数,它们可以返回任意类型的对象返回类型的子类型。

静态工厂的第四个优势方法就是减少创建参数化的详细程度类型的实例。不幸的是,你何时必须指定类型参数的构造函数参数化的类,即使它们是从上下文来看很明显。这通常要求您提供类型连续两次参数:

Map<String, List<String>> m =
new HashMap<String, List<String>>();

提供的主要缺点只有静态工厂方法是这样没有public或protected的类构造函数不能被子类化。

static的第二个缺点工厂方法不是容易与其他区分的静态方法。

构造函数允许初始化列表和其他有用的东西。如果没有复制构造函数,就无法动态初始化数组(不使用指向对象的指针)中的对象。

不,他们不邪恶。

构造函数不是邪恶的。它们的存在是为了在初始化类的实例时运行代码。就像任何其他编程概念一样,如果使用不当,它们可能会成为一场灾难。但是,如果使用得当,它们可以成为一个伟大的(和必不可少的)工具。

http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)

我不会说构造函数是邪恶的

构造函数返回对你正在实例化的对象的引用,应该用来将对象设置为默认状态。我可以看到使用Initialize方法的好处,但没有多大意义。除非您需要在对象被分配堆栈空间和初始值之后初始化一些逻辑。

构造函数不是邪恶的。不管你读的是什么文章,都是错误的,你最好忘记链接。

构造函数既不坏也不好。如果在正确的上下文中使用得当,构造函数是一种非常有用的工具。事实上,至少在。net语言(如c#)中,如果你没有在代码中显式声明构造函数,编译器就会为你创建一个没有任何功能的构造函数。

构造函数在遵循正常的OO编程范例时是很好的。在某些情况下,您可能需要对对象的创建方式施加额外的约束,因此在某些情况下,带有私有部门的Factory模式可能更适合您。还有一种哲学/最佳实践认为对象实例化应该与初始化相同,在这种情况下,构造函数是除了工厂之外唯一真正的选择。

(当然工厂内部仍然使用构造函数)

这个问题可能不是关于Java或c#中的构造函数,而是关于javascript中的构造函数。在Javascript中,构造函数可能是细微错误的来源。许多Javascript书籍建议初学者避开构造函数。

有关构造函数和new关键字的更详细的讨论,在javascript中请参阅:Is javascript 's "new"关键词被认为有害?

我在某种程度上从Miško Hevery的演讲"不要寻找东西"中获得了这种氛围,该演讲可在YouTube上获得。在他给出的部分概述讨论中,我认为这是对"肥胖构造函数"的批评,如果不是对一般构造函数的批评的话。

这个参数的要点,至少在我的理解中是这样的:包含对象所需的一切的构造函数鼓励您使用构造函数来强制执行正确性,而不是通过测试来强制执行正确性。构造函数确实倾向于膨胀来完成这个任务,所以如果这让您感到困扰,您可以认为这是构造函数概念中的一个邪恶的特点。他在演讲中说,他更喜欢只在需要一个对象做某事时才要求它"拥有"另一个对象,而不是在构造时要求它。

这里有一篇文章考虑构造函数是否有害,而不是"邪恶"。这主要是在JavaScript/Es6的上下文中,但参数可能适用于任何具有构造函数的语言。

参数实际上是关于用户定义的构造函数,您仍然需要调用系统提供的默认构造函数,否则您根本无法创建任何实例。

最简单的论点是,如果您可以使用静态方法做与自定义构造函数相同的事情,那么选择其中一种方法并始终坚持下去不是更好吗,除非有特定的原因不这样做。

使您的程序总体上更简单,从而更不容易出错。注意Smalltalk从来没有"构造函数"。

https://medium.com/@panuviljamaa constructors-considered-harmful-c3af0d72c2b1