问题描述
|
只是想知道如果两个代码块都能产生相同的结果,哪种方法会更好:
string from = ddFrom.SelectedItem.ToString(),to = ddTo.SelectedItem.ToString();
switch(from)
{
case \"celsius\":
switch(to)
{
case \"celsius\":
break;
case \"fahrenheit\":
break;
case \"kelvin\":
break;
}
break;
case \"fahrenheit\":
switch(to)
{
case \"celsius\":
break;
case \"fahrenheit\":
break;
case \"kelvin\":
break;
}
break;
case \"kelvin\":
switch(to)
{
case \"celsius\":
break;
case \"fahrenheit\":
break;
case \"kelvin\":
break;
}
break;
}
或这一个:
string from = ddFrom.SelectedItem.ToString(),to = ddTo.SelectedItem.ToString(),conversion = from + to;
switch(conversion)
{
case \"celsiusfahrenheit\":
break;
case \"celsiuskelvin\":
break;
case \"fahrenheitcelsius\":
break;
case \"fahrenheitkelvin\":
break;
case \"kelvincelsius\":
break;
case \"kelvinfahrenheit\":
break;
}
谢谢。
解决方法
第二种选择是可取的,因为,正如大家都说过的那样,它使代码的外观和感觉更好。
但是,您可能需要考虑使用更具体系结构的选项:
public class TemperatureConverter
{
private static readonly IDictionary<Tuple<string,string>,Func<double,double>> ConverterMap =
new Dictionary<Tuple<string,double>>
{
{ Tuple.Create(\"celsius\",\"kelvin\"),t => t + 273 },// add similar lines to convert from/to other measurements
}
public static double Convert(double degrees,string fromType,string toType)
{
fromType = fromType.ToLowerInvariant();
toType = toType.ToLowerInvariant();
if (fromType == toType) {
return degrees; // no conversion necessary
}
return ConverterMap[Tuple.Create(fromType,toType)](degrees);
}
}
用法:
TemperatureConverter.Convert(0,\"celcius\",\"kelvin\");
当然,这可以进一步改善(首先想到使用枚举值而不是温度类型的字符串,还需要进行一些错误检查),但是总的思路是存在的。
恕我直言,这是介于老式C风格的mega-switch
和成熟的OO方法之间的一个很好的中间立场方法(这里没有真正的OO需求,因为这个特定的转换问题具有非常简单的域模型)。
,第二个对于快速结果和更少的编码会更好,因为它给出了相同的结果。
,最好对代码进行重组,以便具有温度标度类和一个抽象工厂,该抽象工厂根据输入字符串返回对应的实例:
public interface ITemperatureScale
{
double GetAbsoluteValue();
ITemperatureScale ConvertTo(ITemperatureScale temperatureScale);
}
public class CelciusScale : ITemperatureScale
{
public double GetAbsoluteValue()
{
throw new NotImplementedException();
}
public ITemperatureScale ConvertTo(ITemperatureScale temperatureScale)
{
throw new NotImplementedException();
}
}
public class FarScale : ITemperatureScale
{
public double GetAbsoluteValue()
{
throw new NotImplementedException();
}
public ITemperatureScale ConvertTo(ITemperatureScale temperatureScale)
{
throw new NotImplementedException();
}
}
public class KelvinScale: ITemperatureScale
{
public double GetAbsoluteValue()
{
throw new NotImplementedException();
}
public ITemperatureScale ConvertTo(ITemperatureScale temperatureScale)
{
throw new NotImplementedException();
}
}
public static class TemperatureScaleProvider
{
private const string SCALE_CELSIUS = \"celsius\";
private const string SCALE_KELVIN = \"kelvin\";
private const string SCALE_FAHRENHEIT = \"fahrenheit\";
public static ITemperatureScale GetFromString(string temperatureScaleString)
{
//Some input checks here
switch (temperatureScaleString.ToLowerInvariant())
{
case (SCALE_CELSIUS):
return new CelciusScale();
case (SCALE_KELVIN):
return new KelvinScale();
case (SCALE_FAHRENHEIT):
return new FarScale();
default:
throw new ArgumentException(\"temperatureScaleString\");
}
}
}
用法将是:
ITemperatureScale fromScale = TemperatureScaleProvider.GetFromString(\"celcius\");
ITemperatureScale toScale = TemperatureScaleProvider.GetFromString(\"KELvIN\");
,我认为第二个更好,更直接,更易读。如果需要,第二种方法将来会更易于维护,修改和扩展。
,选项#2看起来更干净,并且会产生相同的结果