单一职责原则

设计模式三大分类

(1)创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

(2)结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

(3)行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

    定义:不要存在多于一个导致类变更的原因,即一个类只负责一项职责

    问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。

    解决方案:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。当修改类T1时,不会使职责P2发生故障风险;当修改T2时,也不会使职责P1发生故障风险。

   职责扩散会导致不遵循单一职责原则

   职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2

   用一个类描述动物呼吸这个场景:

class Animal{
    public void breathe(String animal){
        System.out.println(animal+"呼吸空气");
    }
}
public class Client{
    public static void main(String[] args){
        Animal animal = new Animal();
        animal.breathe("");
        animal.breathe("");
        animal.breathe("");
    }
}
View Code

     程序上线后,发现问题了,并不是所有的动物都呼吸空气的,比如鱼就是呼吸水的。修改时如果遵循单一职责原则,需要将Animal类细分为陆生动物类Terrestrial,水生动物Aquatic,代码如下:

class Terrestrial{
    public void breathe(String animal){
        System.out.println(animal+"呼吸空气");
    }
}
class Aquatic{
    public void breathe(String animal){
        System.out.println(animal+"呼吸水");
    }
}
 
public class Client{
    public static void main(String[] args){
        Terrestrial terrestrial = new Terrestrial();
        terrestrial.breathe("");
        terrestrial.breathe("");
        terrestrial.breathe("");
        
        Aquatic aquatic = new Aquatic();
        aquatic.breathe("");
    }
}
View Code

    我们会发现如果这样修改花销是很大的,除了将原来的类分解之外,还需要修改客户端。而直接修改类Animal来达成目的虽然违背了单一职责原则,但花销却小的多,代码如下:

class Animal{
    public void breathe(String animal){
        if("".equals(animal)){
            System.out.println(animal+"呼吸水");
        }else{
            System.out.println(animal+"呼吸空气");
        }
    }
}
 
public class Client{
    public static void main(String[] args){
        Animal animal = new Animal();
        animal.breathe("");
        animal.breathe("");
        animal.breathe("");
        animal.breathe("");
    }
}
View Code

     可以看到,这种修改方式要简单的多。但是却存在着隐患:有一天需要将鱼分为呼吸淡水的鱼和呼吸海水的鱼,则又需要修改Animal类的breathe方法,而对原有代码的修改会对调用“猪”“牛”“羊”等相关功能带来风险,也许某一天你会发现程序运行的结果变为“牛呼吸水”了。这种修改方式直接在代码级别上违背了单一职责原则,虽然修改起来最简单,但隐患却是最大的。 

    还有一种修改方式:

class Animal{
    public void breathe(String animal){
        System.out.println(animal+"呼吸空气");
    }
 
    public void breathe2(String animal){
        System.out.println(animal+"呼吸水");
    }
}
 
public class Client{
    public static void main(String[] args){
        Animal animal = new Animal();
        animal.breathe("");
        animal.breathe("");
        animal.breathe("");
        animal.breathe2("");
    }
}
View Code

    实际应用中的类都要复杂的多,一旦发生职责扩散而需要修改类时,除非这个类本身非常简单,否则还是遵循单一职责原则的好。

遵循单一职责原的优点有:

  • 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
  • 提高类的可读性,提高系统的可维护性;
  • 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

 

 

参考:

https://blog.csdn.net/zhengzhb/article/details/7278174

 
posted on 2018-09-20 12:28  溪水静幽  阅读(111)  评论(0)    收藏  举报