对“针对接口编程,而不是针对实现编程”的理解

今天在阅读《Head First设计模式》的时候,看到了这句话:“针对接口编程,而不是针对实现编程”,第一次见到的时候,不太清楚作者想表达的意思,想着到后来看看实例就懂了。没想到后面阅读时,发现作者反复提及这句话,我不得不停下来,仔细思考一下这句话的意义所在。

总结理解


其实“针对接口编程,而不是针对实现编程”这句话正是利用了Java语言中的多态。编程时针对超类型(父类)进行编程,也就是说变量的声明类型(或方法的返回类型)是超类型,而不是具体的某个子类。超类型中的各个方法的具体实现不在超类型中,而是在各个子类中。这样在程序执行时可以根据实际状况执行到真正的(某个子类)行为。这样带来的好处是,我们在声明一个变量时无需关心以后执行时的真正的数据类型是哪种(某个子类类型),这是种解耦合(松耦合)的思想。我们之后维护的时候可以随时将声明的变量替换为真正需要要执行的类型,具有很高的可维护性和可扩展性。所以其实我们还可以换个说法:“针对超类型编程”,超类型则通常是接口或是一个抽象类。这么说可能这还是比较抽象,我习惯性举个例子来感受下。

举例说明


场景需求

首先,假设我们有一个如下的场景需求:饲养场里面有几种动物,牛、猪和鸡。你现在带着你的小孩子过来,想让他感受下每个动物的叫声是啥样子的,于是你就有这样的一个需求,拉来一种动物,就听下它的叫声。

三种动物有一些共同特点,比如都有质量、都会叫、都会跑...我们现在可以先设计个Animal父类,此处我们只需要考虑叫声,所以简单构造如下(具体到每种动物叫声都不一样,所以做成接口形式,各个动物可以自己去实现):

public interface Animal {......public void makeSound();
}

具体到“牛”,来单独实现其叫声方法makeSound():

public class Cow implements Animal {@Overridepublic void makeSound() {// TODO Auto-generated method stubSystem.out.println("哞哞~");}
}

猪--Pig和鸡--Chicken与之类似,就不列举了。现在我们构造完成了,那么如何做到来一种动物,就听到其叫声呢?

针对实现编程

首先我们来“针对实现编程”,假设我们调用hearSound来听到每种动物的发声。现在,先来了一只牛,我们想听到其声音,可以把hearSound()编写如下:

public void hearSound(Cow cow) {cow.makeSound();}

调用这个方法来发声: hearSound(new Cow());

然后又来了一只鸡,我们想听其声音,就需要再编写一个针对鸡的hearChickenSound:

public void hearChickenSound(Chicken chicken) {chicken.makeSound();}

调用这个方法来发声:  hearChickenSound(new Chicken());

这就是说,每想听到一种动物的声音,你就得去新建一个与该动物相关的hearSound()方法,原来的方法没法复用,因为你已经在原来的方法里写死了只能是“牛”发声。每一个hearSound()方法与每种动物紧耦合,扩展起来不方面(可能每个heardSound方法都得去扩展相应的功能)。而且,假如我原来是只想听“牛”叫,就写个hearSound(Cow cow)方法就行了。现在不想听了,只想听“鸡”叫,那么就得修改掉hearSound()方法,还有曾经所有调用过hearSound()方法的也需要进行相应的修改,可见这种设计维护起来也很差劲。

针对接口编程

既然上述“针对实现编程”有诸多问题,就得寻找解决方式,“针对接口编程”的好处也就显现出来。我们来看看上述场景需求下,“针对接口编程”如何来实现。

Animal类还是与上述一样的,每种动物还是各自实现其makeSound()方法。不同的是,在设计hearSound()方法的时候,我们的参数设计成Animal接口,而不是具体的某种动物(牛、鸡或猪):

public void hearSound(Animal animal) {animal.makeSound();}

这样,来了一头“牛”,我们可以这样调用: hearSound(new Cow()); ,

继续来了一只鸡,我们还可以这样调用: hearSound(new Chicken()); 。

由于hearSound()方法定义的时候调用的是接口,我们无需关心以后执行时的真正的数据类型是哪种。而在实际调用时,我们可以传入实现了Anima接口的任意一种子类(牛、鸡或猪),而且hearSound()中调用的makeSound()方法也是真正传入的类型的makeSound()方法。这种松耦合的设计理念提高了代码的复用度,需要扩展的时候也很方便。想在替换原有类型的时候也很方便,提高了可维护性。

所以针对接口编程的真正意义是针对超类型编程!!!!

文章出处:https://www.cnblogs.com/gavinzhang/p/6051821.html

对“针对接口编程,而不是针对实现编程”的理解相关推荐

  1. 设计原则 —— 针对接口编程而不针对实现编程

    对"针对接口编程,而不是针对实现编程"的理解 应该针对接口编程 而不是针对实现编程 0. 理解 接口,定义了一堆空实现函数的接口,如下,是对其全部实现类的约束,即必须实现我(接口) ...

  2. 从针对接口编程到依赖注入

    1.概况说明 2.猫狗大战举例 3.说明为什么要针对接口编程,优点 4.说明为什么要"依赖抽象,不要依赖具体类" 5.说明"依赖倒置"与抽象工厂模式 6.说明& ...

  3. 针对接口编程,不要针对实现编程

    这个OO设计原则,策略模式中也有运用,先参照代码和代码注释简单了解一下: public abstract class Cat {IEatBehavior pEatBehavior; // 用接口定义一 ...

  4. 设计引导---不要再盲目的new了!你要学着针对接口编程!(具体方法,Factory,Abstract Factory)...

    应园友提议,本篇博将帮助大家解决"针对接口编程"这一疑惑.而我所讲的例子将从上一篇设计引导---一个鸭子游戏引发的设计(多态,继承,抽象,接口,策略者模式)的案例中,延伸下来,让大 ...

  5. 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)

    访问控制是针对类而不是针对对象 先看几个标准定义 A member of a class can be - private; that is, its name can be used only by ...

  6. [一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念...

    本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍 什么是函数式编程?   java程序员第一反应可能会理解成类的成员方法一类的东西 此处并不是这个含义,更接近是数学上的函数 ...

  7. java中函数是什么_[一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念...

    本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍 什么是函数式编程? java程序员第一反应可能会理解成类的成员方法一类的东西 此处并不是这个含义,更接近是数学上的函数 看 ...

  8. 解答为什么@Autowired使用在接口上而不是实现类上

    如果Spring配置了<context:component-scan base-package="com.*.service"></context:compone ...

  9. 穿透版CTP综合交易平台接口V2.0-程序化交易编程模板(VC源码)

    期货程序化VC++ .做最好用的程序化交易软件. 最快的交易速度.最简单的交易策略编写.高级语言竟然如此简单! void MA_CROSS_Trade(CThostFtdcDepthMarketDat ...

最新文章

  1. python创建图片对应的csv格式_Python:如何从csv文件创建图形节点和边?
  2. OpenStack 架构图
  3. Functional Language
  4. Bootstrap框架系列 - 初识
  5. terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr
  6. 数据中台送到家 企业数字化转型“输血”变“造血”
  7. win10计算器rsh_Win10 内置计算器评测:PowerShell 很靠谱
  8. Spring配置中的classpath:与classpath*:的区别研究
  9. 虚拟键码对照表与ASCII对照表的整理
  10. DH参数标定原理推导
  11. RTMP/RTSP直播播放器的几种选择
  12. JRebel过期激活
  13. fw150r虚拟服务器设置,迅捷 FW150R 无线路由器端口映射设置指南
  14. Paper:2020.02.09钟南山团队首篇新冠病毒论文《Clinical characteristics of 2019 novel coronavirus infection in China》
  15. 从Scrum之父探源敏捷方法论
  16. ddgr:一个从终端搜索 DuckDuckGo 的命令行工具
  17. 2、趋势科技2017校招开发岗试题
  18. 美团一面:说说前、后端分离权限控制设计和实现思路?
  19. 个人作业2——集大通APP案例分析
  20. 谷歌找邮箱插件,外贸人必备

热门文章

  1. 索引越位:String index out of range: 1
  2. [spring boot] Table 'yhm.hibernate_sequence' doesn't exist
  3. 王者服务器维护5月1日,王者荣耀异常说明公告:5月1日全服不停机更新,游戏内问题通告说明...
  4. 定制型的OA系统要了解一下吗?
  5. Jerry Ma:期货市场反转的三个重要标志
  6. CentOS 7 中忘记密码后怎么办
  7. android 百度地图 黑屏,百度地图 Fragment之间切换黑屏现象解决方案
  8. JavaScript 绘制柱状图
  9. 微信公众平台开发--快递查询
  10. 华为畅享20怎么样 值得买吗