我最近在作業中遇到了一段代碼,它有一個重復if-else條件,用于檢查名為 的列舉OperationType:
public enum OperationType
{ A, B }
現在該類的作業是在設備 A 或設備 B 上運行操作,同時從 a 讀取SharedDevice并存盤一些基本上用于 X,Y 圖的值。我們在 DeviceA 或 DeviceB 的函式中記錄了 SharedDevice 的特性。問題是我們需要遍歷不同引數的串列并將它們發送到 SharedDevice。該串列對于設備 A 和設備 B 是不同的。
Device 班級:
public class Device
{
public double CurrentValue { get; }
public DeviceParameters Parameters { get; set; }
}
這是負責執行此操作的類:
public class MyOperationExecuter
{
public Device SharedDevice { get; }
public Device DeviceA { get; }
public Device DeviceB { get; }
public List<DeviceParameters> ParametersA { get; }
public List<DeviceParameters> ParametersB { get; }
public List<double> XValuesOfA { get; }
public List<double> YValuesOfA { get; }
public List<double> XValuesOfB { get; }
public List<double> YValuesOfB { get; }
public void DoMyOperation(OperationType operationType)
{
List<DeviceParameters> changingDeviceParameters;
if (operationType == OperationType.A)
{
changingDeviceParameters = ParametersA;
}
else
{
changingDeviceParameters = ParametersB;
}
if (operationType == OperationType.A)
{
XValuesOfA.Clear();
YValuesOfA.Clear();
}
else
{
XValuesOfB.Clear();
YValuesOfB.Clear();
}
foreach (var parameters in changingDeviceParameters)
{
// set the device parameters
SharedDevice.Parameters = parameters;
// retrieve the device readings and store the values in the correct dataprovider
if (operationType == OperationType.A)
{
XValuesOfA.Add(DeviceA.CurrentValue);
YValuesOfA.Add(SharedDevice.CurrentValue));
}
else
{
XValuesOfB.Add(DeviceB.CurrentValue);
YValuesOfB.Add(SharedDevice.CurrentValue);
}
}
// save updated x,y data
Save();
}
}
正如你所看到的,有一個重復的 if 陳述句,這不是未來的證明,因為我們必須在每一步中檢查列舉。此外,我們可能需要添加一個 C 型別的設備,這將導致不斷增長的 switch 陳述句。我們可能還需要在 A 和 B 上執行操作。我應該如何重構這個操作,以便我可以繼續擴展它而不總是重復 if-else 邏輯?
uj5u.com熱心網友回復:
一個相當簡單的方法是宣告一個代表 A 或 B 的變數:
var XValues = operationType == OperationType.A ? XValuesOfA : XValuesOfB;
那么你可以只使用 XValues。對DeviceA. 如果您有更多操作,您可以使用switch 運算式。
一個更簡潔的解決方案是創建包含 A 或 B 所需的所有內容的單獨物件,這樣您的類就可以簡單地檢查操作型別,然后將所有作業委托給相應的物件。IE
public class MyDevice
{
public Device SharedDevice { get; }
public Device Device { get; }
public List<DeviceParameters> Parameters { get; }
public List<double> XValuesOf { get; }
public List<double> YValuesOf { get; }
public void DoMyOperation()
{
...
}
}
我還建議使用包含 X 和 Y 值的單個串列,例如Vector2。我發現這更易于使用,并有助于避免重復代碼。
uj5u.com熱心網友回復:
在不更改類欄位/屬性的情況下,我會使用新方法:
private void SetParameters(List<DeviceParameters> parameters, List<double> xValues, List<double> yValues, Device device)
{
xValues.Clear();
yValues.Clear();
foreach(var parameter in parameters)
{
SharedDevice.Parameters = parameter;
xValues.Add(device.CurrentValue);
yValues.Add(SharedDevice.CurrentValue);
}
}
然后在 DoMyOperation 中,它足以:
if (operationType == OperationType.A)
{
SetParameter(ParametersA, XValuesOfA, YValuesOfA, DeviceA);
}
else
{
SetParameter(ParametersB, XValuesOfB, YValuesOfB, DeviceB);
}
uj5u.com熱心網友回復:
您應該添加新課程。這將用于定義設備型別的特定屬性。
這樣的班級;
public class MyDeviceValues
{
public MyDeviceValues(List<DeviceParameters> parameters, List<double> xValuesOf, List<double> yValuesOf)
{
Parameters = parameters;
XValues = xValuesOf;
YValues = yValuesOf;
}
public List<DeviceParameters> Parameters { get; }
public List<double> XValues { get; }
public List<double> YValues { get; }
}
所以,你可以有一個通用的DoMyOperation功能。它會是這樣的:
public void DoMyOperation(MyDeviceValues myDeviceValues)
{
var changingDeviceParameters = myDeviceValues.Parameters;
myDeviceValues.XValues.Clear();
myDeviceValues.YValues.Clear();
foreach (var parameters in changingDeviceParameters)
{
// set the device parameters
SharedDevice.Parameters = parameters;
// retrieve the device readings and store the values in the correct dataprovider
myDeviceValues.XValues.Add(DeviceA.CurrentValue);
myDeviceValues.YValues.Add(SharedDevice.CurrentValue);
}
// save updated x,y data
Save();
}
這是您粘貼的整個代碼的重構版本:
https://dotnetfiddle.net/dLyJl9
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/316334.html
上一篇:C中字符的條件
