马克思曾说,运动是物质固有的根本属性,是一切物质形态的存在方式。万事万物无不在运动之中。一个好的程序不但需要经受bug的考验,还得经受时间的冲刷。那些不能够随时代而更迭的程序,无一不被时代淘汰,成为历史。

既然时代在交替,而程序在设计结束之时就完成了,那我们怎么让程序做到与时俱进呢?有一条不得不说的原则:“开放-关闭原则”(注:意为对扩展开放,对修改关闭)。要让程序能够符合这一原则,面向接口编程这一概念就呼之欲出了。

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

如同每台电脑有USB接口、充电器接口等等不同接口。同一个接口,接入的设备不同则对应的功能不同。JAVA的接口也是如此,如果我们开放了接口,程序的可拓展新就能够得到满足。举个例子:同样的“读”、“写”功能,或许U盘和MP3Player的不同,但只要它们继承了接口来重写方法,则最终在电脑里调用时都是调用read()、write()。

下面用一个例子来具体说明:

假设:现在我们要开发一个应用,模拟不同类型货车的装货与卸货。

上下文(环境):已知要实现轻型卡车(下面简称轻卡)、重型卡车(下面简称重卡)、火车三种运货设备,要求工厂能同这三种货车进行物资的装载或者卸载,并且以后可能会有新的运货机器出现,所以工厂能够装货的车型必须有扩展性,能与目前未知而以后可能会出现的货车进行物资交换。各种货车间上货、下货的实现方法不同,轻卡和重卡只有这两个方法,火车还有一个车厢分离(假设为Separating())方法。

名词定义:数据交换={装,卸}

解决方案列举

方案一:分别定义LightTruck、HeavyTruck、Train三个类,实现各自的Load()和UnLoad()方法。然后在Factory类中实例化上述三个类,为每个类分别写装,卸方法。例如,为LightTruck写Load、UnLoad两个方法。总共六个方法。

方案二:定义抽象类Trunk,在里面写虚方法Load和UnLoad,三个货运设备继承此抽象类,并重写Load和UnLoad方法。Factory类中包含一个类型为Car的成员变量,并为其编写get/set器,这样Factory中只需要两个方法:Loading_cargo和Unloading_cargo,并通过多态性实现不同移动设备的读写。

方案三:与方案二基本相同,只是不定义抽象类,而是定义接口ITrunk,三个货运类实现此接口。Factory中通过依赖接口ITrunk实现多态性。

下面,我们来分析一下以上四种方案:

  首先,方案一最容易想到和实现,but它有一个致命的弱点:可扩展性差。当将来时代变迁了,有了新的货运设备时,必须对Factory进行修改。这就如在一个真实的工厂里,为每一种货运设备修一块各自的停车场、并分别有各自的管理设施。当有了一种新的货运设备后,我们就要将原来的场地全部拆除重新划分,再给新的货运设备一块场地。这种设计显然不可取。

  此方案的另一个缺点在于,冗余代码多。如果有100种货运设备,那我们的Factory类中岂不是要至少写200个方法? It's Unacceptable.

  再看 方案二和方案三,他们基本是一个方案,只不过实现手段不同,一个是使用了抽象类,一个是使用了接口,而且最终达到的目的应该是一样的。

  首先很明显的是:它解决了代码冗余的问题。因为可以动态替换货运方式,并且都实现了共同的接口,所以不管有多少种货运方式,只要一个Load方法和一个Unload方法,多态性就帮我们解决问题了。而对第一个问题,由于可以运行时动态替换,所以有了新的设备时,完全可以替换进去运行。这就是所谓的“依赖接口,而不是依赖与具体类”,不信你看看,Factory类只有一个Trunk类型或ITrunk类型的成员变量,至于这个变量具体是什么类型,它并不知道,这取决于我们在运行时给这个变量的赋值。如此一来,Factory和Trunk类的耦合度大大下降。

  那么 这里该选抽象类还是接口呢?看动机。这里,我们的动机显然是实现多态性而不是为了代码复用,所以当然要用接口。

所以,我们选择方案三来实现:

首先编写ITrunk接口:

public interface ITrunk {void Load();        //装货void Unload();    //卸货
}

然后是三种交通工具的类,都继承ITrunk接口,并重写Load()和Unload():

public class LightTruck implements ITrunk{public void Load() {System.out.println("Load to LightTruck");System.out.println("Load finished!");}public void Unload() {System.out.println("Unload from LightTruck");System.out.println("Unload finished!");      }   }
public class HeavyTruck implements ITrunk{public void Load() {System.out.println("Load to HeavyTruck");System.out.println("Load finished!");}public void Unload() {System.out.println("Unload from HeavyTruck");System.out.println("Unload finished!");      }
}
public class Train implements ITrunk{public void Load() {System.out.println("Load to Train");System.out.println("Load finished!");}public void Unload() {System.out.println("Unload from Train");System.out.println("Unload finished!");     }   //车厢分离public void Separating(){System.out.println("The carriage is separating.");}
}

下面来写Factory类:

public class Factory {private ITrunk  trunk;public Factory() {this.trunk = null;}public Factory(ITrunk trunk) {this.trunk = trunk;}public ITrunk getTrunk() {return trunk;}//设置用何种交通工具public void setTrunk(ITrunk trunk) {this.trunk = trunk;}//工厂类实现装货public void Loading_cargo(){this.trunk.Load();}//工厂类实现卸货public void Unloading_cargo(){this.trunk.Unload();}}

到此,所有的类就写完了。结果对不对呢?我们再写一个Test类来检验一下:

public class Test {public static void main(String args[]){Factory myfac = new Factory();ITrunk  mytunk1 = new LightTruck();ITrunk  mytunk2 = new HeavyTruck();ITrunk  mytunk3 = new Train();//用三种货车来运输System.out.println("1.use LightTruck:");myfac.setTrunk(mytunk1);myfac.Loading_cargo();System.out.println("=================");System.out.println("2.use HeavyTruck:");myfac.setTrunk(mytunk2);myfac.Loading_cargo();System.out.println("=================");System.out.println("3.use Train:");myfac.setTrunk(mytunk3);myfac.Loading_cargo();System.out.println("=================");}
}

运行结果如下:

可见,结果完全符合预期。如果按照面向接口编程的思路来写程序,则程序的多态性和可扩展性都将变得容易操作。

然而,在java中还有一种机制能实现不断扩展程序的功能,更好的实现与时俱进,名唤“反射”。反射顾名思义,就如同一面镜子,它将当前已经有的类照下来,并复制一份作为副本,这个过程我们可以得到原有类的构造器及参数,得到原有类的方法,我们可以操作这个类去实现新的功能,让它成为一个新的类。

详情请看下一篇文章,程序的与时俱进之二——JAVA的反射机制。

程序的与时俱进之一——面向接口编程相关推荐

  1. 黑马java教程是什么_Java教程:揭秘什么是面向接口编程

    先用一个案例来给大家说明一下面向接口编程. 案例:有一个电脑类(Computer),电脑除了有基本的开机关机功能外,还有连接任何外接设备的功能,比如能电脑能连接外置键盘(Keyboard),鼠标(Mo ...

  2. Java面向接口编程,低耦合高内聚的设计哲学

    接口体现的是一种规范和实现分离的设计哲学,充分利用接口可以极大的降低程序中各个模块之间的耦合,提高系统的可维护性以及可扩展性. 因此,很多的软件架构设计理念都倡导"面向接口编程"而 ...

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

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

  4. Java 面向抽象编程和面向接口编程

    以下内容来自<Java 2实用教程>,主编:耿祥义.张跃平 鉴于面向抽象编程和面向接口编程思维培养的重要性,写此博客巩固. 面向抽象编程: 在设计程序时,经常会使用到abstract类,其 ...

  5. 为什么有人说面向对象编程就是面向接口编程?

    "面向对象编程就是面向接口编程" 这句话相信, 很多人都在网上见过, 装b利器. 我一开始也是这么想的, 那些装b者丢下这一句, 就没下文了. 首先, 我认为这句话是1个假命题. ...

  6. python面向接口编程_Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  7. C语言面向对象编程(四):面向接口编程

    Java 中有 interface 关键字,C++ 中有抽象类或纯虚类可以与 interface 比拟,C 语言中也可以实现类似的特性. 在面试 Java 程序员时我经常问的一个问题是:接口和抽象类有 ...

  8. python 接口编程_Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  9. 软件设计模式—面向接口编程

    原文作者:laoer2009 原文地址:设计模式之面向接口编程 01第一次需求 玩家有很多属性,例如:身高,性别 blalalala ,玩家可以攻击其他玩家.产品狗YY妹子写程序也是很利索,一天就把程 ...

最新文章

  1. springboot配置文件的加载顺序(./config目录优先级最高)
  2. 利用 Angular Directive 和 @HostBinding 实现输入文本框随着键盘输入自动变色效果
  3. ocelot 自定义认证和授权
  4. 不用ajax调用搞后台小技巧
  5. Redo Log的逻辑与物理结构
  6. 【bzoj 2541】 [Ctsc2000]冰原探险(BFS)
  7. Flash学习资源汇编
  8. 陕西省高等数学竞赛_陕西省高等数学竞赛试题答案
  9. VTD场景搭建指南-搭建一个最简单的场景
  10. 【组成原理-处理器】数据通路
  11. unef螺纹_统一螺纹(美制螺纹)UN,UNC,UNF,UNEF详细区别
  12. 二极管伏安特性曲线_二极管的温度特性
  13. 测试硬盘怀道的软件,硬盘坏道检测工具(HDDScan)
  14. HTB Doctor
  15. ggplot2读书笔记9:第六章 标度(二)
  16. python qq群自动加入_Python实现向QQ群成员自动发邮件的方法
  17. USRP B210同步采集
  18. 写在前面的一些话:《Learning OpenCV》中文版 .
  19. 设计模式之结构型模式(7种)
  20. 856计算机专业综合考试,2017年中央民族大学856计算机学科专业综合硕士研究生考试大纲...

热门文章

  1. 数据库三范式 无重复列 完全依赖主键 属性不依赖非主属性
  2. vs-code 中导入新的字体
  3. SAP Router是个啥
  4. Orace登录及建库
  5. 露曦科技在 KIBIDANGO 众筹达成率406%,1600万日元成就VR黑科技
  6. 【C语言|菜鸟教程】100道进阶经典例题详细解答(实例二)
  7. 工程师如何拥抱数字化转型?
  8. 2010.5.11项目管理群主题:网游那些事-DDV731731-SSE
  9. 操作系统基本原理概述
  10. 微信小程序抓包https抓包的血泪史