开发者

Why are Constructors Evil?

I recall reading an article about constructors being evil (but can't place it). The author mentioned that constructors are a special case of methods; but have restrictions (such as that they cannot have a return value).

Are constructors evil? Is it better to have no constructors and instead rely on a method like Initialize, along with default values for 开发者_高级运维member variables?

(Your answer can be specific to C# or Java, if you must pin down a language.)


That sounds like Allen Holub. One might argue that constructors are evil solely to drive web traffic :) They are no more evil than any other language construct. They have good and bad effects. Of course you can't eliminate them -- no way to construct objects without them!

What you can do, though, and this is the case that Allen was making, is you can limit your actual invocation of them, and instead favor, when sensible, factory methods like your Initialize. The reason for this is simple: it reduces coupling between classes, and makes it easier to substitute one class for another during testing or when an application evolves.

Imagine if your application does something like

DatabaseConnection dc = new OracleDatabaseConnection(connectionString);
dc.query("...");

and imagine that this happens in a hundred places in your application. Now, how do you unit test any class that does this? And what happens when you switch to Mysql to save money?

But if you did this:

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

Then to update your app, you just have to change what DatabaseConnectionFactory.get() returns, and that could be controlled by a configuration file. Avoiding the explicit use of constructors makes your code more flexible.

Edit: I can't find a "constructors" article, but here's his extends is evil one, and here's his getters and setters are evil one.


They aren't. In fact, there is a specific pattern known as Inversion of Control that makes ingenious use of Constructors to nicely decouple code and make maintenance easier. In addition, certain problems are only solvable by using non default constructors.


Evil? No.

Calling a constructor does require that you call "new", which does tie you to a particular implementation. Factories and dependency injection allow you to be more dynamic about runtime types, but they require programming to interfaces.

I think the latter are more flexible, but constructors evil? That's going too far, just like having an iterface for everything goes too far.


Constructors aren't evil, but (at least in Java) often it's better to use static Factory methods instead (which of course use constructors internally).

Here are a few quotes From Effective Java, Item 1: Consider static factory methods instead of constructors:

One advantage of static factory methods is that, unlike constructors, they have names. If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name is easier to use and the resulting client code easier to read.

...

A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked. This allows immutable classes (Item 15) to use preconstructed instances, or to cache instances as they’re constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects.

...

A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.

...

A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances. Unfortunately, you must specify the type parameters when you invoke the constructor of a parameterized class even if they’re obvious from context. This typically requires you to provide the type parameters twice in quick succession:

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

...

The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.

...

A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.


Constructors allow initialization lists and other useful things. There's no way to dynamically initialize an object in an array (that doesn't use pointers to objects) without a copy constructor.

No they aren't evil.

They are special cases.


Constructors are not evil. They exist so that code can be run when an instance of a class is initialized. Just as with any other programming concept, if they aren't used right they can be a disaster to work with. But, if used correctly, they can be a great (and essential) tool.

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


I wouldn't say constructors are evil.

Constructors return a reference to the Object you are instantianting and should be used to set an object up to a default state. I can see benefits of using an Initialize method but there isn't much point. UNLESS you need to initialize some logic AFTER the object has been allocated stack space and initial values.


Constructors are not evil. Whatever article you read is wrong and you're better off having forgotten the link.


Constructors are not evil nor are they good. Constructors are a tool that can be very helpful if used properly and in the correct context. In fact at least in .NET languages such as C# if you do not explicitly declare a constructor in your code a constructor will be created for you by the compiler with no functionality.


Constructors are good when following normal OO programming paradigms. There are situations where you might need to place extra constraints on how objects are created, so in some cases a Factory pattern with private ctors might be a better fit. There is also a philosophy/best practice that says object instantiation should be the same as initialization, in which case constructors are the only real option outside factories that you have.

(factories still use constructors internally of course)


The question may not be about constructors in Java or C#, but constructors in javascript. In Javascript constructors can be a source of subtle errors. A lot of Javascript books recommend that beginners steer clear of constructors.

For a more detailed discussion of the evilness of constructors, and the new keyword, in javascript look : Is JavaScript's "new" keyword considered harmful?


I picked up this sort of vibe, to a degree, from Miško Hevery's talk "Don't look for things" which is available on YouTube. Part of the outlining discussion he gives, I interpret as a criticism of 'fat constructors', if not constructors in general.

The point of this argument, at least as I understood it, was that constructors that take in everything the object wants encourage you to enforce correctness using the constructor, instead of enforcing correctness with tests. Constructors do tend to bloat to do exactly that, so if this bothers you, you could consider it an evil streak in the concept of the constructor. In the talk he says he prefers to only require an object to 'have' another object when it's needed to do something, rather than requiring it on construction.


Here's one article that considers whether constructors are harmful, not "evil". It's mostly in the context of JavaScript/Es6 but the arguments may hold for any language which has constructors.

The argument is really about user-defined constructors, you still need to call the system provided default constructors, else you could not create any instances at all.

The simplest argument is that if you can do the same thing with static methods as with custom constructors, isn't it better to choose one of the approaches and always stick to that, except if there is a specific reason not to.

That makes your program simpler in total and thus less error-prone. Note that Smalltalk never had "constructors".

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜