如何在一套行动中遵循单一责任原则

时间:2018-11-26 02:52:03

标签: 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 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
}

对此有更好的选择吗?

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

2 个答案:

答案 0 :(得分:2)

如果DoAction类过程未更改,则可以直接将GetFileContentApplyBusinessLogicUploadContent封装到DoAction类中。

但是我会为每个类创建接口以使代码更灵活。

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

然后每个类都实现与它的操作相匹配的每个接口。

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

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

答案 1 :(得分:1)

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

必须在许多服务之间进行某种编排的

动作(如 DoMyAction )是常见的,没有简单的方法可以解决。但是,很容易忘记它们的真实目的,并添加理想情况下应该位于其他地方的其他内容。因此,本着单一责任的精神:

  • 不要封装依赖项的构造。这本身就是一项单独的责任。您可以通过this answer所示的注入方式从构造函数中获取所有依赖项
  • 遵循Law of Demeter并坚持您的直接依赖关系。这将使您的操作与其依赖关系的耦合最小化。例如,不要这样做:getFileContent()。getRelevantSections()。formatProperly()
  • 该操作应在抽象接口上进行操作,以适应多种类型的文件,处理器和上载服务
  • 通常,提醒自己行动的范围,并除去编排方面的内容或应做的事情