【问题标题】:How should I design classes for Many-to-Many relationships?我应该如何为多对多关系设计类?
【发布时间】:2009-07-05 11:39:12
【问题描述】:

假设我正在为一家制药公司开发一个软件,其中每个'ProductionLine' 有多个'Stages',每个Stage 有多个'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 中的何处进行映射?

What is a good design pattern in C# for classes that need to reference other classes?

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

【问题讨论】:

    标签: c# associations business-objects


    【解决方案1】:

    尽管它与业务问题无关,但 Machine 实际上确实与一个由集合表示的阶段相关联。如果您使用的是 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.
    }
    

    【讨论】:

      【解决方案2】:

      你说过

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

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

      【讨论】:

      • 没有。因为我可能有数百台机器和舞台。但是当我创建一个机器对象时,我不需要知道它们属于哪个阶段。
      • 如果我以后需要知道它,我应该调用一个方法 Machine.GetStages(),它应该返回一个 List。
      • 是的。当我创建舞台对象时。
      • 在药品生产的情况下,一台机器可以是多个阶段的一部分。
      【解决方案3】:

      如果您执行以下操作:

      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 类中维护冗余列表。

      【讨论】:

      • StageMachine - 类的问题是,我需要维护单独的 ID 并跟踪它们等。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2021-09-13
      • 2013-02-06
      • 2013-12-04
      • 2010-11-01
      • 2015-05-27
      • 1970-01-01
      相关资源
      最近更新 更多