views:

217

answers:

3

Suppose I am developing a software for a pharmaceutical company where each 'ProductionLine' has multiple 'Stages' and each Stage has multiple 'Machines'

Now suppose I am maintaining three tables to record Stages and its Machines (leave the ProductionLine away for the shake of the discussion).

(1) Stage (Basic data which represents all possible Stages any production line can have)

(2) Machine (Basic data which represents all possible machines the production-factory can have)

(3) StageMachines (Represents a number of machines assigned for a stage)

Please note that, a stage can have multiple machines and a machine can be a part of multiple stages. But a Machine class shouldn't have a list of Stages, coz it is irrelevant accoring to the bussiness problem domain.

I have the following classes designed:

public class Stage
    {
        private int _stageId;
        public int StageID
        {
            get { return _stageId; }
            set { _stageId = value; }
        }

        private string _stageName;
        public string StageName
        {
            get { return _stageName; }
            set { _stageName = value; }
        }

        private List<Machine> myVar;        
        public List<Machine> Machines
        {
            get { return myVar; }
            set { myVar = value; }
        }

        public static bool Save(Stage stage)
        {
            //save code goes here...
        }
    }


public class Machine
    {
        private int _machineId;
        public int MachineID
        {
            get { return _machineId; }
            set { _machineId = value; }
        }

        private string _machineName;
        public string MachineName
        {
            get { return _machineName; }
            set { _machineName = value; }
        }

        public Machine()
        {
        }

        public Machine(int id, string name)
        {
            _machineId = id;
            _machineName = name;
        }
    }

Now I am facing a dillemma:

(1) When I am creating a Stage, I have to choose some Machines from all machines and save the data. How should I handle this in my code, coz then I should be able to write the following code:

Stage s = new Stage();
            s.Machines.Add(new Machine(1, "Machine#1"));
            s.Machines.Add(new Machine(2, "Machine#2"));
            s.Machines.Add(new Machine(3, "Machine#3"));

            Stage.Save(s);

(2) How should I maintain this many-to-many relationship in my code? Should I create a third class named 'StageMachine'? If I do so, how should I save the machines in when I am creating an Stage object?

Can anyone give me a solution?

*** An additional question is, when retrieving the machines of a Stage, how and where in the nTier I should do the mapping?

http://stackoverflow.com/questions/249171/what-is-a-good-design-pattern-in-c-for-classes-that-need-to-reference-other-clas

This link discusses the class design problem but don't answer the Saving and Retrieving mechanism of Machines of my Stage object in the NTier design.

A: 

You've said that

... a Machine class shouldn't have a list of Stages, coz it is irrelevant accoring to the bussiness problem domain.

Does that not mean all you need is a 1-to-many relationship from stage to machine? In that case what you've got would be enough.

Graham Miller
No.Coz I may have hundreds of machines and Stages. But When I am creating a machine object, I don't need to know which stages they belong to.
If I need to know it at any later time, I should call a method Machine.GetStages(), which should return a List<Stage>.
Yes. When I am creating a Stage object.
In case of pharmaceutical production, a machine can be a part of multiple stages.
A: 

If you do the following:

s1.Add(new Machine(1, "Machine#1");
s2.Add(new Machine(1, "Machine#1");

you will end up with two different objects representing the same machine data. Instead, you can have a List of machines or a MachineFactory that provides you with the same object reference, given a machine ID, so:

Machines.Add(New Machine(1, "Machine#1");
s1.Add(Machines[1]);
s2.Add(Machines[1]);

or

s1.Add(MachineFactory.GetOrCreate(1)); // maintains its own Machines[] internally

(Sorry if "factory" is the wrong term here. Basically you can have a static method that creates a singleton for each machine ID.)

That's all you need for many-to-many in OOP terms, since you mentioned that you don't need to traverse from a Machine to its parent Stage. A separate StageMachine class would be useful to keep your classes aligned with the relational database structure for simplicity, or to allow easier bi-directional traversal between stages and machines without needing to maintain redundant lists in both the Machine and Stage classes.

James M.
The problem with StageMachine - class is, I need to maintain seperate IDs and keep track of them, etc.
+1  A: 

Although its irrelevant to the business problem, a Machine does in fact have an association to a Stage that is best expressed by a collection. If you're using an O/R mapper, I think the easiest solution is to implement the Stage collection on Machine but don't expose it publicly. This may offer other advantages later, on such as exposing the Count property to represent how many stages a machine is used on. My solution would be something like:

public class Stage
{
    private List<Machine> _machines = new List<Machine>();

    public IEnumerable<Machine>
    {
        get { return _machines; }
    }

    public void AddMachine(Machine machine)
    {
        _machines.Add(machine);
        machine.AddStage(this);
    }

    public void RemoveMachine(Machine machine)
    {
        _machines.Remove(machine);
        machine.RemoveStage(this);
    }

    // etc.
}

public class Machine
{
    private List<Stage> _stages = new List<Stage>();

    internal void AddStage(Stage stage)
    {
        _stages.Add(stage);
    }

    internal void RemoveStage(Stage stage)
    {
        _stage.Remove(stage);
    }

    // etc.
}
Jamie Ide