C# 如何在一系列行动中遵循单一责任原则

C# 如何在一系列行动中遵循单一责任原则,c#,.net,oop,solid-principles,single-responsibility-principle,C#,.net,Oop,Solid Principles,Single Responsibility Principle,我有一个windows服务应用程序,它可以读取一些文件,进行一些修改并上传到web API 在这里,我尽可能遵循单一责任原则 在这个应用程序中,我有3个类来读取文件的内容,应用业务逻辑并将修改后的内容上传到服务器 class GetFileContent { // in here there is a method to return the file content } class ApplyBusinessLogic { // in here there is a method to

我有一个windows服务应用程序,它可以读取一些文件,进行一些修改并上传到web API

在这里,我尽可能遵循单一责任原则

在这个应用程序中,我有3个类来读取文件的内容,应用业务逻辑并将修改后的内容上传到服务器

class GetFileContent { 
// in here there is a method to return the file content
}

class ApplyBusinessLogic { 
// in here there is a method to get that file content as param and apply business logic
}

class UploadContent {
// get the modified content and upload it
}
现在我的问题是,如果我添加了一个新类作为
DoMyActions
,并创建了上述类的对象并调用了执行这些任务的方法,这是否违反了单一责任原则?为了澄清我的问题,我尝试做如下的事情

class DoMyAction { 

GetFileContent content = new GetFileContent();
// call the method in above class and get the content

ApplyBusinessLogic doMyThing = new ApplyBusinessLogic();
// do my stuff using that file content

UploadContent uploader = new UploadContent();
// upload the content
}
有没有更好的办法


如果我一直想使用
domaAction
类如何遵循单一责任原则?

如果
DoAction
类流程没有改变,可以直接封装
GetFileContent
ApplyBusinessLogic
将内容上传到
DoAction
类中

但我会为每个类创建接口,让代码更加灵活

public interface IFileContent{
    byte[] GetFileContent();
}
public interface IApplyBusinessLogic{
    void ApplyLogic();
}
public interface IUploadContent{
    void Upload();
}
public class DoMyAction { 

    IFileContent _content;
    // call the method in above class and get the content

    IApplyBusinessLogic _doMyThing;
    // do my stuff using that file content

    IUploadContent _uploader;
    // upload the content


    public DoMyAction(IFileContent content,IApplyBusinessLogic doMyThing,IUploadContent uploader){
        _content  = content;
        _doMyThing = doMyThing;
        _uploader = uploader;
    }

    public void excuteAPI(){
      //doing something here
    }
}
然后每个类实现每个接口,该接口与其操作相匹配

public class GetFileContent : IFileContent { 
    public  byte[] GetFileContent(){

    }
    // in here there is a method to return the file content
}

public class ApplyBusinessLogic : IApplyBusinessLogic { 
    public void ApplyLogic(){

    }
    // in here there is a method to get that file content as param and apply business logic
}

public class UploadContent : IUploadContent{
    public void Upload(){

    }
    // get the modified content and upload it
}
然后我会使用构造函数注入来注入procedure类,让代码更加灵活

public interface IFileContent{
    byte[] GetFileContent();
}
public interface IApplyBusinessLogic{
    void ApplyLogic();
}
public interface IUploadContent{
    void Upload();
}
public class DoMyAction { 

    IFileContent _content;
    // call the method in above class and get the content

    IApplyBusinessLogic _doMyThing;
    // do my stuff using that file content

    IUploadContent _uploader;
    // upload the content


    public DoMyAction(IFileContent content,IApplyBusinessLogic doMyThing,IUploadContent uploader){
        _content  = content;
        _doMyThing = doMyThing;
        _uploader = uploader;
    }

    public void excuteAPI(){
      //doing something here
    }
}

您可以在
DoMyAction
类的
excuteAPI
方法中设置您的执行逻辑。

我认为这是一个时不时困扰我的大问题,所以这是我的2美分

像DoMyAction这样必须在许多服务之间进行某种编排的操作是常见的,没有简单的方法可以绕过它们。然而,人们很容易忘记它们的真正目的,而添加额外的东西,理想情况下这些东西应该在别处。因此,本着单一责任的精神:

  • 不要封装依赖项的构造。这本身就是一项单独的责任。您可以通过注入从构造函数中获取所有依赖项,如图所示
  • 遵循规则并坚持您的直接依赖关系。这将最小化操作与其依赖项的耦合。例如,不要这样做:getFileContent().getRelevantSections().FormatRightly()
  • 该操作应在抽象接口上运行,以便满足多种类型的文件、处理器和上传服务
  • 一般来说,提醒自己行动的范围,并将除编排或其应做的任何事情以外的任何事情移出

您能解释一下您的第三个代码块的优点是什么或者使用它的原因是什么吗?@0第三个代码块可以让用户决定在
DoMyAction
类中使用哪个实例来代替硬代码。由于我对SRP有问题,您能看一下这个问题吗: