六大设计原则之单一设计原则

Single Responsibility Principle(SRP):单一设计原则

它规定一个类只有一个发生变化的原因。如果多余一个导致类变更的原因,则违反了SRP。

问题来源:

分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样当修改T1时,不会使职责P2发生故障风险,同理当修改T2时,也不会使P1发生故障。

但是现实中,不管是新手,还是资深程序员,经常会违反,这不仅仅是技术的问题,还有职责扩散,就是因为某种原因,职责P被分化成粒度更细的职责P1和P2.

  比如:类T只负责一个职责P,这样设计是符合单一职责原则的。后来由于业务变更,需要将P细化成粒度更细的职责P1、p2。这时如果要遵循单一职责原则,也需要将T细化成T1和T2,分别负责P1,P2两个职责。如果程序已经完成了,这样写太浪费时间。所以简单修改T,用它来负责两个职责也是可行的。虽然这样会违背单一职责原则。(这样的风险在于职责扩散的不确定性,因为我们不会想到这个职责P,未来可能会扩散为P1,P2,P3。。。,所以记住,在职责扩散到我们无法的程度之前,立即对代码进行重构)。

 
  
    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("猪");  
        }  
    }  
 
  

 

 

如上面代码,每个动物都有呼吸空气这个职责。但是现在加入新的动物鱼。它不需要呼吸空气,我们就改变将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("鱼");  
        }  
    }  

如果要遵循单一职责原则,还需要将Client也细化成两个类,这样开销太大,如果直接修改类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("鱼"); 
    }  
}  

虽然不符合单一职责原则,但是这样工作量会减少很多。但是以后如果又出现淡水鱼和海水鱼,这样又得修改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("鱼");  
        }  
    }  

可以看出,这种修改方式没有修改原来的方法,只是在原来类中新增一个方法,这样虽然也违背了单一职责原则,但是在方法级别上却是符合单一职责原则的,因为它并没有动原来方法的代码,。这三种方式各有优缺点。实际中,遵循的原则应该是:只有逻辑足够简单,才可以在代码级别上违反单一职责原则,只有类中方法数量比较少,才可以在方法级别上违反单一职责原则。

遵循单一职责原则优点:

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

单一职责原则不只是面向对象编程思想所持有的,只要是模块化的程序设计,都使用单一职责原则。

注意:单一职责原则提出了一个编写了一个编写程序的标准,用“职责”和“变化原因”来衡量接口或类设计的是否优良,但是“职责”和“变化原因”是不可度量的,因项目而异,因环境而异。

 

单一职责原则很难在项目中得到体现。在实际中,会考虑技术人员的地位和话语权,考虑环境,考虑工作量,考虑人员技术水平,考虑硬件等等,最终妥协的是精彩违背单一设计原则(如果生搬硬套单一原则,那么类的数据太多,维护困难),也许随着技术的深入,单一原则会越来越体现在项目中。

转载:http://blog.csdn.net/zhengzhb/article/details/7278174/

参考:《设计模式之禅》

 

转载于:https://www.cnblogs.com/gudulijia/p/6473425.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值