2009-07-04 51 views
2

假設我正在開發一個軟件,在一家制藥公司,其中每個'ProductionLine'有多個'Stages'每個階段有多個'Machines'我應該如何設計多對多關係類?

現在假設我維護着三個表來記錄階段及其機(離開ProductionLine離開的抖動討論)。

(2)機(其代表所有可能的機器的生產工廠可以具有基本數據)(

(1)第一階段(其代表所有可能的階段的任何生產線可具有基本數據) 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; 
     } 
    } 

現在我面臨着一個dillemma:

(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?

這個環節討論了一流的設計問題,但不接儲蓄與n層設計檢索我的舞臺對象的機器的機制。

回答

0

你說

...一臺機器類不應該有階段的名單,怎麼這是不相干的accoring到經營業務的問題域。

這並不意味着所有你需要的是從舞臺到機器的一對多關係嗎?在這種情況下,你擁有的就足夠了。

+0

號 怎麼我可能有數百臺機器和階段。但是當我創建一個機器對象時,我不需要知道它們屬於哪個階段。 – 2009-07-04 07:56:32

+0

如果我以後需要知道它,我應該調用一個方法Machine.GetStages(),它應該返回一個List 。 – 2009-07-04 07:58:16

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術語中多對多所需的全部內容,因爲你提到過你不需要從機器移動到其父級。爲簡單起見,單獨的StageMachine類將有助於使類與關係數據庫結構保持一致,或者允許在階段和機器之間更輕鬆地進行雙向遍歷,而無需在Machine和Stage類中保留冗餘列表。

1

雖然它與業務問題無關,但機器實際上與舞臺的關聯最好由集合表達。如果您使用的是O/R映射器,我認爲最簡單的解決方案是在機器上實現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. 
}