深入理解软件设计原则 第 7 篇

面向接口进行开发, 而不是面向实现; 依赖于抽象类 型, 而不是具体类。

如果无需修改已有代码就能轻松对类进行扩展, 那就可以说 这样的设计是灵活的。让我们再来看一个关于猫的例子, 看 看这个说法是否正确: 一只可以吃任何食物的猫 Cat 要比 只吃香肠的猫更加灵活。无论如何你都可给第一只猫喂香肠, 因为香肠是“任何食物”的一个子集;当然,你也可以喂这 只猫任何食物。

当你需要两个类进行合作时, 可以让其中一个类依赖于另一 个类。实话实说, 刚入行时我自己也常常这么做。但是, 你 可用另外一种更灵活的方式来设置对象之间的合作关系。

  1. 确定一个对象对另一对象的确切需求: 它需执行哪些方法?

  2. 在一个新的接口或抽象类中描述这些方法。

  3. 让被依赖的类实现该接口。

  4. 现在让有需求的类依赖于这个接口, 而不依赖于具体的类。

    你仍可与原始类中的对象进行互动, 但现在其连接将会灵活得多。

抽取接口前后的对比。右侧的代码要比左侧更加灵活, 但也更加复杂。

完成修改后, 你很可能没法马上看到任何好处; 相反, 代码 会变得比以前更加复杂。但如果你觉得这里可以是个不错的 额外功能扩展点, 或者其他使用这些代码的用户希望在此进 行扩展的话, 那就马上动手去做吧。

示例

让我们来看另一个例子, 它说明了通过接口与对象交互要比 依赖于其具体类的好处更多。假设你正在开发一款软件开发 公司模拟器, 而且使用了不同的类来代表各种类型的雇员。

                                       修改前:所有类都紧密耦合。

刚开始时, 公司 Company 类与具体雇员类紧密耦合。尽 管各个雇员的实现不尽相同, 但我们还是可以归纳出几个与 工作相关的方法, 并且将其抽取为所有雇员的通用接口。

此后, 我们可在 公司 类内应用多态机制, 通过雇员

Employee 接口来处理各类雇员对象。

优化:多态机制能帮助我们简化代码,但公司类的其他部分仍然依赖于具体的雇员类。

公司类仍与雇员类相耦合,这很糟糕,因为如果引入包含 其他类型雇员的公司类型的话, 我们就需要重写绝大部分的 公司 类了,不能复用其代码。

为了解决这个问题, 我们可以声明一个抽象方法来获取雇员。每个具体公司都将以不同方式实现该方法, 从而创建自己所需的雇员。

      修改后:公司类的主要方法独立于具体的雇员类。雇员对象将在具体公司子类中创建。

修改后的 公司 类将独立于各种雇员类。现在你可以对该类 进行扩展, 并在复用部分公司基类的情况下引入新的公司和 雇员类型。对公司基类进行扩展时无需修改任何依赖于基类 的已有代码。

顺便提一句, 你刚刚目睹的就是设计模式的应用! 这就是工厂方法模式的一个示例。不要担心, 稍后我会对其进行详细讨论。

推荐阅读:

单一职责原则

开闭原则

里氏替换原则

接口隔离原则

优秀软件设计的特征

面向接口进行开发,而不是面向实现相关推荐

  1. 面向过程(POP)、面向对象(OOP)、面向接口(IOP)、面向切面(AOP)

    面向过程POP 是一种以过程为中心的编程思想.这些都是以什么正在发生为主要目标进行编程,不同于面向对象的是谁在受影响. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个 ...

  2. php 面向接口,php开发app接口

    一.app接口简介:与PHP面向对象的接口不同,是通信接口地址 1.条件: 1)接口地址 2)接口文件 3)接口数据 2.如何通信 1)类似BS模式 3.客户端app通信格式区别:xml和json 1 ...

  3. 面向“接口”编程和面向“实现”编程

    英文原文:Program to an Interface, Fool 如果你已经读了我的前几篇关于面向对象范式因为受到 Rust, Go 等语言的影响而发生变化的文章,看到了我正在研究的 Rust 设 ...

  4. java的知识点13——多态、对象的转型(casting)、final关键字、抽象方法和抽象类、接口的作用、如何定义和使用接口?、接口的多继承、面向接口编程

    多态 多态指的是同一个方法调用,由于对象不同可能会有不同的行为.现实生活中,同一个方法,具体实现会完全不同. 多态的要点: 1. 多态是方法的多态,不是属性的多态(多态与属性无关). 2. 多态的存在 ...

  5. Java中的面向接口编程

    面向接口编程是很多软件架构设计理论都倡导的编程方式,学习Java自然少不了这一部分,下面是我在学习过程中整理出来的关于如何在Java中实现面向接口编程的知识.分享出来,有不对之处还请大家指正. 接口体 ...

  6. swift 组件化_打造完备的iOS组件化方案:如何面向接口进行模块解耦?

    作者 | 黑超熊猫zuik,一个修行中的 iOS 开发,喜欢搞点别人没搞过的东西,钻研过逆向工程.VIPER 架构和组件化. 关于组件化的探讨已经有不少了,在之前的文章 iOS VIPER架构实践(三 ...

  7. java继续_Java中消除实现继续和面向接口编程

    在匆忙之际理清消除实现继续和面向接口编程这样两个大题目可不是一件轻易的事情,尤其考虑到自身的熟悉水平.坦白的说,这又是一篇"炒冷饭"的文章,但这"冷饭"又确实不 ...

  8. Java中继承和面向接口的编程

    继承是面向对象中很重要的概念.如果考虑到Java语言特性,继承分为两种:接口继承和实现继承.这只是技术层面的问题,即便C++中不存在接口的概念,但它的虚基类实际上也相当于接口.对于OO的初学者来说,他 ...

  9. Spring框架(IoC、AOP面向接口切面)

    新建一个Maven工程 Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开发. ...

最新文章

  1. 示波器探头使用注意事项,示波器探头的选择
  2. 如何用asp.net实现校验功能!
  3. python写表格_使用Python对Excel进行读写操作
  4. 【OpenCV入门指南】第五篇 轮廓检测 上
  5. 工具用的好下班走的早
  6. 《改善java代码》第一章:java开发通用原则
  7. [ZJOI2010]数字计数
  8. 总结JSON.parse()报错VM71:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0等之类的问题
  9. BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)
  10. Matlab实用技巧
  11. JavaScript 字符串属性和方法
  12. 语言题库安装包312mb_大学为什么要考取计算机二级,以后很需要,附二级Msoffice题库...
  13. 木疙瘩离线版导出html,木疙瘩的功能介绍和特色
  14. Cluster-level pseudo-labelling forsource-free cross-domain facial expressionrecognition
  15. wine模拟器linux,Wine模拟器使用手册(转)
  16. 将ipad作为Windows10系统的的扩展显示屏
  17. scipy笔记—scipy.misc.imresize用法(方便训练图像数据)
  18. 打字速度单位wpm,kpm 是怎样计算的
  19. C++ QT开发人机象棋(评估函数)
  20. Pandas秘籍【第七章】

热门文章

  1. http状态码、含义大全
  2. ios sinaweibo 客户端(三)
  3. 什么是java的关键字_java中常见的关键字
  4. ReDim, split
  5. 常用的邮箱有哪些,可用好用的邮箱大全推荐 - 【比较最佳电子邮件邮箱:Zoho Mail、Outlook、ProtonMail 和 NetEase, QQ Mail】
  6. TortoiseSVN (Subversion客户端) 使用手册(中文) (六)
  7. 数据化管理洞悉零售及电子商务——零售策略中的数据化管理
  8. 95后阿里P7晒出工资单:狠补了这个,真香...
  9. VCC、VDD、VSS的区别
  10. 第二十七篇 网页数据解析三种方法: 正则表达--BeautifulSoup--xpath 满满的干货