2012-04-26 69 views
1

我有一種感覺,我做錯了。我是新來的抽象類等,一直在讀一些教程,但我無法弄清楚如何將它應用於我的情況。我認爲我的設計可能有問題,但我想不出另一種方式來做到這一點。我的公司生產一些不同的電腦,我需要能夠監控電池信息。儘管獲取信息不是問題,但要弄清楚如何將不同的命令發送到基類來完成我需要的操作。說我想讓我的電池1電壓。在一個單元上,命令是0x0418,另一個單元是0x453。所以在我的信息課上,我運行一個測試來看看模型是什麼。我有一個稱爲電池的基類,它有一堆變量,這些變量是每個電池的標準變量(電池電壓,充電電流,充電電流等),然後決定爲我的每個單元制定延長電池的單獨班級。從繼承類傳遞給基類的方法

現在我的設計我認爲是現貨(可能是錯的,因爲我不擅長抽象和多態)。我有一個面板,最終會顯示我從BatteryInformation類獲得的信息。像Battery1Cell1Label.Text = batteryInfo.GetCell1(1); Battery2Cell1Label = batteryInfo.GetCell1(2)。我想我需要一個GetValue(字節命令)(因爲它是一個嵌入式控制器命令來獲取每種不同類型的信息)。也許我應該停止說話,只是發佈我的代碼我有什麼並告訴你我有錯誤。

battery.cs

public abstract class Battery<T> //not sure that the <T> is right 
{ 
    public string Information { get; private set; } 
    public float Cell1 { get; private set; } 
    public float Cell2 { get; private set; } 
    public float Cell3 { get; private set; } 
    public float Cell4 { get; private set; } 
    public int FCC { get; private set; } 
    public bool ChargeIC { get; private set; } 
    public int StartCharge { get; private set; } 
    public int CurrentCharge { get; private set; } 
    public bool Exists { get; private set; } 

    protected internal void GetValue(byte command) 
    { 
     //Use Embedded controller to get said value 
     //ECPort.ReadEC(command); 
     //Testing Purposeses 
     Console.WriteLine(command); 
    } 
} 

Battery8800.cs

class Battery8800 : Battery<Battery8800> 
{ 
    public Battery8800() : base() 
    { 

    } 
    public void GetValue(BatteryCommands command) 
    { 
     base.GetValue((byte)command); 
    } 

    public enum BatteryCommands 
    { 
     Battery1VoltageHigh = 0x0402, 
     Battery1VoltageLow = 0x0403, 
     Batt1ChargeCurrentHigh = 0x0404, 
     Batt1ChargeCurrentLow = 0x0405, 
     Battery1MaxError = 0x0407, 
     Battery1RSOC = 0x0409, 
     Battery1FCCHigh = 0x040E, 
     Battery1FCCLow = 0x040F, 
     Battery1DCHigh = 0x0412, 
     Battery1DCLow = 0x0413, 
     Battery1Cell1High = 0x0418, 
     Battery1Cell1Low = 0x0419, 
     Battery1Cell2High = 0x041A, 
     Battery1Cell2Low = 0x041B, 
     Battery1Cell3High = 0x041C, 
     Battery1Cell3Low = 0x041D, 
     Battery1Cell4High = 0x041E, 
     Battery1Cell4Low = 0x041F, 
     PowerSource1 = 0x0420, 
//many more commands for battery 2 etc etc 
    } 
} 

BatteryInformation.cs

class BatteryInformation 
{ 
    public Battery battery1; //error says it needs 1 type of argument 
    public Battery battery2; //error says it needs 1 type of argument 
    public BatteryInformation() 
    { 

     switch (UnitModel.GetModelEnum()) 
     { 
      case UnitModel.DLIModel.DLI8300M: 
       battery1 = new Battery8300(); 
       battery2 = new Battery8300(); 
       break; 
      case UnitModel.DLIModel.DLI8400: 
       battery1 = new Battery8400(); 
       battery2 = new Battery8400(); 
       break; 
      case UnitModel.DLIModel.DLI8500: 
       battery1 = new Battery8500(); 
       break; 
      case UnitModel.DLIModel.DLI8500P: 
       battery1 = new Battery8500P(); 
       break; 
      case UnitModel.DLIModel.DLI8800: 
       battery1 = new Battery8800(); 
       break; 
      case UnitModel.DLIModel.DLI9200: 
       battery1 = new Battery9200(); 
       break; 
      default: 
       break; 
     } 
     //for testing purposes 
     battery1 = new Battery8800(); 
     battery1.DoThis(Battery8800.BatteryCommands.Batt1ChargeCurrentHigh); 
    } 
} 

YEAH在尾節能!權力剛剛熄滅了,我沒有放鬆,但一句話!

所以,當我的電腦開機時,我想在我的電池板類中做這樣的事情可能會更好。

//in my timer_tick event 
    BatteryInformation.UpdateBatteries(); 
    battery1Cell1Label.Text = BatteryInformation.Battery1.Cell1.ToString(); 
    //etc etc 

,但我仍然需要得到這個工作,但我有一個很難搞清楚該怎麼做抽象。感謝您的時間。

編輯

我想我會對此錯誤的方式。

class Battery1_8400 : Battery 
{ 
    public override bool Update() 
    { 
     //TODO finish 
     Exists = GetValue((ushort)Commands.PowerSource) != 0xFF; 
     if (Exists) 
     { 
      Cell1 = GetValue((ushort)Commands.Cell1Low, (ushort)Commands.Cell1High)/1000.0f; 
      Cell2 = GetValue((ushort)Commands.Cell2Low, (ushort)Commands.Cell2High)/1000.0f; 
      Cell3 = GetValue((ushort)Commands.Cell3Low, (ushort)Commands.Cell3High)/1000.0f; 
      FCC = GetValue((ushort)Commands.FCCLow, (ushort)Commands.FCCHigh); 
      Voltage = GetValue((ushort)Commands.VoltageLow, (ushort)Commands.VoltageHigh); 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    private enum Commands 
    { 
     PowerSource = 0x0480, 
     Charge = 0x0432, 
     RSOC = 0x0734, 
     DCLow = 0x0402, 
     DCHigh = 0x0403, 
     FCCLow = 0x0404, 
     FCCHigh = 0x0405, 
     MaxError = 0x0730, 
     Cell1Low = 0x0778, 
     Cell1High = 0x0779, 
     Cell2Low = 0x077C, 
     Cell2High = 0x077D, 
     Cell3Low = 0x0780, 
     Cell3High = 0x0781, 
     VoltageLow = 0x0438, 
     VoltageHigh = 0x0439, 
     ChargeCurrentLow = 0x0728, 
     ChargeCurrentHigh = 0x0729, 
     ChargeIC = 0x1A03, 
    } 
} 

我有9個文件在更新命令的工作方式方面都是相同的,不同之處在於enum。每個類的命令略有不同。看看batter2_8400.cs的枚舉

private enum Commands 
    { 
     PowerSource = 0x0480, 
     Charge = 0x04C2, 
     RSOC = 0x0834, 
     DCLow = 0x0492, 
     DCHigh = 0x0493, 
     FCCLow = 0x0494, 
     FCCHigh = 0x0495, 
     MaxError = 0x0830, 
     Cell1Low = 0x0878, 
     Cell1High = 0x0879, 
     Cell2Low = 0x087C, 
     Cell2High = 0x087D, 
     Cell3Low = 0x0880, 
     Cell3High = 0x0881, 
     VoltageLow = 0x04C8, 
     VoltageHigh = 0x04C9, 
     ChargeCurrentLow = 0x0828, 
     ChargeCurrentHigh = 0x0829, 
     ChargeIC = 0x1A04, 
    } 

更新命令是一樣的,以及其他7個文件。似乎有點不好的設計給我,但我很難理解我應該如何做到這一點。順便說一句,這是我的課程後,我給了一個答案,並收到少數意見。

+3

什麼是正在使用的通用參數?它看起來像你,只是不需要它。 – 2012-04-26 16:10:44

+0

是Cell1應該調用getvalue什麼的? – 2012-04-26 16:20:44

+0

@JamieDixon通用來自我試圖從其他職位複製一些關於繼承的想法。 – 2012-04-26 16:42:11

回答

0

最後我想我想出了我應該做的事情。它看起來很乾淨,似乎有道理。也許你可以批評它?

public abstract class Battery 
{ 
    public string Information { get; set; } 
    public float Cell1 { get {return GetValue(Cell1Low, Cell1High)/1000.0f;} } 
    public float Cell2 { get {return GetValue(Cell2Low, Cell2High)/1000.0f;} } 
    public float Cell3 { get {return GetValue(Cell3Low, Cell3High)/1000.0f;} } 
    public float Cell4 { get {return GetValue(Cell4Low, Cell4High)/1000.0f;} } 
    public float Voltage { get {return GetValue(VoltageLow, VoltageHigh);} } 
    public int DC { get {return GetValue(DCLow, DCHigh);} } 
    public int FCC { get {return GetValue(FCCLow, FCCHigh);} } 
    //public bool ChargeIC { get {return } } 
    //public int StartCharge { get {return } } 
    //public int CurrentCharge { get {return } } 
    public bool Exists { get {return GetValue(PowerSource) != 0xFF} } 
    public int FCCPercent { get {return ((FCC * 100)/DC);} } 

    /// <summary> 
    /// Gets a value depending on the Embedded controller 
    /// </summary> 
    /// <param name="low">The low byte command to process</param> 
    /// <param name="high">The high byte command to process</param> 
    /// <returns></returns> 
    private int GetValue(ushort low, ushort high) 
    { 
     //Use Embedded controller to get said value 
     //ECPort.ReadEC(command); 
     //Testing Purposeses 
     var lowValue = ECPort.ReadEC(low); 
     var highValue = ECPort.ReadEC(high); 
     return (int)((highValue << 8) + lowValue); 
    } 

    private int GetValue(ushort command) 
    { 
     return (int)ECPort.ReadEC(command); 
    } 

    public abstract ushort PowerSource {get;} 
    public abstract ushort Charge{get;} 
    public abstract ushort RSOC{get;} 
    public abstract ushort DCLow{get;} 
    public abstract ushort DCHigh{get;} 
    public abstract ushort FCCLow{get;} 
    public abstract ushort FCCHigh{get;} 
    public abstract ushort MaxError{get;} 
    public abstract ushort Cell1Low{get;} 
    public abstract ushort Cell1High{get;} 
    public abstract ushort Cell2Low{get;} 
    public abstract ushort Cell2High{get;} 
    public abstract ushort Cell3Low{get;} 
    public abstract ushort Cell3High{get;} 
    public abstract ushort Cell4Low { get; } 
    public abstract ushort Cell4High { get; } 
    public abstract ushort VoltageLow{get;} 
    public abstract ushort VoltageHigh{get;} 
    public abstract ushort ChargeCurrentLow{get;} 
    public abstract ushort ChargeCurrentHigh{get;} 
    public abstract ushort ChargeIC{get;} 

} 

然後在我的子類繼承它的一個例子是此

class Battery1_8400 : Battery 
{ 
    public override ushort PowerSource { get {return 0x0480;}} 
    public override ushort Charge { get {return 0x0432;}} 
    public override ushort RSOC { get {return 0x0734;}} 
    public override ushort DCLow { get {return 0x0402;}} 
    public override ushort DCHigh { get {return 0x0403;}} 
    public override ushort FCCLow { get {return 0x0404;}} 
    public override ushort FCCHigh { get {return 0x0405;}} 
    public override ushort MaxError { get {return 0x0730;}} 
    public override ushort Cell1Low { get {return 0x0778;}} 
    public override ushort Cell1High { get {return 0x0779;}} 
    public override ushort Cell2Low { get {return 0x077C;}} 
    public override ushort Cell2High { get {return 0x077D;}} 
    public override ushort Cell3Low { get {return 0x0780;}} 
    public override ushort Cell3High { get {return 0x0781;}} 
    public override ushort VoltageLow { get {return 0x0438;}} 
    public override ushort VoltageHigh { get {return 0x0439;}} 
    public override ushort ChargeCurrentLow { get {return 0x0728;}} 
    public override ushort ChargeCurrentHigh { get {return 0x0729;}} 
    public override ushort ChargeIC { get {return 0x1A03;}} 
} 

現在我需要做的就是編輯一個文件battery.cs如果我需要做出改變吧。

0

基類BatteryInformation應該對每一個值的抽象屬性需要檢索,像這樣:

public abstract class BatteryInfo { 
    // int should be replaced with the actual data type of the value 
    public abstract int VoltageHigh { get; } 
    public abstract int VoltageLow { get; } 
    // etc. for each value you need 
} 

然後在你的子類你實現每個屬性

public class Battery8800 : BatteryInfo { 
    public override int VoltageHigh { 
     get { 
      int value; 
      // do code to retrieve value 
      return value; 
     } 
    } 
} 

此外,我會提供一種方法,您的用戶界面可以消耗的方式如下所示:

public IEnumerable<BatteryInfo> GetAllBatteryInfo() { 
    // get each battery 
} 

這樣用戶界面不需要擔心如何爲每個電池檢索電池信息。這允許您使用列表或網格樣式控件之一來查看電池信息。

+0

我希望避免覆蓋所有不同的值,因爲獲取信息是相同的。它取決於命令來獲取來自子類的所述信息。那麼這仍然是正確的方法? – 2012-04-26 16:45:34

+1

您可以在基類中實現'GetValue'方法,但將其標記爲受保護的,並讓子類中的屬性調用該方法來獲取值。 – 2012-04-26 18:11:28

+0

我在battery.cs中做了這個public abstract void Update(),那麼擴展電池的所有東西都必須擁有它。然後我創建了一個GetValue(ushort low,ushort high),並在battery.cs中返回int。然後在我的每個子類中的每個更新方法中,我都將值發送到GetValue並存儲結果。到目前爲止,我認爲它的工作..我必須測試它。 – 2012-04-26 19:03:36