Your Constructors are Completely Irrational - The Code Whisperer

> "In a well-factored Java codebase, most of the code should be in constructors." This stands out as strange to me, rather in the extreme. By chance, can you point to an example? It seems to me that constructors doing most of the work in a system leads to an excess of hardwired dependencies that makes for a terrifying case of ripple effect everywhere all the time. I'd hate to try to test any part of that system on its own, except perhaps the very bottom layer. I'm happy to see a counterexample, because that would really change my worldview.

The clearest example I've found of this is in Wicket UIs, where you tend to end up with a parallel hierarchy of components that correspond to datatypes. E.g. you might have a UserEditorPanel that contains a NameEditorField and an AddressEditorPanel and the latter includes various fields. So you do new UserEditorPanel(user), and that constructor in turn calls new AddressEditorPanel(user.getAddress()) and so on. Everything does ripple up and down, but in a structured way that corresponds directly to the domain model.

You're right that this does push one away from doing conventional unit testing where one would mock UserEditorPanel (although this is largely just an artefact of Java rather than a fundamental thing, and you can use e.g. PowerMock if you really need to). But I'm coming around to a position that those kind of "middle" unit tests aren't actually as valuable as the more integrated tests that you get from my approach. Think about it in bottom-up terms: if AddressEditorPanel passes all its tests then we're happy it behaves as it's meant to. So then if UserEditorPanel fails a test, even if that test ran against the real (non-mock) AddressEditorPanel, we know the problem is in UserEditorPanel not in AddressEditorPanel. And we're less likely to get the kind of subtle bugs that happen when your mock AddressEditorPanel behaves slightly differently from the real one.

> "A constructor needs to put an object in a valid state, which it should really only have one of - if your object might be in one of several different states, you should probably be using polymorphism and instead have something that might be one of several different objects." Yes. I don't understand why this sentence followed "Nope", seeing as we agree on this and I made the first part of this point directly and, I thought, clearly in the article. Do you think we disagree on this point? If so, why?

I think we disagree because of your article's example. As originally written, the class has an invariant that the list always contains 50 Pop Questions, etc. (at least assuming the class doesn't allow outsiders to modify the lists, which it shouldn't - it would be better if it used guava's `ImmutableList` and declared the list as `final`). It's part of the game's valid state that it has those, and it's impossible to ever construct a `Game` that doesn't have those 50 questions in. By moving the adding the questions into a static factory method, you give the object more possible states, some of them invalid, and you will need to e.g. test whether the `Game` returned from some higher-level function has those 50 questions or not (a non-static factory method would at least allow you to mock/verify the correct call without needing PowerMock, though that's fairly marginal).

On re-reading the article, maybe the `Game` example was supposed to have multiple constructors? In which case I think that's the real problem, and the right solution is to split the class into `RealGame` and `TestGame` which implement the same interface, and `TestGame`'s constructor should add those test questions and `RealGame`'s constructor should not.

> Regarding "Factory", yeah, yeah... no matter what word we choose, you can find one group of people who believe that clear communication matters and we should use words consistently, so they don't like that "Abstract Factory" and "Factory Method" use the same word to mean different things -- and then you can find the other group of people whose Harley gets 40 rods to the hogshead and that's the way they likes it. I understand that with regard to this word, you're used to the extra cognitive load and don't mind.

It seems the other way around to me. I care about consistency of the meaning of words. I want the meaning of the word "Factory" to be consistent with the ordinary, English meaning of the word "Factory"; I don't want it to mean something different when we're programming from what it means in "real life". (I get equally annoyed when someone tries to insist that e.g. "story" has to mean something specific to a particular workflow: no it doesn't, it's the ordinary English word "story", if you wanted something more specific you should have coined a more specific word)

If you want to just call it personal preference that's fine, but from your "please stop calling things factories" it sounded like you were trying to get other people to change what they said.