我是否传递代码以从服务进行进一步处理?

Were do I pass code for further processing from a service?

这里的学生,我真的尝试 google 这个可能很简单的问题,但找不到好的答案,也许我只是不知道 google 的正确术语,如果是的话对不起!

我正在尝试找出最佳做法,以便在服务收到数据后将 JSON 字符串转发到系统中,例如传递到解析器中,然后继续使用该对象。

今天,我们学习编写服务的方式可能看起来像这样。

private void ReceiveData(string json)
{
    var parser = new JsonParser();
    var normalizer = new Normalizer();
    var dataHandler = new DataHandler();

    var data = normalizer.Normalize(parser.Parse(json));
    dataHandler.Handle(data);
}

但在我看来,该服务似乎违反了单一责任原则,因为现在它不仅被设置为接收数据,而且还被解析、规范化和处理。这是正确的方法吗,因为我觉得这样做不对?

//突击贝蒂

在我看来,是的,您的代码违反了 Single Responsibility 因为如果

您需要更改逻辑
  • 您想更改为使用另一个 json 解析器
  • 您想更改接收数据逻辑

我很难向你推荐一个正确的重构方法,因为它缺少很多关于你的项目性质、类型、架构等的信息。然而,最简单的方法是把你的 json 解析器别处的逻辑

示例:我更愿意在这里使用字符串扩展方法。

//StringExtension.cs
public static class StringExtension {
    public static string ToJson(this string input)  {
        var parser = new JsonParser();
        var normalizer = new Normalizer();
        var dataHandler = new DataHandler();

        return normalizer.Normalize(parser.Parse(json));
    }
}

// in your class
private void ReceiveData(string json)
{
    dataHandler.Handle(json.ToJson());
}

我不同意 kienct89,进一步分解这个方法是多余的。您的方法的职责是接收数据,但该方法中的所有操作都属于 接收 数据的类别。

您可以通过声明数据解析接口来分解 class。

public interface IDataParser
{
    string ParseData(string input);
}

然后,您可以创建实现此接口的数据处理程序和 JSON 数据解析器。

public class JsonDataParser : IDataParser
{
    public string ParseData(string input)
    {
        //Convert the input to JSON.
    }
}

public class DataHandler
{
    private IDataParser _parser;

    public DataHandler(IDataParser parser)
    {
        _parser = parser;
    }

    public void ReceiveData(string data)
    {
        //Convert the data to the desired format.
        string result = _parser.ParseData(data);
    }
}

围绕此方法的想法是,通过使用 接口 进行编程,您的数据处理程序 class 不再依赖于解析数据的特定实现。也许将来您可能希望将数据解析为 CSV 格式而不是 JSON,在这种情况下,您只需为数据处理程序提供不同的解析器实现即可。

这是一个用法示例:

JsonDataParser jsonParser = new JsonDataParser();
DataHandler myDataHandler = new DataHandler(jsonParser);

myDataHandler.ReceiveData("Le toucan has arrived.");

正如我之前提到的,DataHandler 不依赖于特定的实现,因此您可以传入 CsvDataParser,而无需更改 DataHandler 中的任何内容。

无论如何,我仍然认为这有点矫枉过正。当然,这有助于您的代码更好地适应不断变化的需求,如果您愿意的话,可以更 敏捷 。但是,对于您的需求,我相信您当前的方法完全符合要求。

示例代码违反了SOLID设计原则;然而,我关心的不是单一职责原则,而是依赖倒置原则。该服务应该将其三个依赖项(JsonParserNormalizerDataHandler)注入其中,而不是自己实例化它们。

请注意,依赖倒置可能不是本课的目的,因此为简单起见可能已将其省略。