设计模式六大原则(1)--单一职责原则

定义:

  一个类,只有一个引起它变化的原因。通俗的来说就是一个类只负责一项职责。

问题由来:

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

解决方案:

  遵循单一职责原则,设计两个类T1和T2,T1负责完成职责P1,T2负责完成P2。当P1变动需要修改T1时不会影响T2;同理,当P2变动需要修改T2时不会影响T1。这样,T1与T2之间职责不同,独立存在,因此无论修改哪一项的实现功能都不会影响另一方的职责。

  说到单一职责原则,很多人可能会不屑一顾,因为它实在是太简单了。稍微一个人即使他不懂设计模式,不知道单一职责原则,在设计类的时候也知道自觉遵守这一原则,因为这是常识,哈哈。在软件编程过程中,谁也不想因为修改了某个功能而使另外其他的功能出现问题,显然遵循单一职责原则很重要。既然这样,那又为什么很多经验丰富的程序员也会犯这个错误(违背单一职责原则)呢?这是因为有职责扩散。所谓的职责扩散是指由于某种原因,职责P被分化为粒度更细的职责P1和P2。

  比如,类T只负责职责P,这是符合单一职责原则的。但是,由于需要变更或者是开发者的层次提高了,需要将职责P分化为粒度更新的职责P1、P2,按照单一职责原则,需要设计两个类分别完成职责P1和P2,但是由于实现P职责的代码已经写好的情况下,这样做就太浪费时间了。于是,直接在T类中修改添加,实现职责P1和P2,这样是比较简单的(显然,这违反了单一职责原则)。但是这样的风险就是由于职责扩散的不确定性,我们不确定是否将来职责P会扩展为P1、P2、P3…Pn。记住,在职责扩散到我们无法控制之前,要立即果断的将代码重构。

  举例说明一下,比如用类描述动物呼吸这个场景(注意演示使用的类比较简单,实际应用的类要复杂得多),代码如下所示:

class Animal
    {
        public void Breathe(string animal)
        {
            Console.WriteLine(animal + "呼吸空气");
        }
    }
    class Client
    {
        static void Main(string[] args)
        {
            var animal = new Animal();
            animal.Breathe("猪");
            animal.Breathe("狗");
            animal.Breathe("牛");
            animal.Breathe("羊");
            Console.ReadKey();
        }
    }

  运行结果如下所示:

  程序上线了,发现并不是所有动物都是呼吸空气的,比如鱼就是呼吸水的。这样一来,按照单一职责原则要设计两个类:陆生动物类Terrestrial,水生动物Aquatic,代码如下:

class Terrestrial
    {
        public void Breathe(string animal)
        {
            Console.WriteLine(animal + "呼吸空气");
        }
    }
    class Aquatic
    {
        public void Breathe(string animal)
        {
            Console.WriteLine(animal + "呼吸水");
        }
    }
    class Client
    {
        static void Main(string[] args)
        {
            var terrestrial = new Terrestrial();
            terrestrial.Breathe("狗");
            terrestrial.Breathe("牛");
            terrestrial.Breathe("羊");
            var aquatic = new Aquatic();
            aquatic.Breathe("鱼");
            Console.ReadKey();
        }
    }

  运行结果如下:

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

class Animal
    {
        public void Breathe(string animal)
        {
            if("鱼".Equals(animal))
                Console.WriteLine(animal + "呼吸水");
            else
            Console.WriteLine(animal + "呼吸空气");
        }
    }
    class Client
    {
        static void Main(string[] args)
        {
            var animal = new Animal();
            animal.Breathe("狗");
            animal.Breathe("牛");
            animal.Breathe("羊");
            animal.Breathe("鱼");
            Console.ReadKey();
        }
    }

  运行结果如下:

  可以看到,这样修改时最简单的。但是,若有一天,需要区分呼吸淡水和海水的鱼,就要在修改对应Breathe方法了,这种修改直接可能会影响牛、羊等原来正确执行的参数,可能会出现羊呼吸水这样的结果。在这种代码级别上违反单一职责原则是最严重的错误,这个必须要严格避免,因为隐患最大。来看另一种修改方式,代码如下所示:

class Animal
    {
        public void Breathe1(string animal)
        {
            Console.WriteLine(animal + "呼吸空气");
        }

        public void Breathe2(string animal)
        {
            Console.WriteLine(animal + "呼吸水");
        }
    }
    class Client
    {
        static void Main(string[] args)
        {
            var animal = new Animal();
            animal.Breathe1("狗");
            animal.Breathe1("牛");
            animal.Breathe1("羊");
            animal.Breathe2("鱼");
            Console.ReadKey();
        }
    }

  运行结果如下所示:

  这种改动方法在原来的基础上添加了一个方法,在代码级别上违背了单一职责原则,但在方法级别上却遵循了单一职责原则。上面的这3种方式各有自己的特点,实际项目中该使用哪一种,这个真的不好说,要根据具体项目具体需求而定。个人建议就是:只有逻辑足够简单,才可以在代码级别上不遵循单一职责原则;只有类中方法足够少时,才可以在方法级别上不遵循单一职责原则。

  上面介绍使用的例子比较简单,所以无论是在代码级别还是在方法级别违背单一职责原则都不会造成太大影响。但在实际项目开发过程中,实际应用的类要复杂的多,一旦有职责扩散发生,除非这个类很简单,否则一定要遵循单一职责原则来设计的好。

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

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

  需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。

设计模式六大原则(1)--单一职责原则

时间: 2024-10-12 11:52:50

设计模式六大原则(1)--单一职责原则的相关文章

学习设计模式 - 六大基本原则之单一职责原则

设计模式总共有六大基本原则,统称为SOLID (稳定)原则,分别是S-单一职责原则(Single Responsibility Principle), O-开闭原则(Open closed Principle),L-里氏替换原则(Liskov Substitution Principle),L-迪米特法则(Law of Demeter),I-接口隔离原则(Interface Segregation Principle),D-依赖倒置原则(Dependence Invension Principl

面向对象编程6大设计原则:单一职责原则

单一职责原则(Single  Responsibility Principle)简称SRP原则. 定义 应该有且仅有一个原因引起类的变更. 优点 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多: 提高类的可读性,提高系统的可维护性: 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响. 说明 单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则: 单一职责原则要根据项目的实际情

面向对象设计原则:单一职责原则(The Single Responsibility Principle)

热爱生活.享受娱乐.专注技术,欢迎关注微信公众号QGer,我们一起见证成长! 什么是单一职责原则? - 官方解释:一个类应该只有一种改变的原因 - 通俗解释:一个类被修改.拓展的时候,应该只能因为一种职责(功能)的扩展,而不应该有第二种职责导致类的修改,一个也不能有另一种职责存在. 为什么遵循单一职责原则? 降低类的复杂度,一个类负责一种职责,逻辑上也变得直观简单. 使代码变得灵活,提高系统的维护性. 变更的风险降低,有需求就会有变更,单一职责原则可降低变更的影响面. 保持松耦合,提供内聚. 如

设计模式六大原则之单一职责原则

一.什么是设计模式 设计模式:设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.由此可见,设计模式不是代码复用而是经验复用.是代码设计的经验总结. 设计模式的六大原则:[单一职责.里氏替换.依赖倒置.接口隔离.迪米特法则.开闭] 23中常用的设计模式: [单例模式.工厂模式.抽象工厂模式.模板模式.代理模式.建造者模式.原型模式.中介者模式. 命令模式.装饰模式.策略模式.责任链模式.适配模式.迭代器模式.组合模式.观察者模式.备忘录模式

设计模式(三)面向对象设计原则之单一职责原则

引用自:http://blog.csdn.net/lovelion  作者:刘伟 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小.单一职责原则定义如下: 单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责, 或者可以定义为:就一个类而言,应该只有一个引起它变化的原因. 单一职责原则告诉我们:一个类不能太"累"!在软件系统中,一个类(大到模块,小到方法)承担的 职责越多,它被复用的可能性就越小,而

面向对象五大原则_1.单一职责原则&2.里氏替换原则

单一职责原则:Single Responsibility Principle (SRP) 一个类.仅仅有一个引起它变化的原因.应该仅仅有一个职责.每个职责都是变化的一个轴线.假设一个类有一个以上的职责,这些职责就耦合在了一起.这会导致脆弱的设计.当一个职责发生变化时,可能会影响其他的职责.另外,多个职责耦合在一起,会影响复用性. 比如:要实现逻辑和界面的分离. T负责两个不同的职责:职责P1.职责P2.当因为职责P1需求发生改变而须要改动类T时.有可能会导致原本执行正常的职责P2功能发生问题.

day01_面向对象五大原则_1.单一职责原则&2.里氏替换原则

单一职责原则:Single Responsibility Principle (SRP) 一个类,只有一个引起它变化的原因.应该只有一个职责.每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起.这会导致脆弱的设计.当一个职责发生变化时,可能会影响其它的职责.另外,多个职责耦合在一起,会影响复用性.例如:要实现逻辑和界面的分离. T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障.也就是

设计原则之单一职责原则

定义:一个类只负责一项职责,应该只有一个能引起它变化的原因. 问题:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常 的职责P2功能发生故障. 解决:分别建立两个类T1.T2,使T1完成职责P1功能,T2完成职责P2功能.这样,当修改类T1时,不会使职责P2发生故障风险: 同理,当修改T2时,也不会使职责P1发生故障风险. 举个栗子:介绍几种动物的栖息地和食物,这里边有两项职责:栖息地和食物. 用一个类Recommend介绍牛生活在

6大设计原则(1):单一职责原则

定义:应该且仅有一个原因引起类的变更. 理解: 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力, 这种耦合会导致脆弱的设计.当变化发生时,设计会遭受到意想不到的破坏. 假如一个类A,有两个职责a,b,当职责a由于需求发生变化而需要修改时,有可能会导致职责b的功能发生故障. 解决: 将类中的职责分开,分别建立两个类. 如果是面向接口编程的话,就是将两个职责抽象成为两个不同的接口,原接口再实现这两个接口. 单一职责原则的好处: 1.类的

面向对象设计原则之单一职责原则(SRP)

Web程序猿博客:http://blog.csdn.net/thinkercode 这条原则曾经在 Tom DeMaro 和 Meilir Page-Jones 的著作中描述过,并称之为内聚性(cohesion).他们把内聚性定义为:一个模块的组成元素之间的功能相关性. 单一职责原则(SRP) 单一职责原则(Single Responsibility Principle, SRP):就一个类而言,应该仅有一个引起它变化的原因. 单一职责的原则告诉我们:在软件系统中,如果一个类承担的职责过多,就等