我记得读过一篇关于构造函数是“邪恶”的文章(但不知道在哪里)。作者提到构造函数是方法的特殊情况,但有一些限制(例如不能有返回值)。
构造函数真的邪恶吗?是否最好没有构造函数,而是依靠像Initialize
这样的方法,以及成员变量的默认值?
(如果必须针对一种语言进行固定,请具体到C#或Java。)
我记得读过一篇关于构造函数是“邪恶”的文章(但不知道在哪里)。作者提到构造函数是方法的特殊情况,但有一些限制(例如不能有返回值)。
构造函数真的邪恶吗?是否最好没有构造函数,而是依靠像Initialize
这样的方法,以及成员变量的默认值?
(如果必须针对一种语言进行固定,请具体到C#或Java。)
DatabaseConnection dc = new OracleDatabaseConnection(connectionString);
dc.query("...");
假设这种情况发生在你的应用程序中的一百个地方。现在,你该如何对执行此操作的任何类进行单元测试?而当你切换到Mysql以节省成本时会发生什么呢?
但是如果你这样做:
DatabaseConnection dc = DatabaseConnectionFactory.get(connectionString);
dc.query("...");
DatabaseConnectionFactory.get()
返回的内容,这可以通过配置文件来控制。避免显式使用构造函数可以使您的代码更加灵活。邪恶?不是的。
调用构造函数确实需要使用 "new",这将使您与特定的实现绑定在一起。工厂和依赖注入允许您在运行时更加动态地处理类型,但它们需要通过接口进行编程。
我认为后者更灵活,但认为构造函数邪恶?这太过分了,就像为每件事都设置接口一样太过分了。
静态工厂方法的优点之一是,与构造函数不同,它们有名称。如果构造函数的参数本身并不能描述返回的对象,那么具有良好选择名称的静态工厂更易于使用,客户端代码也更易于阅读。
...
静态工厂方法的第二个优点是,与构造函数不同,它们不需要每次被调用时创建一个新对象。这使得不可变类(第15条)可以使用预构建的实例,或者在构建时缓存实例,并重复分发它们以避免创建不必要的重复对象。...
静态工厂方法的第三个优点是,与构造函数不同,它们可以返回其返回类型的任何子类型的对象。...
静态工厂方法的第四个优点是它们减少了创建参数化类型实例时的冗长。不幸的是,即使从上下文中很明显,当您调用参数化类的构造函数时,仍必须指定类型参数。这通常要求您在短时间内快速提供两次类型参数。Map<String, List<String>> m =
new HashMap<String, List<String>>();
...
提供仅静态工厂方法的主要缺点是,没有公共或受保护构造函数的类无法被子类化。...
静态工厂方法的第二个缺点是它们与其他静态方法不容易区分。T
类型实例(而不是派生类型)或仅用于创建派生类型实例(但不是该类)的T
类型构造函数会很有帮助。您同意这个观点吗? - supercat构造函数允许初始化列表和其他有用的功能。如果没有复制构造函数,就没有办法在数组中动态初始化对象(不使用对象指针)。
它们并不邪恶。
它们是特殊情况。
构造函数并不是邪恶的。它们存在的目的是在类的实例初始化时运行代码。就像任何其他编程概念一样,如果它们没有正确使用,它们可能会成为一个灾难性的工作。但是,如果正确使用,它们可以成为一个伟大(且必不可少)的工具。
http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)
我不会说构造函数是邪恶的。
构造函数返回一个对你正在实例化的对象的引用,应该用于将对象设置为默认状态。我可以看到使用初始化方法的好处,但没有太多意义。除非你需要在对象分配堆栈空间和初始值之后初始化一些逻辑。
构造函数既不是邪恶的,也不是善良的。如果正确使用并在正确的上下文中使用,构造函数可以成为非常有用的工具。事实上,在.NET语言(如C#)中,如果您在代码中没有明确声明构造函数,则编译器将为您创建一个没有功能的构造函数。
构造函数在遵循常规面向对象编程范例时非常有用。在某些情况下,您可能需要对对象创建的方式施加额外的约束,因此,在某些情况下,使用私有构造函数的工厂模式可能更适合。还有一种哲学/最佳实践认为,对象实例化应该与初始化相同,在这种情况下,除了工厂之外,构造函数是您唯一真正的选择。
(当然,工厂在内部仍然使用构造函数)