英文原文:Program to an Interface, Fool

  如果你已经读了我的前几篇关于面向对象范式因为受到 Rust, Go 等语言的影响而发生变化的文章,看到了我正在研究的 Rust 设计模式,你会发现我对 Rust 语言十分的偏爱。

  除此之外,就在上周末,我读完了经典的《设计模式:可复用面向对象软件的基础》。这些种种,引起了我对这本书中谈及的一个核心原则的思考:

面向‘接口’编程,而不是面向‘实现’。

  这是什么意思?

  首先我们需要理解什么是‘接口’,什么是‘实现’。简言之,一个接口就是我们要调用的一系列方法的集合,有对象将会响应这些方法调用。

  一个实现就是为接口存放代码和逻辑的地方。

  本质上讲,这个原则倡导的是,当我们写一个函数或一个方法时,我们应该引用相应的接口,而不是具体的实现类。

  面向‘实现’编程

  首先我们看看,如果不遵循这个原则会发生什么。

  假设你是《华氏 451 度》这本书里的“Montag”这个人。大家都知道,书在华氏 451 度会烧着的。小说中的消防队员只要看到了书就会把它们丢到火里。我们用面向对象的视角说问题,书有一个叫做burn () 的方法。

  书并不是唯一会燃烧的东西。假设我们还有另外一个东西,比如木头,它也有一个方法叫做 burn ()。我们用 Rust 语言来写这段代码,看看在不是面向‘接口’编程的情况下它们是如何燃烧的。

struct Book {title: @str,author: @str,
}struct Log {wood_type: @str,
}

  很直接。我们创建了两个结构体来表示一本书(Book)和一个木头(Log)。下面我们为结构体实现它们的方法:

impl Log {fn burn (&self) {println (fmt!("The %s log is burning!", self.wood_type));}
}impl Book {fn burn (&self) {println (fmt!("The book %s by %s is burning!", self.title, self.author));}
}

  现在LogBook 都有了 burn () 方法,让我们把它们放到火上。

  我们首先把木头放到火上:

fn start_fire (lg: Log) {lg.burn ();
}fn main () {let lg = Log {wood_type: @"Oak",length: 1,};// Burn the oak log!     start_fire (lg);
}

  非常顺利,我们得到了输出 “The Oak log is burning!”.

  现在,因为我们已经写了一个 start_fire 函数,是否我们可以把书也传进去,因为它们都有 burn ()。让我们试一下:

fn main () {let book = Book {title: @"The Brothers Karamazov",author: @"Fyodor Dostoevsky",};// Let's try to burn the book...     start_fire (book);
}

  可行吗?不行。出现了下面的错误:

mismatched types: expected Log but found Book (expected struct Log but

found struct Book)

  说的非常清楚,因为我们写出的函数需要的是一个 Log 结构体,而不是我们传进去的 Book 结构体。如何解决这个问题?我们可以再写一个这样的方法,把参数改成Book 结构体。然而,这并不是一个好的方案。我在两个地方有了两个几乎一样的函数,如果一个修改,我们需要记得修改另外一个。

  现在让我们看看面向‘接口’编程如何能解决这个问题。

  面向接口编程

  我们仍然使用前面的结构体,但这次我们加一个接口。在 Rust 语言里,接口叫做traits

struct Book {title: @str,author: @str,
}struct Log {wood_type: @str,
}trait Burnable {fn burn (&self);
}

  现在,除了两个结构体外,我们又多了一个叫做 Burnable 的接口。它的定义里只有一个叫做 burn () 的方法。我们来为每个结构体实现它们的接口:

impl Burnable for Log {fn burn (&self) {println (fmt!("The %s log is burning!", self.wood_type));}
}impl Burnable for Book {fn burn (&self) {println (fmt!("The book \"%s\" by %s is burning!", self.title, self.author));}
}

  看起来并没有多大的变化。这就是面向接口编程的强大之处:

fn start_fire<T: Burnable>(item: T) {item.burn ();
}

  不仅仅只能接收一个 Book 对象或 Log 对象做参数,我们可以往里面传入任何实现了 Burnable 接口的类型(我们叫它类型T)。这使得我们的主函数可以写成这样:

fn main () {let lg = Log {wood_type: @"Oak",};let book = Book {title: @"The Brothers Karamazov",author: @"Fyodor Dostoevsky",};// Burn the oak log!     start_fire (lg);// Burn the book!     start_fire (book);
}

  正如期望的,我们得到了下面的输出:

The Oak log is burning!

The book “The Brothers Karamazov” by Fyodor Dostoevsky is burning!

  这跟我们期望的完全一致。

  结论

  遵循“面向‘接口’编程”原则,我们可以写出一个函数,使其能完全能复用任何实现了 Burnable 接口的对象。因为很多的程序员都是按小时收费的,我们写出越多可复用的代码,用于维护它们的时间就会越少,也就是更好。

  因此,这是一个非常强大的编程思想。

  并不是什么时候都可以面向接口编程的,但遵循这种原则会让你更容易的写出可复用的更优雅的代码。接口提供了非常优秀的抽象归纳,让我们的开发工作变得容易很多。

原文链接:http://news.cnblogs.com/n/183515/

面向“接口”编程和面向“实现”编程相关推荐

  1. 【转】工厂模式面向接口编程

    为了实现更好的灵活性     应改面向接口编程.因此,应该面向接口提供工场.         比如,Cat,   Dog,   Mouse,都是4条腿会跑的动物.     因此,我们建立一个接口叫做F ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. 在eclipse中通过基于spring data的easyrest风格的maven项目操纵cassandra和lucene
  2. 邮件客户端WebMail Pro v7.7.5发布,在线订购限时75折优惠!
  3. POJ-2948 Martian Mining 动态规划
  4. pod install 失败 Сocoapods trunk URL couldn't be downloaded
  5. Medusa(美杜莎)和Hydra(九头蛇)快速入门手册:01
  6. YJX_rxjh_10_2.5.2
  7. 外显子和基因组基本概念(一)
  8. Facebook史上最严重宕机:互联网企业是时候重新审视架构了?
  9. qcombobox 隐藏_Qt之QComboBox定制
  10. Ground Turth在深度学习中的意思
  11. 【语言处理与Python】1.3计算语言:简单的统计
  12. 软件架构设计之Utility模块——DateTime
  13. 微信小程序下拉刷新功能--onPullDownRefresh
  14. 勇者斗恶龙服务器没有响应,PC版勇者斗恶龙英雄打不开怎么办?
  15. 三线性插值(Trilinear Interpolation)详解
  16. 汽车网络安全之——CAN网关测试
  17. AUTH 使用登录验证
  18. Makefile中的奇葩字符
  19. Appium学习日记(一)——Appium工作原理及其主要组件
  20. 网络基础-路由篇-RIPv2

热门文章

  1. 虚拟机装的XP,无法上网,因为没有安装网卡驱动,怎么解决
  2. 【机考】华为OD2022.11.01机考题目思路与代码
  3. Android动画之Tween Animation
  4. android 登录注册动画,Android开发(14)——动画实战:炫酷登录
  5. 对定向天线的浅薄理解
  6. ThingsBoard资产设备总数/离线数/在线数统计
  7. 新视野大学英语视听说第三版答案
  8. 脑波设备mindwave介绍
  9. excel 数据读出
  10. vivo图像算法工程师双非研究生可以吗_双非材料专业小硕秋招春招找工作历程,希望对大家有帮助,劝退警告!!!...