单一职责原则

定义:

      该原则规定每个类都应该只有一个单一的功能,并且该功能应该由这个类完全封装起来。

何为职责?

      

既然是单一“职责”,那么职责即为被规定的因素。

  • 概括:"功能(职责)"为改变的原因,一个类或者模块应该有且只有一个改变的原因。

 

例子一:

  • 如下图农活责任所示,耕菜地和耕水田即为牛和耕地机的职责,即为这个对象存在的原因(下面将来讨论这个关系图)。

 

                                       

 

看上图农活责任,晃眼一看我们会决定这是对的!但仔细一分析农活接口其中包含的耕菜地和耕水田两个责任。

  • 牛耕水田,但它耕不动菜地,只能调用耕水田的接口,因此耕菜地的接口对于牛来说就是多余的。但耕地机即能耕菜地,也能耕水田。这就像是牛本来是耕田的,我们却说它还能去耕菜地,耕地机能做的事情,老牛表示无能为力!

  • 这样违反了SRP,导致了严重的问题。因为我们给牛保留了一个多余而不会完成的责任,这让我们每次提到牛不仅说它能耕水田还能耕菜地。这让我们对牛的描述更加的复杂而没有准确性。程序也时这样,当没用的责任增加,就会让相应的类都变得臃肿腐臭。当我们要添加牛要耕后要吃草,耕地机耕地后要加油时,继续往农活接口中添加,这样使得农活什么都能干,使得后期修改维护等难度太大。

  • 如果不分离责任,在不断变化和添加的需求面前,责任之间耦合度强导致我们的程序更加的脆弱

                                                 
如上图将两个责任分离,牛实现耕水田的时候,不会知道也不会去在意耕菜地,分离了责任,该做的才做,不做的不用管。

例子二:

      电话这玩意,是现代人都离不开的。电话通话的时候有四个过程发生:拨号、通话、回应、挂机。如下面的接口代码:

interface IPhone {
  void dial(String pno);//拨号
  void chat(Object o);//发送消息
  void hangup();//挂断
}

       大家看下这个接口有没有问题?我相信大部分读者都会说没有问题呀,我就是这么做的呀。是的,这个接口几乎没有问题。但是,单一职责原则要求一个接口或类只有一个原因引起变化,也就是一个接口或类只有一个职责。

       这个接口中显示了两个职责,一个是连接管理,一个是数据通信。dial和hangup函数进行调制解调器的连接处理,而chat函数进行数据的通信。

这两个责任应该被分开吗?这决定于应用程序以何种方式变化。如果应用程序的变化会影响连接函数的部署,那么这个设计就具有僵化性的臭味。因为调用send和recv的类必须要重新编译连接处理函数,部署的次数常常会超过我们希望的次数。在这种情况下,这两个职责应该被分离。如图下图所示,这样避免了客户应用程序和这两个职责耦合在一起。

       如果应用程序的变化方式总是会导致两个职责同时变化,那么就不必分离他们,分离后会导致不必要的复杂性。

总结

  • SRP为最简单的原则,也是最难运用好的原则
  • 软件设计真正要做的其实就是发现责任并把那些责任分离
  • 其他原则都将能追溯到SRP
  • 大道至简,只有不断在代码中运用才能真正体会其中的奥妙

 

参考

[1]《设计模式之》第1章 单一职责原则

转载于:https://my.oschina.net/u/3488327/blog/1490398

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单一职责原则(Single Responsibility Principle,SRP)是面向对象设计中的一个重要原则。它要求一个类或模块应该只负责完成一个职责或功能。换句话说,一个类应该只有一个引起它变化的原因。 在Java中,我们可以通过以下几种方式来遵循单一职责原则: 1. 将不同的职责分离到不同的类中:将一个类中的多个职责拆分成多个类,每个类只负责一个职责。这样可以提高代码的可维护性和可扩展性。 2. 使用接口进行解耦:通过定义接口,将不同的职责分离开来,使得类之间的依赖关系更加松散。这样可以降低类之间的耦合度,提高代码的灵活性。 3. 使用设计模式:设计模式是一种经过验证的解决特定问题的方案。在遵循单一职责原则时,可以使用一些设计模式,如策略模式、观察者模式等,来将不同的职责分离开来,使得代码更加清晰和可维护。 下面是一个示例代码,演示了如何在Java中遵循单一职责原则: ```java // 负责处理用户信息的类 class UserInfoHandler { public void saveUserInfo(UserInfo userInfo) { // 保存用户信息的逻辑 } } // 负责发送邮件的类 class EmailSender { public void sendEmail(String email, String message) { // 发送邮件的逻辑 } } // 负责生成报表的类 class ReportGenerator { public void generateReport(List<Data> dataList) { // 生成报表的逻辑 } } ``` 在上面的示例中,我们将处理用户信息、发送邮件和生成报表这三个不同的职责分别放在了不同的类中,每个类只负责完成一个职责。这样可以使得代码更加清晰和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值