坚实的原则/建设者模式
Solid Principles / Builder Pattern
我正在创建一个非常小的应用程序来展示坚实的原则以及构建器模式的简要实现,有人对如何改进它或它如何打破坚实的原则有任何反馈吗?该应用程序是一个仅转换单位的小应用程序,例如码换算为米,英寸换算为 cms。
界面
public interface IConverter
{
double ConversionRate { get; set; }
string[] ConvertedUnits { get; set; }
string DisplayText { get; set; }
string[] Convert(string input);
}
Class 实现接口
public class Converter : IConverter
{
public double ConversionRate { get; set; }
public string[] ConvertedUnits { get; set; }
public string DisplayText { get; set; }
public Converter(double conversionRate, string[] convertedUnits, string displayText)
{
ConversionRate = conversionRate;
ConvertedUnits = convertedUnits;
DisplayText = displayText;
}
public string[] Convert(string input)
{
if (!input.Contains('\n'))
{
double d = double.Parse(input, CultureInfo.InvariantCulture) * ConversionRate;
string[] array = new string[1];
array[0] = d.ToString();
return array;
}
else
{
double[] doubles = new double[input.Split('\n').Count()];
for (int i = 0; i < input.Split('\n').Count(); i++)
{
double value = double.Parse(input.Split('\n')[i]);
doubles[i] = value;
string.Format("{0}", value * ConversionRate);
}
string[] strings = new string[doubles.Length];
for (int i = 0; i < input.Split('\n').Length; i++)
{
strings[i] = string.Format("{0}", doubles[i] * ConversionRate);
}
return strings;
}
}
}
生成器(摘要class)
public abstract class ConverterBuilder
{
protected double _conversionRate;
protected string[] _convertedUnits;
protected string _displayText;
public ConverterBuilder AddConversionRate(double conversionRate)
{
_conversionRate = conversionRate;
return this;
}
public ConverterBuilder AddConversionRate(string[] convertedUnits)
{
_convertedUnits = convertedUnits;
return this;
}
public ConverterBuilder AddDisplayText(string displayText)
{
_displayText = displayText;
return this;
}
public Converter Build()
{
return new Converter(_conversionRate, _convertedUnits, _displayText);
}
}
构建器实现抽象构建器class
public class UnitConverterBuilder : ConverterBuilder
{
public UnitConverterBuilder()
{
}
}
控制器
public IActionResult Convert(string text, double conversionRate)
{
Converter converter = new UnitConverterBuilder()
.AddConversionRate(conversionRate)
.Build();
string output = "";
for (int i = 0; i < converter.Convert(text).Count(); i++)
{
output += converter.Convert(text)[i] + Environment.NewLine;
}
return Content(output);
}
查看
输入要转换的值
<form asp-controller="Home" asp-action="Convert" method="post">
<textarea id="text" name="text" rows="10" cols="40"></textarea>
<select name="conversionRate">
<option value="">Please Select</option>
<option value="0.9144">Yards to Meters</option>
<option value="2.54">Inches To Centimeters</option>
</select>
<button>Convert</button>
</form>
该应用程序是使用 .net 核心构建的,非常感谢任何反馈:)
这些不一定与 SOLID 原则相关,但如果我在工作中审查此代码,我会提到以下几点
- 过度使用 char
'/n'
。如果您想从 '/n'
更改为 '/r/n'
,则必须在 Converter.Convert
中更改 5 次。处理此问题的更好方法是将其存储在变量中,或者允许通过构造函数对其进行设置。
- 您可以使用
var
而不是显式声明变量类型,例如 var d = double.Parse(input, CultureInfo.InvariantCulture) * ConversionRate;
- 变量名,干净的代码应该易于阅读,而不是使用像 d 和 double 这样的名称,使用易于阅读代码的人理解的名称
- 接口IConverter不需要指定Converter的属性,因为接口只需要暴露对象的行为,属性更多的是实现细节。删除属性将允许您拥有多个实现 IConvert 的对象,而不必被迫拥有这些特定属性(接口隔离)
希望对您有所帮助:)
首先,看起来像是复制粘贴错误...您的第二个 AddConversionRate 方法应该是 AddConversionUnits。
关于 SOLID 原则,您不能总是在像这样的小代码示例中展示所有原则的证据。
- 单一职责 - 如前所述,转换器中的显示文本可能违反了此原则。
- Open/Closed - 您没有在此处扩展任何 class,因此很难用您的示例显示。
- Liskov 的换人 - 没有替补class所以也没有证据表明违反了这一规定。
- 接口隔离 - DisplayText 应该从 IConverter 中移除。
- 依赖倒置 - 最大的违规行为在这里。细节是针对具体类型而不是抽象实现的。在 ConverterBuilder 上构建应该 return IConverter 而不是具体的 Converter。您的控制器 Convert 操作应将转换器变量声明为 IConverter 而不是 Converter 具体类型,我还将将该依赖项注入构造函数中的控制器 class(再次作为 IConverter),然后在操作中使用该依赖项而不是而不是声明局部变量。
我写了 an article on the SOLID principles 你可能会觉得有趣
我正在创建一个非常小的应用程序来展示坚实的原则以及构建器模式的简要实现,有人对如何改进它或它如何打破坚实的原则有任何反馈吗?该应用程序是一个仅转换单位的小应用程序,例如码换算为米,英寸换算为 cms。
界面
public interface IConverter
{
double ConversionRate { get; set; }
string[] ConvertedUnits { get; set; }
string DisplayText { get; set; }
string[] Convert(string input);
}
Class 实现接口
public class Converter : IConverter
{
public double ConversionRate { get; set; }
public string[] ConvertedUnits { get; set; }
public string DisplayText { get; set; }
public Converter(double conversionRate, string[] convertedUnits, string displayText)
{
ConversionRate = conversionRate;
ConvertedUnits = convertedUnits;
DisplayText = displayText;
}
public string[] Convert(string input)
{
if (!input.Contains('\n'))
{
double d = double.Parse(input, CultureInfo.InvariantCulture) * ConversionRate;
string[] array = new string[1];
array[0] = d.ToString();
return array;
}
else
{
double[] doubles = new double[input.Split('\n').Count()];
for (int i = 0; i < input.Split('\n').Count(); i++)
{
double value = double.Parse(input.Split('\n')[i]);
doubles[i] = value;
string.Format("{0}", value * ConversionRate);
}
string[] strings = new string[doubles.Length];
for (int i = 0; i < input.Split('\n').Length; i++)
{
strings[i] = string.Format("{0}", doubles[i] * ConversionRate);
}
return strings;
}
}
}
生成器(摘要class)
public abstract class ConverterBuilder
{
protected double _conversionRate;
protected string[] _convertedUnits;
protected string _displayText;
public ConverterBuilder AddConversionRate(double conversionRate)
{
_conversionRate = conversionRate;
return this;
}
public ConverterBuilder AddConversionRate(string[] convertedUnits)
{
_convertedUnits = convertedUnits;
return this;
}
public ConverterBuilder AddDisplayText(string displayText)
{
_displayText = displayText;
return this;
}
public Converter Build()
{
return new Converter(_conversionRate, _convertedUnits, _displayText);
}
}
构建器实现抽象构建器class
public class UnitConverterBuilder : ConverterBuilder
{
public UnitConverterBuilder()
{
}
}
控制器
public IActionResult Convert(string text, double conversionRate)
{
Converter converter = new UnitConverterBuilder()
.AddConversionRate(conversionRate)
.Build();
string output = "";
for (int i = 0; i < converter.Convert(text).Count(); i++)
{
output += converter.Convert(text)[i] + Environment.NewLine;
}
return Content(output);
}
查看
输入要转换的值
<form asp-controller="Home" asp-action="Convert" method="post">
<textarea id="text" name="text" rows="10" cols="40"></textarea>
<select name="conversionRate">
<option value="">Please Select</option>
<option value="0.9144">Yards to Meters</option>
<option value="2.54">Inches To Centimeters</option>
</select>
<button>Convert</button>
</form>
该应用程序是使用 .net 核心构建的,非常感谢任何反馈:)
这些不一定与 SOLID 原则相关,但如果我在工作中审查此代码,我会提到以下几点
- 过度使用 char
'/n'
。如果您想从'/n'
更改为'/r/n'
,则必须在Converter.Convert
中更改 5 次。处理此问题的更好方法是将其存储在变量中,或者允许通过构造函数对其进行设置。 - 您可以使用
var
而不是显式声明变量类型,例如var d = double.Parse(input, CultureInfo.InvariantCulture) * ConversionRate;
- 变量名,干净的代码应该易于阅读,而不是使用像 d 和 double 这样的名称,使用易于阅读代码的人理解的名称
- 接口IConverter不需要指定Converter的属性,因为接口只需要暴露对象的行为,属性更多的是实现细节。删除属性将允许您拥有多个实现 IConvert 的对象,而不必被迫拥有这些特定属性(接口隔离)
希望对您有所帮助:)
首先,看起来像是复制粘贴错误...您的第二个 AddConversionRate 方法应该是 AddConversionUnits。
关于 SOLID 原则,您不能总是在像这样的小代码示例中展示所有原则的证据。
- 单一职责 - 如前所述,转换器中的显示文本可能违反了此原则。
- Open/Closed - 您没有在此处扩展任何 class,因此很难用您的示例显示。
- Liskov 的换人 - 没有替补class所以也没有证据表明违反了这一规定。
- 接口隔离 - DisplayText 应该从 IConverter 中移除。
- 依赖倒置 - 最大的违规行为在这里。细节是针对具体类型而不是抽象实现的。在 ConverterBuilder 上构建应该 return IConverter 而不是具体的 Converter。您的控制器 Convert 操作应将转换器变量声明为 IConverter 而不是 Converter 具体类型,我还将将该依赖项注入构造函数中的控制器 class(再次作为 IConverter),然后在操作中使用该依赖项而不是而不是声明局部变量。
我写了 an article on the SOLID principles 你可能会觉得有趣