zoukankan      html  css  js  c++  java
  • 单一职责原则

    定义:

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

    何为职责?

          

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

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

    例子一:

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

                                                  

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

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

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

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

                                                            

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

    例子二:

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

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

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

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

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

     

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

    总结

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

    参考

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

    转载请注明出处:http://www.cnblogs.com/jiansen/
  • 相关阅读:
    Java实现第十届蓝桥杯旋转
    Java实现第十届蓝桥杯旋转
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯质数
    【JSP EL】EL表达式获取当前时间(两种方式)
    23种设计模式总结
  • 原文地址:https://www.cnblogs.com/jiansen/p/7343882.html
Copyright © 2011-2022 走看看