Link to home
Start Free TrialLog in
Avatar of deleyd
deleydFlag for United States of America

asked on

OOP design. Tree of classes containing classes containing classes...

I'm tinkering with developing a Model-View-Controller design of classes. I've ended up with something like this:
        +--------Machine-------+
        v                      v
      Model                Controller
        |                      |
   +----+-----+           +----+--------+
   |          |           |             |
   v          v           v             v
 ModelA    ModelB    ControllerX   ControllerY
 data1      data2

Open in new window

Now suppose ControllerY wants to fetch data1 and data2. I could pass Machine down to ControllerY, then ControllerY could call
Machine->Model->ModelA->data1

Open in new window

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 to ControllerY, 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 and ControllerY 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 to ControllerY constructor.

I could probably figure out how to move the extraction of data1 from Machine up to Controller, maybe something like this:
private:
Machine& machine;
Data1 data1;
Controller::Controller(Machine& m) : machine(m), data1(machine.Controller.data1)
{
}

Open in new window

(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?
SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of deleyd

ASKER

Is that the same as Model-View-Presenter?
Avatar of deleyd

ASKER

As I play with my class diagram, moving to Machine -> Controller -> Model -> View,

well now I have Model controlling the View with no Controller in between.


It also hearkens back to an older question I had, which was, if I'm displaying a Menu, does the data for the Menu go in the Model?

The Menu is dependent on the screen size, and Model isn't supposed to know about the View, so Menu text doesn't go in the Model.

Likewise, Menu text doesn't go in the View, because then I have a thick View.

It was suggested to me that Menu text actually should go in the Controller.


(Are there any examples of an actual C++ OOP MVC design? (Or MVP, or anything good?))
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of deleyd

ASKER

I just read some articles on the "DCI" Data Context Interaction design pattern. Didn't fully understand the proposed solution of "injecting" code into classes.

I do see the problem is somewhere needs to go the code that handles interaction between two classes. I thought that's what the Controller was for.

Have you heard of this DCI idea?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of deleyd

ASKER

I guess there's no "correct" way of doing it. I like the idea of reorganizing the hierarchy of classes.