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

总结理解


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

举例说明


场景需求

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

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

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

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

public class Cow implements Animal {
@Override
public void makeSound() {
// TODO Auto-generated method stub
System.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()方法。这种松耦合的设计理念提高了代码的复用度,需要扩展的时候也很方便。想在替换原有类型的时候也很方便,提高了可维护性。

对“针对接口编程,而不是针对实现编程”的理解的更多相关文章

  1. ZT 针对接口编程而不是针对实现编程

    java中继承用extends 实现接口用 implements 针对接口编程而不是针对实现编程 2009-01-08 10:23 zhangrun_gz | 分类:其他编程语言 老听说这句,不知道到 ...

  2. 针对接口编程能帮助达到面向对象开发和设计中"低耦合"的要求. 某公司...打印机...(笔试中遇到的题目)

    针对接口编程能帮助达到面向对象开发和设计中"低耦合"的要求.         举个例子:某公司有一台特殊打印机,还可以使用一年,一年后可能换为另一种打印机,这两种打印机都特殊而贵. ...

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

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

  4. struts2针对mvc的框架 spring针对解耦与事务的框架

    struts2针对mvc的框架 spring针对解耦与事务的框架

  5. 设计模式之Programming to an Interface, not anImplementation 程序指向接口,而不是实现

    Class inheritance is basically just a mechanism for extending an application's functionality by reus ...

  6. python学习之flask接口开发,环境变量扩展,网络编程requests

    python基础 flask之mock接口 所谓mock接口,其实就是我们在正式接口还没联调或者是测试接口没有正式使用时,自己创建一个模拟接口,来供项目暂时打通功能或者测试流程梳理的桥梁,而我们这儿使 ...

  7. 我面向 Google 编程,他面向薪资编程

    面试官:同学,说一说面向对象有什么好处? 神仙开发者:我觉的面向对象编程没有什么好处. 面试官:为什么(摊手.问号脸)? 神仙开发者:因为在面向对象的时候,我对象总是跟我说话,问我在淘宝上挑的衣服哪个 ...

  8. [.net 面向对象编程基础] (2) 关于面向对象编程

    [.net 面向对象编程基础]  (2)  关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问 ...

  9. 学习响应式编程 Reactor (1) - 响应式编程

    响应式编程 命令式编程(Imperative Programing),是一种描述计算机所需做出的行为的编程范式.详细的命令机器怎么(How)去处理以达到想要的结果(What). 声明式编程(Decla ...

随机推荐

  1. pipe----管道

    #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h&g ...

  2. ON COMMIT PRESERVE ROWS

    定义声明式全局临时表的每个会话拥有自己的独特的临时表描述.当会话终止时,表行和临时表描述均会被删除. 有如下选项,可控制commit后临时表的状态: ON COMMIT DELETE ROWS:在执行 ...

  3. C# 中判断字符串是不是汉字

    //1.用ASCII码判断 //在 ASCII码表中,英文的范围是0-127,而汉字则是大于127,具体代码如下: string text = "是不是汉字,ABC,柯乐义"; ; ...

  4. 本地Eclipse连接HDFS进行简单的文件操作

    昨天总结了一点自己在搭建Hadoop完全分布式环境过程中遇到的几个小问题以及解决方案,今天在搭建成功的环境中进行了简单的文件操作,包括:文件目录的创建.文件的创建.本地文件的上传.文件的重命名.文件的 ...

  5. Dubbo源码学习--服务是如何发布的

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 ServiceBean ServiceBean 实现ApplicationListener接口监听Conte ...

  6. 办理西蒙菲莎大学(本科)学历认证『微信171922772』SFU学位证成绩单使馆认证Simon Fraser University

    办理西蒙菲莎大学(本科)学历认证『微信171922772』SFU学位证成绩单使馆认证Simon Fraser University Q.微信:171922772办理教育部国外学历学位认证海外大学毕业证 ...

  7. Docker集群实验环境布署--swarm【6 配置上层Nginx代理,让任意Docker client访问得到高可用的管理API】

    10.40.42.10上,也就是对应的VRRP中的10.40.42.1和2上,配置nginx tcp代理   # cat 4000_manager.venic.com_10.40.100.141-14 ...

  8. winServer2008添加IIS服务

    右键我的电脑,选择管理,打开服务器管理器 点击左边菜单栏角色调出角色窗口 接着点击添加角色,弹出添加角色向导 点击下一步进入服务器角色选项 勾选Web服务器(IIS),点击下一步 出现 点击下一步,出 ...

  9. webpack + vue最佳实践

    webpack + vue最佳实践 我的原文地址:http://www.xiaoniuzai.cn/2016/10/04/webpack%20+%20vue%E6%9C%80%E4%BD%B3%E5% ...

  10. 驱动7段LED显示器

    拿到7段LED显示器,先看看是共阴极还是共阳极,如果是共阳极,3和8接5V,5V串联一个220欧姆的电阻. 下面是购买的LED显示器的接线图例 5V串联电阻图例 下面为代码,此代码将实现在LED显示器 ...