这可能是个很简单的问题,但首先需要一些背景.我正在模拟各种硬件开关,这些开关可以打开或关闭。这些开关是可配置的,允许用户指定发送到硬件的数字值,以表示它应该打开或关闭。这是Switch类:-
public class Switch
{
public Id { get; set; }
public SwitchConfig Config { get; set; }
public void TurnOn()
{
WriteToSerialPort(Id, Config.OnValue);
}
public void TurnOff()
{
WriteToSerialPort(Id, Config.OffValue);
}
}
public class SwitchConfig
{
public int OnValue { get; set; }
public int OffValue { get; set; }
}到目前一切尚好。
现在我需要建模一种新类型的开关,它不仅可以打开和关闭,而且还可以设置温度阈值,因此从Switch类继承似乎是明智的。该配置还需要扩展以包括最低/最高允许温度,例如:
public TemperatureSwitchConfig : SwitchConfig
{
public int MinTemperature { get; set; }
public int MaxTemperature { get; set; }
}专业开关类如下所示:-
public TemperatureSwitch : Switch
{
public void SetTemperature(int temperature)
{
var temperatureSwitchConfig = Config as TemperatureSwitchConfig;
if (temperature < temperatureSwitchConfig.MinTemperature
|| temperature > temperatureSwitchConfig.MaxTemperature)
{
return;
}
WriteToSerialPort(Id, temperature);
}
}在我不得不抛出Config属性的地方,它感觉“不对”。我相信一定有一个更圆滑的OO解决方案,但我认为“分析瘫痪”已经开始,我看不到树木的木材!还是我什么都不担心--在这种情况下,铸造是一个可以接受的解决方案吗?
发布于 2014-04-25 13:52:17
我建议您从类中删除Config属性,并将它的所有属性放入类本身。然后,在每个开关的构造函数中或作为属性设置这些属性。
您说SwitchConfig来自于XML序列化。如果您想以某种方式将序列化参数化,这通常是使用模型类中的属性完成的(在您的例子中是SwitchConfig)。然后,SwitchConfing和传递的Switch就会依赖于模块来进行XML序列化。
如果您想要创建基于XML以外的其他东西的开关呢?然后,您需要不必要地创建Config类,而不是在构造函数或属性中设置参数。
最后想到的是:如何创建Switch类的具体类型?例如:如何决定创建Switch或TemperatureSwitch?可能是基于SwitchConfig的类型。如果你已经有了这样的代码,为什么不直接把它变成一个功能齐全的工厂,根据XML数据构建特定的开关呢?而且XML序列化可以在这个工厂内部封装。
如果您担心在配置更改时需要更改许多东西,那么您可以按照Karl的话,使用弱类型反序列化,而不是显式类模型。
发布于 2014-04-25 12:54:16
您关于需要从xml生成Config的评论为问题添加了一个全新的维度。强类型在编译时最有用,在这里不适用。我倾向于创建一个Dictionary来保存解析的配置,并使用它如下:
public TemperatureSwitch : Switch
{
public void SetTemperature(int temperature)
{
if (temperature < config["MinTemperature"]
|| temperature > config["MaxTemperature"])
{
return;
}
WriteToSerialPort(Id, temperature);
}
}您可以将验证放入解析器代码或setter代码中。或者,您可以完全放弃Config,让您的xml解析器代码直接创建Switch对象,并为配置项设置单独的字段。
发布于 2014-04-25 12:50:17
您可以将配置设置为参数:
public abstract class Switch<TConfig> where TConfig : SwitchConfig
{
public Id { get; set; }
public TConfig { get; set; }
public void TurnOn()
{
WriteToSerialPort(Id, Config.OnValue);
}
public void TurnOff()
{
WriteToSerialPort(Id, Config.OffValue);
}
}
public class NormalSwitch : Switch<SwitchConfig>
{
}
public TemperatureSwitch : Switch<TemperatureSwitchConfig>
{
public void SetTemperature(int temperature)
{
if (temperature < Config.MinTemperature
|| temperature > Config.MaxTemperature)
{
return;
}
WriteToSerialPort(Id, temperature);
}
}https://softwareengineering.stackexchange.com/questions/236988
复制相似问题