I'm tinkering with developing a Model-View-Controller design of classes. I've ended up with something like this:
| | | |
v v v v
ModelA ModelB ControllerX ControllerY
Now suppose ControllerY
wants to fetch data1
. I could pass Machine
down to ControllerY
, then ControllerY
to fetch the data. However, now I have a fragile design, where I can't make any changes to the overall structure of the Model
, because Controller
relies on that structure being there.
So I thought, "Maybe Controller
should just pass data1
, since that's what it really needs. ControllerY
doesn't really need the entire Machine
class, it just needs data1
. That should make it easier to test, as I don't have to instantiate an entire Machine
class (which ironically contains ControllerY
) and pass it to ControllerY
in order to test it."
However, I came up with a problem in how to do this.
When I instantiate my Machine
class, a whole cascade of class creation happens, because Machine
has a Model
class and a Controller
class, which it instantiates; the Model
class has a ModelA
class and a ModelB
class, which it instantiates; then the Controller
class has a ControllerX
class, which it instantiates.
And I'm supposed to initialize all this in the constructors, using constructor initialization lists
. I don't see how in the Controller
constructor initialization list, to extract and pass data1
I could probably figure out how to move the extraction of data1
up to Controller
, maybe something like this:
Controller::Controller(Machine& m) : machine(m), data1(machine.Controller.data1)
(The syntax probably isn't quite correct, but the general idea is to extract it in the initialization list. Then I can pass it on to ControllerX
when it gets instantiated.)
I've discovered constructor initialization lists
are difficult to debug. There's nowhere to set a breakpoint. It all happens at once. And a whole cascade of classes being constructed all at once using initialization lists quickly becomes a big problem to debug. Especially if I anticipate making any changes in the future, I foresee endless frustration debugging the creation of these classes.
I'm trying to avoid using new
to create classes, because this isn't managed code.
So how do I avoid this problem at the design stage? What trick or design pattern am I missing?