
Scott Meyers wrote:
So I'm confused. Constructors that "really" initialize objects detect some kind of errors during compilation, but they make testing harder, are arguably contrary to exploratory programming, and seem to contradict the advice of the designers of the .NET API. Constructors that "sort of" initialize objects are more test-friendly (also more loosely coupled, BTW) and facilitate an exploratory programming style, but defer some kinds of error detection to runtime (as well as incur the runtime time/space costs of such detection and ensuing actions).
So, library users, what do you prefer, and why?
One-phase construction definitely! Testing in isolation is a different matter and should not degrade the interfaces. There are ways to allow isolated testing without degrading the interface. It all boils down to decoupling and isolating dependencies. My favorites: 1) Use a template where policies can be replaced by hooks to the testing engine that tests the expected results. In your example, I'd imagine this interface: template <class Printer> EventLog. 2) Use callbacks. In the example you provided, I'd imagine EventLog calls logstream to print. So, I'd use a constructor like: EventLog::EventLog(boost::function<void(std::string const&)> print) instead. So, instead of calling logstream << stuff directly, I'll call print(stuff). For the testing engine, I'll replace it with something that tests the expected results. All these falls under the "Hollywood Principle: Don't call us, we'll call you". IMO, with proper design, you can have both single phase construction *and* isolation testing. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net