为什么80%的码农都做不了架构师?>>>   

上一篇

Interface Segregation Principle 接口隔离原则

Introduction 介绍

The Interface Segregation principle states that no implementation of an interface should be forced to depend on methods it does not use. Have you ever had to implement methods of an interface that you did not need? If so, you probably created blank methods in your implementation. This is an example of being forced to use an interface that breaks the Interface Segregation principle.

接口隔离原则规定在实现接口的时候,不能强迫去实现没有用处的方法。你是否曾被迫去实现一些接口里你用不到的方法?如果答案是肯定的,那你可能创建了一个空方法放在那里。被迫去实现用不到的函数,这就是一个违背了接口隔离原则的例子。

In practical terms, this principle demands that interfaces be granular and focused. Sound familiar? Remember, all five SOLID principles are related, such that by breaking one you often must break the others. When breaking the Interface Segregation principle, the Single Responsibility principle must also broken.

在实际操作中,该原则要求接口必须粒度很细,且专注于一个领域。听起来很耳熟?记住,所有五个“坚实”原则都是相关的,也就是说当打破一个原则时,你通常肯定打破了其他的原则。在这里当你违背了接口隔离原则后,肯定也违背了单一职责原则。

Instead of having a "fat" interface containing methods not needed by all implementations, it is preferable to have several smaller interfaces that may be implemented individually as needed. By breaking fat interfaces into smaller, more focused contracts, consuming code can depend on the smaller interface, without creating dependencies on parts of the application it does not use.

“臃肿”的接口,有着很多不是所有的实现类都需要的方法。与其写这样的接口,不如将其拆分成多个小巧的接口,里面的方法都是各自领域所需要的。这样将臃肿接口拆成小巧、功能集中的接口后,我们就可以使用小接口来编码,而不必为我们不需要的功能买单。

Interface Segregation Principle 接口隔离原则

This principle states that no implementation of an interface should be forced to depend on methods it does not use.

该原则规定,一个接口的一个实现类,不应该去实现那些自己用不到的方法。如果需要,那就是接口设计有问题,违背了接口隔离原则。

In Action 实践

To illustrate this principle, let's consider an example session handing library. In fact, we will consider PHP's own SessionHandlerInterface. Here are the methods defined by this interface, which is included with PHP beginning in version 5.4:

为了说明该原则,我们来思考一个关于会话处理的类库。实际上我们将要考察 PHP 自己的SessionHandlerInterface。下面是该接口定义的方法,他们是从 PHP 5.4 版才开始有的:

<!-- lang:php -->
interface SessionHandlerInterface {public function close();public function destroy($sessionId);public function gc($maxLifetime);public function open($savePath, $name);public function read($sesssionId);public function write($sessionId, $sessionData);
}

Now that you are familiar with the methods defined by this interface, consider an implementation using Memcached. Would a Memcached implementation of this interface define functionality for each of these methods? Not only do we not need to implement all of these methods, we don't need half of them!

现在我们知道接口里面都是什么方法了,我们打算用Memcached来实现它。Memcached需要实现这个接口里的所有方法么?不,里面一半的方法对于Memcached来说都是不需要实现的!

Since Memcached will automatically expire the values it contains, we do not need to implement the gc method of the interface, nor do we need to implement the open or close methods of the interface. So, we are forced to define "stubs" for these methods in our implementation that are just empty methods. To correct this problem, let's start by defining a smaller, more focused interface for session garbage collection:

因为Memcached会自动清除存储的过期数据,我们不需要实现gc方法。我们也不需要实现openclose方法。所以我们被迫去写空方法来站着位子。为了解决在这个问题,我们来定义一个小巧的专门用来垃圾回收的接口:

<!-- lang:php -->
interface GarbageCollectorInterface {public function gc($maxLifetime);
}

Now that we have a smaller interface, any consuming code can depend on this focused contract, which defines a very narrow set of functionality and does not create a dependency on the entire session handler.

现在我们有了一个小巧的接口,功能单一而专注。需要垃圾清理的只用依赖这个接口即可,而不必去依赖整个会话处理。

To further understand the principle, let's reinforce our knowledge with another example. Imagine we have a Contact Eloquent class that is defined like so:

为了更深入理解该原则,我们用另一个例子来强化理解。想象我们有一个名为Contact的Eloquent类,定义成这样:

<!-- lang:php -->
class Contact extends Eloquent {public function getNameAttribute(){return $this->attributes['name'];}public function getEmailAttribute(){return $this->attributes['email'];}
}

Now, let's assume that our application also employs a PasswordReminder class that is responsible for sending password reminder e-mails to users of the application. Below is a possible definition of the PasswordReminder class:

现在我们再假设我们应用里还有一个叫PasswordReminder的类来负责给用户发送密码找回邮件。下面是PasswordReminder的定义方式的一种:

<!-- lang:php -->
class PasswordReminder {public function remind(Contact $contact, $view){// Send password reminder e-mail...}
}

As you probably noticed, our PassswordReminder is dependent upon the Contact class, which in turns means it is dependent on the Eloquent ORM. It is neither desirable or necessary to couple the password reminder system to a specific ORM implementation. By breaking the dependency, we can freely change our back-end storage mechanism or ORM without affecting the password reminder component of the application. Again, by breaking one of the SOLID principles, we have given a consuming class too much knowledge about the rest of the application.

你可能注意到了,PasswordReminder依赖着Contact类,也就是依赖着Eloquent ORM。 对于一个密码找回系统来说,依赖着一个特定的ORM实在是没必要,也是不可取的。切断对该ORM的依赖,我们就可以自由的改变我们后台存储机制或者说ORM,同时不会影响到我们的密码找回组件。重申一遍,违背了“坚实”原则的任何一条,就意味着有个类它知道的太多了。

To break the dependency, let's create a RemindableInterface. In fact, such an interface is included with Laravel, and is implemented by the User model by default:

要切断这种依赖,我们来创建一个RemindableInterface接口。事实上Laravel已经有了这个接口,并且默认由User模型实现了该接口:

<!-- lang:php -->
interface RemindableInterface {public function getReminderEmail();
}

Once the interface has been created, we can implement it on our model:

一旦接口定义好了,我们就可以在模型上实现它:

<!-- lang:php -->
class Contact extends Eloquent implements RemindableInterface {public function getReminderEmail(){return $this->email;}
}

Finally, we can depend on this smaller, more focused interface in the PasswordReminder:

最终我们可以在PasswordReminder里面依赖这样一个小巧且专注的接口了:

<!-- lang:php -->
class PasswordReminder {public function remind(RemindableInterface $remindable, $view){// Send password reminder e-mail...}
}

By making this simple change, we have removed unnecessary dependencies from the password reminder component and made it flexible enough to use any class from any ORM, so long as that class implements the new RemindableInterface. This is exactly how the Laravel password reminder component remains database and ORM agnostic!

通过这小小的改动,我们已经移除了密码找回组件里不必要的依赖,并且使它足够灵活能使用任何实现了RemindableInterface的类或ORM。这其实正是Laravel的密码找回组件如何保持与数据库ORM无关的秘诀!

Knowledge Is Power 知识就是力量

Again we have discovered the pitfalls of giving a class too much knowledge about application implementation details. By paying careful attention to how much knowledge we are giving a class, we can abide by all of the SOLID principles.

我们再次发现了一个使类知道太多东西的陷阱。通过小心留意是否让一个类知道了太多,我们就可以遵守所有的“坚实”原则。

下一篇

转载于:https://my.oschina.net/zgldh/blog/389125

From Apprentice To Artisan 翻译 19相关推荐

  1. From Apprentice To Artisan 翻译 08

    为什么80%的码农都做不了架构师?>>>    上一篇 As Organizer 作为管理工具 One of the keys to building a well architec ...

  2. From Apprentice To Artisan 翻译 17

    为什么80%的码农都做不了架构师?>>>    上一篇 Open Closed Principle 开放封闭原则 Introduction 介绍 Over the life time ...

  3. 微信公众平台开发(六) 翻译功能开发

    转载自:http://www.php100.com/html/php/api/2013/0909/6130.html 微信公众平台开发(六) 翻译功能开发 来源:David Camp   时间:201 ...

  4. 如何设置Qt程序软件的语言翻译(Qt自带翻译软件)

    文章目录 01 - 目的和说明 02 - 过程步骤 03 - 链接分享 01 - 目的和说明   目的:可以由用户通过互斥按钮选择界面显示语言,中文或英文(如需要其它语言,则需要稍作修改).   说明 ...

  5. Laravel深入学习5 - 应用架构

    声明:本文并非博主原创,而是来自对<Laravel 4 From Apprentice to Artisan>阅读的翻译和理解,当然也不是原汁原味的翻译,能保证90%的原汁性,另外因为是理 ...

  6. Laravel深入学习10 - 里氏替换原则

    声明:本文并非博主原创,而是来自对<Laravel 4 From Apprentice to Artisan>阅读的翻译和理解,当然也不是原汁原味的翻译,能保证90%的原汁性,另外因为是理 ...

  7. php 单一职责原则,Laravel深入学习8 - 单一责任原则

    声明:本文并非博主原创,而是来自对<Laravel 4 From Apprentice to Artisan>阅读的翻译和理解,当然也不是原汁原味的翻译,能保证90%的原汁性,另外因为是理 ...

  8. php lumen和laravel,Laravel 还是 Lumen?

    Laravel 还是 Lumen?相信有不少人在纠结这个问题,相对来讲,我并不推荐使用 Lumen,因为作者的更新维护很明显还是偏重于 Laravel 的,还有一个理由就是 Laravel 已经包含了 ...

  9. Theano2.1.1-基础知识之准备工作

    来源:http://deeplearning.net/software/theano/tutorial/index.html#tutorial 这里介绍的是使用theano的一些基础知识,虽然thea ...

最新文章

  1. Ubuntu 12.04 64bit或者CentOS 6.3 64bit上搭建OpenRTMFP/Cumulus服务器
  2. mybatis注解配置出现returned more than one row, where no more than one was expected
  3. vc 版本 宏 (zz.IS2120@BG57IV3)
  4. 【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )
  5. 【转】【Linux】sed命令详解
  6. 城市APP集成Firebase/Admob/增强现实带PHP管理后台
  7. 2015-2016-1学期 《信息安全系统设计基础》课程总结
  8. Ext JS 4.2.0发布
  9. Pinyin Comparison 拼音辨别 V1.0
  10. Java-前后端分离-单点登录(SSO二级跨域和跨一级域名)
  11. 签名验签服务器的作用,签名验签服务器
  12. 什么是图像直方图直方图均衡的原理和作用图像信噪比的概念
  13. 罗马数字与十进制数字对应生成(1-3999)
  14. 模型微调(finetune)
  15. Ubuntu 7.04--桌面
  16. 基于JAVA的洗衣店订单管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  17. 3d空间中球体的动量守恒
  18. #10049. 「一本通 2.3 例 1」Phone List(trie树应用)
  19. ngrok 免费,本地项目,域名
  20. 数据结构和算法(第九章哈希表)

热门文章

  1. 分享实录|争议不断地EOS,我们如何才能理性看待?
  2. 最简单 - 单例模式
  3. openstack的vnc启动ssl
  4. Excel数据生成SQL insert语句
  5. Python中如何把一个UTC时间转换为本地时间
  6. Python操作Excel——win32com模块和xlrd+xlwt+xlutils组合
  7. Java开发者为最急需IT技术人才
  8. struts2中jsp页面上验证码的生成
  9. java中想要保留2位小数_java使double保留两位小数的多方法 java保留两位小数
  10. js面向对象与PHP面向对象总结