这个构造函数是否违反了单一责任原则?

时间:2018-02-16 15:44:24

标签: c# constructor coding-style solid-principles

我试图强迫自己使用SOLID原则并编写单元可测试代码。最近,在编写代码时我一直变得偏执和优柔寡断,因为我觉得我总是违反某些原则。

考虑下面的课程。 JavascriptPropertyInitializer负责检测给定类中具有特殊属性的属性列表,并呈现一些javaScript代码。它有太多的责任吗?构造函数做得太多了吗?

我知道我在构造函数中实例化了一个字典,并且我意识到实例化具体对象是一种已知的违规行为。是的,我知道,我应该通过构造函数注入它,但为什么呢?根据具体的字典,我班级的伤害是什么?

public class JavascriptPropertyInitializer
{
    private readonly HtmlTextWriter _writer;
    private readonly object _containerObject;
    private readonly string _javascriptObjectName;
    private readonly Dictionary<string, string> _settings;
    private List<PropertyInfo> _customWebControls;

    public JavascriptPropertyInitializer(HtmlTextWriter writer, object containerObject, string javascriptObjectName)
    {
        _writer = writer;
        _containerObject = containerObject;
        _javascriptObjectName = javascriptObjectName;
        _settings = new Dictionary<string, string>();
        ValidateParameters(writer, containerObject, javascriptObjectName);
        DetectCustomWebControls();
        CollectSettings();
    }

    public void Render() 
    {
        RenderJSProperties();
    }
}

2 个答案:

答案 0 :(得分:1)

单一责任原则定义如下:

  

一个班级应该只有一个改变的理由。

所以这就是为什么找到正确的措辞。但是,原因只在上下文中有意义,换句话说,在特定的抽象层次上。通过提升抽象层次,代码会改变其与单一责任原则的一致性。

您的经验可能与您使用的框架知识有所改善有关,因此您的理解正在转向更具体的抽象(接近框架内部)。在这个级别,你的代码做得太多了(因为你预见到很多改变的原因)。做一个心理练习,并尝试移动到您的应用程序的抽象,它做什么和为什么,并重新评估与SRP的一致性。

答案 1 :(得分:1)

这里的字典几乎是一种原始类型;它用于存储键值对,而不是其他(?)。我无法看到你需要将它换成不同的实现,这是IOC有用的地方。 作者更有意义的是IOC(你做过):我可以看到以后需要输出xml,或者作为字符串等输出。

关于太多的责任&#34;侧。从你的句子描述这个类的作用,1)检测特殊属性,2)渲染一些js。这里可能有分裂的可能性。如果此类刚刚检测到属性并在C#对象中返回检测到的属性,该怎么办?然后其他一些类,JavascriptRenderer可能会接受这些属性并转换为javascript。

var pi = JavascriptPropertyInitializer(containerObject, javscriptObjectName);
var r = JavascriptRenderer(writer);
var output = r.Render(pi.DetectAttributes());

我经常发现自己因不遵守编码原则而变得偏执。在这个时候,我只是尽我所能。我会在明显或有用时应用原则,但是当我不确定时,我会尽量不去担心它并继续前进。当我的代码变得痛苦时,我安慰自己知道我可以回去重构。