I am creating a main object, MACHINE, which will contain a diversity of several other objects -- AXIS, AMPLIFIER, ENDEFFECTOR, etc. The number of contained objects will vary depending on the MACHINE model object that I am using.

For example, a certain machine might have one AXIS and one ENDEFFECTOR; another 3 AXIS and 2 ENDEFFECTORS, etc.

I was planning to create subclasses with each machine model, and initialize the respective number of contained objects depending on the model. My fear is that there is going to be an explosion of machine models, as well as quite a lot of repeated code and settings among subclasses.

I get the feeling that there is a cleaner way to implement this, but I am not sure how to. Any ideas will be greatly appreciated.

  • 1
    a machine that is merely a collection of parts doesn't sound very useful, unless you're just building an inventory system - will anything else be done with the parts of each machine? Jul 9, 2011 at 1:11
  • @Steven: Mainly the machine is a design for a CNC machine. So, the core functionality is joging different axes in the machine (continuous and step mode), turning on the end effector (spindle, plasma, etc.), changing tools (combination of previous + spindle control), and the most fundamental is to run toolpaths (e.g. gcode files), which is able to use all functionality in a single run. So, to summarize, machine would have methods such as continuousjog, stepjog, loadtoolpath, runtoolpath, etc...
    – Peretz
    Jul 9, 2011 at 2:12
  • Are you doing a simulation, or an actual controller for CNC? I'm asking, because controlling high speed precision machinery may require a real time operating system.
    – Mchl
    Jul 9, 2011 at 12:48
  • @Mchl: I am designing an actual controller, and yes, you are right, speed might become an issue. Most of the application side (which is my job to design) will offshore the machine control commands to a custom circuit. Our current system runs in a PC, and it does not have speed problems. But we need to keep an eye on that too.
    – Peretz
    Jul 9, 2011 at 13:02
  • @Peretz: I think you have to add some more detail. For example, is the loadtoolpath() function machine-specific, or it can be generalized for every machine? More specifically, it is not clear what it is going to change from one machine to the other (just the number of end-effectors, or also their type? and you always use an end-effector in the same way, or how the machine use the end-effector depends also on the end-effector?)
    – knulp
    Jul 13, 2011 at 18:49

1 Answer 1


I would keep this with a single machine class which holds a vector or list of items. To initialize it you can either hardcode the initializing process by using something like an addPart() method or using a init file for each machine type and add a method (or constructor) that can read such init files.

So first version would look something like this: (assuming all machine parts are sub of a base class like Part)

Machine* smallMachine = new Machine;
smallMachine->addPart(new Axis);
smallMachine->addPart(new Amplifier);

Or you could have methods for each possible type of part:

Machine* smallMachine = new Machine;

The second would simply use a filename for the constructor:

Machine* smallMachine = new Machine("/home/machines/small_machine.ini");


There are many ways to handle this inside the machine class and it mainly depends on what the parts actually can do and how much the Macine class knows about them.

Assume the machine know near to nothing about the parts, only that they can do something and will later only start each part once in a loop. In this case you could simply write a pure virtual base class Part;

class Part
     virtual void work() = 0;

All classes that derive from Part must overwrite the work() method and that way implement their functionality. Machine knows nothing else and can use a simple vector of parts.

class Axis : private Part
    virtual void work(){
        // implement actual functionality
        // may call lots of private methods of Axis to do this

If this doesn't work for you, it is in fact a better solution to keep several containers for each type of part. This especially if you plan to have some specific interactions between parts.

If you use the ini solution, this wouldn't change much compared to the method solution, since after all, the constructor would need to call similar functions when evaluating the ini files content.

The virtual base class is the one that would need the least changes in case you add new parts. None at all in best case. But it would be limited to the method (or several methods) that are declared in Part.

The solution with different containers and more knowledge by Machine would need to be updated whenever you add a new type of part or add new functionality to a part. But if you need Machine to know specific details of parts, you won't get around this anyway.

edit: From your comment above about implementing a CNC control system I would think, that you need a more complex structure. Maybe you should have a look in some good book about design patterns. I think this would be worth your time. As it looks each part would implement quite different kinds of functionality and they may even depend on each others state.

  • Thanks for the answer. Two quick observations: 1) How would I differ between the different items in the vector or list? shouldn't I create several different item repositories? (e.g. axis_vector) 2) If the ini file constructor is used, any new machine configuration wouldn't have to be updated within the class? wouldn't the class be more prone towards changes? Thanks
    – Peretz
    Jul 9, 2011 at 2:01
  • I have already started looking at some OOA&D books and design patterns (GoF). But, as you mentioned it, it is quite complex to have a clean initial sketch. Maybe, I should put a post with some UML class diagrams and the problems I am having. In order to see what the community thinks about it.
    – Peretz
    Jul 9, 2011 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.