Boost logo

Boost Users :

From: Joel de Guzman (joel_at_[hidden])
Date: 2006-09-12 19:10:33


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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net