2

假设我正在为一家制药公司开发一个软件,其中每个'ProductionLine'都有多个'Stages',每个阶段都有多个'Machines'

现在假设我正在维护三个表来记录阶段及其机器(将生产线留在讨论中)。

(1) 阶段(代表任何生产线可能具有的所有可能阶段的基本数据)

(2) 机器(代表生产工厂可以拥有的所有可能机器的基本数据)

(3) StageMachines(表示为一个阶段分配的机器数量)

请注意,一个阶段可以有多台机器,一台机器可以是多个阶段的一部分。但是机器类不应该有阶段列表,因为它与业务问题域无关。

我设计了以下课程:

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;
        }
    }

现在我面临一个困境:

(1) 当我创建一个舞台时,我必须从所有机器中选择一些机器并保存数据。我应该如何在我的代码中处理这个问题,因为我应该能够编写以下代码:

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) 我应该如何在我的代码中维护这种多对多的关系?我应该创建一个名为的第三类'StageMachine'吗?如果这样做,在创建 Stage 对象时应该如何保存机器?

谁能给我一个解决方案?

*** 另一个问题是,在检索阶段的机器时,我应该如何以及在 nTier 中的何处进行映射?

对于需要引用其他类的类,C# 中的良好设计模式是什么?

此链接讨论了类设计问题,但没有回答 NTier 设计中我的 Stage 对象的 Machines 的保存和检索机制。

4

3 回答 3

1

尽管它与业务问题无关,但 Machine 实际上确实与由集合表达的 Stage 有关联。如果您使用的是 O/R 映射器,我认为最简单的解决方案是在 Machine 上实现 Stage 集合,但不要公开它。这可能会在以后提供其他优势,例如公开 Count 属性以表示机器使用的阶段数。我的解决方案是这样的:

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.
}
于 2009-07-04T13:05:35.597 回答
0

你说过

...机器类不应该有阶段列表,因为它与业务问题领域无关。

这是否意味着您所需要的只是从舞台到机器的一对多关系?在那种情况下,你所拥有的就足够了。

于 2009-07-04T07:47:56.723 回答
0

如果您执行以下操作:

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

您最终会得到两个代表相同机器数据的不同对象。相反,您可以拥有一个机器列表或 MachineFactory,它为您提供相同的对象引用,给定机器 ID,因此:

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

或者

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

(对不起,如果“工厂”在这里是错误的术语。基本上你可以有一个静态方法为每个机器 ID 创建一个单例。)

这就是 OOP 术语中多对多所需的全部内容,因为您提到不需要从 Machine 遍历到其父 Stage。为了简单起见,单独的 StageMachine 类有助于使您的类与关系数据库结构保持一致,或者允许更轻松地在阶段和机器之间进行双向遍历,而无需在 Machine 和 Stage 类中维护冗余列表。

于 2009-07-04T07:58:33.173 回答