单一责任与封装

时间:2015-02-21 22:09:28

标签: c# encapsulation solid-principles single-responsibility-principle

我试图更多地了解单一责任。如果我尝试代表可以添加,删除,更新,检索的客户那么在过去,我的客户类将在其上添加,删除,更新和获取方法。这有助于将客户的现实行为封装在一个类中。单一责任我最终会将我的客户类分为AddCustomer类,删除客户类,更新客户类和获取客户类,甚至可能获得所有客户类?

3 个答案:

答案 0 :(得分:4)

在您所描述的场景中,您不需要将Customer课程分成多个添加/更新/删除客户类 - 实际上这几乎肯定会使您的系统更难理解。

  

顺便说一下,我可能错了,听起来你正在使用类似Active Record模式的东西;这种模式本身没有任何问题,但它违反了SRP,并且它不是最可测试的模式,所以我倾向于建议你采取另一种方法。

单一责任原则

SRP声明一个类应该只有一个,而且只有一个要改变的理由。但是如果你考虑一下你现在拥有的东西,你的Customer班级已经有两个职责,因此已经有两个可能的原因需要改变

  • 在您正在实施的任何应用程序域中表示客户的数据和行为
  • 坚持自己的数据(即所有CRUD操作)。

因此,如果底层数据库发生更改,则需要更新处理持久性的Customer类方法,如果Customer的所需行为发生更改,则必须更新Customer类以实现新行为。

它如何帮助

当你遇到这样的情况时,你的Customer类总是有可能最终得到混合代码,这些代码将业务逻辑和数据库持久性逻辑纠缠成一个高度耦合的混乱,这样稍后您会发现很难对一方面进行更改而不会在另一方面造成问题。 我去过那里并不好玩,所以请记住这一点;这真的是SRP的全部 - 避免经典" Big Ball of Mud"情况。

从这里开始

  • 如果你真的想要关注" S"在SOLID *中,我建议从Repository模式开始,以处理Customer类与数据库之间的实际持久性(Repository您创建的类当然会遵循SRP,因为它只关注数据库的CRUD并且不包含任何与Customer
  • 相关的业务逻辑"
  • 一旦您对这种方法感到满意,如果您愿意,可以继续使用Command模式,here就是一个很好的例子,您可以阅读Query模式在这里(你需要两者)。但是,一个漂亮,简单的存储库模式也没有错。

*它可能不是可以绝对证明的东西,但我个人发现坚持SOLID原则的代码往往非常容易测试,非常容易理解和改变,并且非常强大。再说一次,那就是我YMMV!

答案 1 :(得分:2)

不,它不一定是那样的,因为SRP意味着你的课程应该只有一个原因可以改变。 你的问题很通用,所以我的答案质量相似。 我不禁想知道为什么客户应该能够添加自己,...... SRP是关于你如何表达阶级责任的问题,关于分层,它不应该被打扰关于如何完全履行这些责任的细节。它必须保持在自己的抽象层。

另见http://en.wikipedia.org/wiki/Single_responsibility_principle

但请注意,改变的原因非常重要,而不仅仅是它应该只对一件事负责。多个动作可能属于一起,因此您仍然有一个改变的理由。

您可能需要查看完整的SOLID首字母缩写词。

答案 2 :(得分:0)

简短的回答是,您不需要为每个客户CURD操作创建多个类,因为这些操作的更改源是相同的。请按照我的说明进行操作。

单一责任原则鼓励我们设计我们的系统,使任何一个班级只有一个改变的理由。因此,要正确实施SRP,需要了解“变更原因”的含义。

任何系统的原因/变更来源都是业​​务。例如,企业有以下部门来管理客户

  1. 客户管理
  2. 客户广告系列管理
  3. 客户架构
  4. 客户订单管理
  5. 这意味着变更来源可以来自任何这些部门。如果必须在上面的示例中正确实施SRP,则应为每个部门创建一个类

    客户管理

    class Customer{    
       private String firstName;
       private String lastName        
       public getCustomerFullName(){
          return firstName+ " "+ lastName
        }
     }
    

    客户广告系列管理

     class Campaign{
          private String code;
          private String details
        }
    

    客户架构

    class CustomerRepository{
    
         CustomerRepository(Customer customer){
    
         }   
         public void create(){        
         }   
         public void update(){         
         }    
         public void delete(){         
         }   
      }
    

    客户订单管理

    class Order{
      private Customer customer;
    
      public Order(Customer customer){
       this.customer=customer;
      }
      public List<Orders> getCustomerOrders(){
    
      }
    }
    

    为CURD操作回答原始问题的变更来源是系统的架构设计者。因此,与CURD操作相关的所有方法都可以存在于同一个类中,并且不会违反SRP。在Nutshell中根据SRP设计您的类,重要的是要提前了解更改的来源。

    可以找到进一步的解释Here。但这是付费视频。