开发者社区 > 博文 > 5 幅插图 让你轻松看懂面向对象编程的S.O.L.I.D原则
分享
  • 打开微信扫码分享

  • 点击前往QQ分享

  • 点击前往微博分享

  • 点击复制链接

5 幅插图 让你轻松看懂面向对象编程的S.O.L.I.D原则

  • 京东科技开发者
  • 2020-09-20
  • IP归属:北京
  • 74880浏览

    1.png



    如果你熟悉面向对象的编程,那么可能已经听说过SOLID原理。

     

    SOLID是针对面向对象编程和设计的五大依赖关系管理,每个字母代表另外一个三个字母的首字母缩写,用来描述一个原则。这五项软件开发原则是构建软件时要遵循的准则,以便于系统扩展和维护。这项原则得到软件工程师Robert C. Martin的赞同。

     

    在其他网站上有太多关于SOLID的精彩文章,但我很少看到带有图片的示例,这使得像我这样喜爱用图片记忆的人在学习上变得有些困难。

     

    因此,本文的主要目的是通过插图强调每种原理的目标,帮助大家更好地理解这些原理。

     

    你可能会看到,其中一些原则看起来很相似,但它们的目标并不相同。 注意!你大可以违反一个原则来满足另一个原则。

     

    为了使此操作更简单明了,我将使用“Class”一词,但请注意,本文中它也可以作为主体应用于函数、方法或模块。

     

    现在,让我们开始吧!



    S

      —Single Responsibility(单一责任)


    Class应负单一责任。

    1.png


    图释:


    • 错误示范——我是一名厨师、园丁、画家和司机;

    • 正确做法——四个Class分别担任厨师、园丁、画家和司机。


    如果一个Class承担许多职责,便会增加发生错误的可能性,因为对其中一个Class进行更改可能会在您不知情的情况下影响其他角色。

     

    目标:该原则旨在区分变量,以防由于更改而产生错误,这样以后修改就不会影响其他无关的行为啦


    O

      —Open-Closed (开闭)


    Class应当在开放的时候进行编程扩展,封闭的时候进行修改。

    1.png



    图释:


    • 错误示范——我能做”Cut”这个动作->封闭后-> 修改成能做”Paint”;

    • 正确做法——我能做”Cut”这个动作->封闭后->扩展成能做”Cut”和”Paint”两个动作。


    更改Class的当前行为将影响使用该类的所有系统。


    如果要让Class执行更多功能,理想的方法是将功能添加到已经存在的功能中,而不是直接更改Class

     

    目标:该原则旨在扩展Class的功能,而不改变特定Calss的现有功能。这是为了避免在使用Class的任何地方引起错误


    L

      — Liskov Substitution(替换)


    如果S是T的子类型,则可以将程序中类型T的Class替换为类型S的Class,这样就无需更改总程序内的任何所需属性。


    1.png



    图释:


    有一对父子Sam和Eden,有人希望Sam 做一杯咖啡

    • 错误示范——父亲Sam不在场时,工作便失效;

    • 正确做法——继承工作给儿子Eden。


    当子类无法执行与其父类相同的操作时,可能会导致错误。

     

    如果您有一个类并从中创建另一个类,则该类将成为父类,而新的类将成为子类。 子类应该能够执行父类可以做的所有事情。此过程称为继承。

     

    子类应该能够处理与父类相同的请求并提供相同的结果,或者它可以传递相同类型的结果。

     

    图中父类提供咖啡(可以是任何类型的咖啡)。 子类交付Cappucino是可以接受的,因为它是一种特殊的咖啡,但是交付水是不可接受的。

     

    如果子类别不符合这些要求,则意味着子类别已完全更改,并违反了这一原则

     

    目标:该原则旨在加强一致性,以便可以以相同的方式使用父类或其子类,而不会出现任何错误


    I

      Interface Segregation(接口隔离)

    不应强迫客户依赖他们不使用的方法

    1.png



    图释:


    • 错误示范——用混乱的方法去作排列 -> 无法使用;

    • 正确做法——用简洁的方法去作排列 -> Awesome!


    当要求一个Class执行无用的操作时,这是浪费的,并且如果该Class没有能力执行那些操作,则可能会产生意外的错误。 


    Class应仅执行其职责所需的操作。如果将来其他Class可能会负责到其他任何动作,则应将其彻底删除或移至其他位置。

     

    目标:该原则旨在将一组动作分成较小的一组,以便Class仅执行其所需的一组动作


    D

       —Dependency Inversion(依赖倒置)

    高级模块不应依赖于低级模块,两者都应取决于abstraction; 

    - abstraction不应依赖细节,细节应取决于abstraction。

    1.png


    图释:


    • 错误示范——我用特定工具来工作;

    • 正确做法——我用任何给我的工具来工作。


    首先,让我们更简单地定义此处使用的术语:

     

    • 高级模块(或Class):使用工具执行动作的Class;

    • 低级模块(或Class):执行操作所需的工具;

    • 抽象abstraction:表示连接两个Class的接口;

    • 详细信息:该工具如何工作。


    该原则表明,不应将Class与用于执行动作的工具融合在一起。而是应将其与允许工具连接到Class的接口融合。 


    它还说明,Class和接口都不应该知道工具的工作方式。但是,该工具需要满足接口规范。


    目标:该原理旨在通过引入接口来减少高级模块对低级模块的依赖性


    总结


    到目前为止,我们已经讨论了这五个原则并突出了它们的目标。它们将帮助你使代码易于调整、扩展和测试,达到完美的境界。

     

    最后,非常感谢你的阅读。 我希望你能对这个主题形成一个更好的概念,并且阅读时和我编写代码时一样开心。


    🔗原文链接:

    https://medium.com/backticks-tildes/the-s-o-l-i-d-principles-in-pictures-b34ce2f1e898


    以上信息来源于网络,由“京东智联云开发者”公众号编辑整理,不代表京东智联云立场