今天在阅读《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. Ubuntu12.10 下搭建基于KVM-QEMU的虚拟机环境(八)

    Libvirt 是用c写的一个管理虚拟机及其资源(如网络.存储和外设等)的工具库,它不仅支持KVM/QEMU,它还支持xen,Vmware,OpenVZ和VirtualBox等其他HyperVisor ...

  2. JVM内存模型及垃圾收集策略解析(一)

    JVM内存模型是Java的核心技术之一,之前51CTO曾为大家介绍过JVM分代垃圾回收策略的基础概念,现在很多编程语言都引入了类似Java JVM的内存模型和垃圾收集器的机制,下面我们将主要针对Jav ...

  3. Python的下载和安装

    一.下载(官方下载地址) 地址:https://www.python.org/downloads/ 我的是window7系统 二.安装详细过程 在选择安装组件的一步时,勾上所有的组件: 特别要注意选上 ...

  4. 对 Select 的各种操作(JQuery)

    在写表单时,经常要用到select元素,这个元素相较于其他文本框标签而言有不同.最近在写一个页面表单时需要对select进行各种操作,现将其用法收集并总结如下: HTML元素: <select ...

  5. 导入导出csv文件

    在工作中需要把csv文件数据导入数据库或者把数据库数据导出为csv文件.以下是我的简单的实现. <?php class csv { public $db_connection; public $ ...

  6. ssm框架中css被拦截

    最近用springmvc spring mybatis框架写程序,请求成功并获得数据,唯独css样式不能加载,但路径正确,css文件编码也是utf-8,用火狐debug总是显示未请求到(都快怀疑自己写 ...

  7. 首页导航点击A连接跳转并添加上背景色,

    <style> ul li { float: left; height: 50px; width: 120px; color: white; text-align: center; mar ...

  8. Elasticsearch 5.0 磁盘空间节省策略的认识

    前言:本文是当时QQ群员讨论磁盘空间如何优化,我搜了下类似的文章,结合官方文档做了一些总结 参考文章1 参考文章2 如果你有疑问,可以联系我参与讨论,或者去原文查看. NOTE: 磁盘空间节省问题,是 ...

  9. java的return区别

    return ;和return null的区别在于:前者当方法返回值为void时候,return ; 跳出方法. 后者当方法的返回值为object对象时,return null,跳出方法,返回值为空值 ...

  10. 【JS学习笔记】第一个JS效果——鼠标提示框

    分析效果实现原理--鼠标提示框 样式:div的display 事件:onmouseover,onmouseout 编写JS的流程 布局:HTML+CSS 属性:确定需要修改哪些属性 事件:确定用户做哪 ...