美文网首页初见
软件构造之【设计模式篇】设计七原则(下)

软件构造之【设计模式篇】设计七原则(下)

作者: 乐音X | 来源:发表于2020-06-07 18:46 被阅读0次

    四、单一职责原则

    单一职责原则又叫单一功能原则(single responsibility principle, SRP)。它是说,一个对象的功能应该尽可能地单一。提出这个原则有多方面的考虑,其中最重要的是,这样的话,对象的改变就只会有一个原因(There should never be more than one reason for a class to change)。

    如果实现了单一职责原则,其好处是显而易见的,由于类的功能单一,使得设计更加简单、代码可读性和可维护性提高、更容易调试、对象变更引起的风险也会降低。

    实际上,这就是各司其职的思想,将对象解耦、提高内聚性。例如管理国家,不仅仅只有一个皇帝或者宰相鞠躬尽瘁,吏户礼兵刑工六部都得分担、各司其职,这样才能权力分明(对象的功能明确)、责任分明(知道出错的代码在哪里)。

    实现这个原则,类的粒度也会降低(因为管的事儿更少了嘛,自然不需要长篇大论了)

    五、接口隔离原则

    接口隔离原则(interface segregation principle, ISP),是指不应该使用过于庞大臃肿的接口,而应该把它们拆分成各司其职的各个小接口,以提供更加灵活、简洁的调用方式。

    其实这个原则是很实用的。我曾经有过这样的经验,在对现实世界进行建模时,有几个事物具有很多共性,然后我就想用一个统一的接口来作为它们的抽象。可是,这些事物又有不同的功能,因此我的接口就必须将所有的方法都涵盖进去,最后,这个接口就变得无比臃肿,到使用的时候,每个具体类又都有用不到的地方,但接口中的每个方法都得实现,就造成了很多冗余代码。这里我至少犯了两个错误,一个是使得我的代码太过冗杂,可读性下降;另一个是我将这些事物都抽象成一个接口,这样导致它们之间的关系不明确。但是,它们之间又没有上下级抽象的关系,也就是说它们是平级的,这怎么办?

    这里,接口隔离原则就派上用场了,我们将不同的功能所需要的方法定义在不同的接口中,然后每一个具体类都只实现自己需要的那些接口,这样我即不用通过多谢代码来规避不需要的方法,又可以通过看大家都实现了哪些接口来明确它们之间的关系(比如它有这个功能、没有这个功能,而另一个两个功能都有,但是没有另一种功能等等)。也就是说,实现接口隔离原则,也给我们提供了描述同级关系的方法(继承和实现都是上下级关系),这能够让我们的软件架构更加清晰。

    从设计师的角度来看,提供描述同级关系的功能,才是接口隔离原则最重要的作用,因为它使得软件设计弥补了继承和实现只能描述上下级关系的不足。

    六、迪米特法则

    迪米则法则原文是Law of Demeter,它也叫做最小知识原则(Least Knowledge Principle)。它的核心思想是,类与类只有在直接联系的时候才相互建立方法来访问(Talk only to your immediate friends and not to strangers)。

    这个法则可以借用画图来理解。假设每一个类都是图中的一个点,那么如果两个类之间可以直接相互作用(一个类调用或访问另一个类),就把代表它们的两个点连上线。这样一个极端就是每两个点之间都有一条线,这个图会变得非常复杂,而且牵一发而动全身,要修改一个点的话,连接这个点的线都得修改,实质上是高耦合。而迪米特法则是另一个极端,也就是只有两个类直接相互作用才建立方法,对应到图中就是只保留必要的线,这样这个图就简单多了,修改起来也容易。遵循这种法则,会提高内聚性而降低耦合性。

    但是,这个法则是一个极端,极端总是不好的。迪米特法则实质上是一种思想,即只保留必要的访问和修改方法。如果我们走了极端,那就会导致大量中间类的产生,增加复杂性且降低通信效率,反而不美。

    做到迪米特法则需要注意几点,这里提一下比较经典的一点,即建立set/get方法而不直接暴露内部属性。

    七、合成复用原则

    合成复用原则(Composite Reuse Principle)也叫组合/聚合复用原则(Composition/Aggregation Reuse Principle)。它的思想非常简单,就是合成优于继承。在基础类的基础上创造新类有两种方法,一种是用子类继承,另一种是创造新类并把基础类作为新类的一个属性,而合成复用原则就是在说这两种复用类的方法中,第二种优于第一种。

    我们分析一下为什么。继承这种关系是比较密切的,子类很大程度上受父类影响,而且父类的大部分内容都暴露给了子类,这是一种耦合度比较高且不甚灵活的关系。组合或者说合成、聚合,它们都只是一种关联关系,耦合度比较低,你看,假若基础类是新类的一个属性,那么新类只能通过基础类的各种public属性的方法对基础类进行操作,这样基础类内部的改变不会影响新类(只要接口不变就行了),新类对基础类的调用也更加灵活。

    总结

    我们介绍了七个软件设计原则

    1 开闭原则 软件设计的大纲,指出了软件设计和代码复用的基本指导思想:易扩展、难修改

    2 里氏替换原则 关注的是开闭原则中的“开”即扩展,主要阐明代码复用中如何设计好继承关系

    3 依赖倒置原则 关注的是开闭原则中的“开”即扩展,涵盖里氏替换原则但高度更高,强调了接口和抽象类的重要性

    4 单一职责原则 关注的是开闭原则中的“闭”即修改,认为类的功能应尽可能单一,这样修改导致的错误会更少且易                            于发现

    5 接口隔离原则 认为粒度更小(适中)的接口由于庞大臃肿的接口,易于描述平级关系、调用更加灵活

    6 迪米特原则 也叫最小知识原则,认为类与类之间应该只保留最直接的联系,这才能使软件架构清晰且易于扩展

    7 合成复用原则 认为合成优于继承,因为合成的耦合度更低、扩展更简单、使用更灵活

    这些软件设计原则是软件设计模式的基础,掌握这七种设计原则及其思想,剩下的设计模式只是对它们的实践和具体化,学习便可一蹴而就。

    相关文章

      网友评论

        本文标题:软件构造之【设计模式篇】设计七原则(下)

        本文链接:https://www.haomeiwen.com/subject/iqzuzhtx.html