【问题标题】:Solid Principles / Builder Pattern坚实的原则/建造者模式
【发布时间】:2019-04-14 07:47:00
【问题描述】:

我正在创建一个非常小的应用程序来演示可靠的原则以及构建器模式的简要实现,是否有人对如何改进或它如何违反可靠原则有任何反馈?该应用程序是一个仅转换单位的小型应用程序,例如码到米,英寸到厘米。

界面

public interface IConverter
{
    double ConversionRate { get; set; }
    string[] ConvertedUnits { get; set; }
    string DisplayText { get; set; }

    string[] Convert(string input);
}

类实现接口

 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;
            }
        }
    }

生成器(抽象类)

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);
        }

    }

构建器实现抽象构建器类

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 核心构建的,非常感谢任何反馈:)

【问题讨论】:

  • 嗯,在这里我将只有一个静态 UnitConverter 类,其中包含支持的单位(非字符串)和内置转换率的枚举。此外,您的 IConverter 界面的 DisplayText 函数似乎违反了 SOLID。
  • 谢谢,在显示文本违反 SOLID 时,您能详细说明一下吗?
  • DisplayText 与转换器的转换工作有什么关系?它违反了单一职责原则——现在你让它对 UI 负责。
  • 嗯是的非常好,所以将显示文本移动到类并从界面中删除
  • 这个问题属于codereview.stackexchange.com

标签: .net design-patterns interface .net-core solid-principles


【解决方案1】:

首先,看起来像复制和粘贴错误...您的第二个 AddConversionRate 方法应该是 AddConversionUnits。

关于 SOLID 原则,您不能总是在这样的小代码示例中展示所有原则的证据。

  1. 单一责任 - 如前所述,转换器中的显示文本可能违反了这一原则。
  2. 打开/关闭 - 您没有在此处扩展任何类,因此很难用您的示例进行展示。
  3. Liskov 的替换 - 没有子类,因此再次没有证据表明违反了这个。
  4. 接口隔离 - DisplayText 应从 IConverter 中提取出来。
  5. 依赖倒置 - 最大的违规行为在这里。细节是针对具体类型而不是抽象来实现的。在 ConverterBuilder 上构建应返回 IConverter 而不是具体的 Converter。您的控制器 Convert 操作应将转换器变量声明为 IConverter 而不是 Converter 具体类型,我还将将该依赖项注入构造函数中的控制器类(再次作为 IConverter),然后在操作中使用该依赖项而不是声明本地变量。

我写了an article on the SOLID principles,你可能会觉得有趣

【讨论】:

    【解决方案2】:

    这些不一定与 SOLID 原则有关,但如果我在工作中查看此代码,我会提到以下几点

    • 过度使用 char '/n'。如果您想从'/n' 更改为'/r/n',则必须在Converter.Convert 中更改5 次。处理此问题的更好方法是将其存储在变量中,或者允许通过构造函数对其进行设置。
    • 您可以使用var 而不是显式声明变量类型,例如var d = double.Parse(input, CultureInfo.InvariantCulture) * ConversionRate;
    • 变量名称、简洁的代码应该易于阅读,因此不要使用 d 和双精度等名称,而是使用易于阅读代码的人理解的名称
    • 你不需要在接口IConverter上指定Converter的属性,这是因为接口只需要暴露对象的行为,属性更多的是一个实现细节。删除属性将允许您拥有多个实现 IConvert 的对象,而不必强制拥有这些特定属性(接口隔离)

    我希望这会有所帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多