专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
码农翻身  ·  漫画 | 为什么大家都愿意进入外企? ·  昨天  
程序员的那些事  ·  清华大学:DeepSeek + ... ·  3 天前  
程序员的那些事  ·  印度把 DeepSeek ... ·  3 天前  
OSC开源社区  ·  2024: 大模型背景下知识图谱的理性回归 ·  4 天前  
程序猿  ·  “我真的受够了Ubuntu!” ·  4 天前  
51好读  ›  专栏  ›  SegmentFault思否

完整的 PHP 依赖倒置原则例程

SegmentFault思否  · 公众号  · 程序员  · 2018-01-26 08:00

正文

设计模式中 依赖倒置原则 ( Dependence Inversion Principle )的定义是“ 高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。 ”理解起来并不难,但在具体实现上,网上给出的很多 PHP 示例都有缺陷。

就拿这篇文章来说,概念讲的没有问题,但在具体实现上,特别是代码中有很多错误,不能体现 PHP 特色,比如 PHP 中应该用 -> 而不是用 . 来调用方法,变量名应该带 $ 等很多错误,这就不说了,最关键的是即使把这些语法错误都改正,例子也不能说明原则,不够有说服力。因为即使不加接口或抽象类,妈妈也一样能给孩子讲故事、读报纸、读杂志。

以下可运行代码,没有用到任何接口和抽象类,一样可以实现功能,并且可扩展,不需要修改 Mother 类里的任何代码,一样可以轻松自如地让妈妈读各种读物,无非就是在上面追加各种 class ,只要这个 class 里有 getContent 方法,妈妈全部可以识别:

  1. php

  2. class Book {

  3.    public function getContent(){

  4.        return "很久很久以前有一个阿拉伯的故事……\n";

  5.    }

  6. }

  7. class Newspaper {

  8.    public function getContent(){

  9.        return "林书豪17+9助尼克斯击败老鹰……\n";

  10.    }

  11. }

  12. class Mother{

  13.    public function narrate($book){

  14.        echo "妈妈开始讲故事\n";

  15.        echo $book->getContent();

  16.    }

  17. }

  18. class Client{

  19.    public static function main(){

  20.        $mother = new Mother();

  21.        $mother->narrate(new Book());

  22.        $mother->narrate( new Newspaper());

  23.    }

  24. }

  25. Client::main();

既然如此随意,还如何体现依赖倒置呢?这是因为 PHP 弱类型语言 ,特点就是不需要为变量指定类型,导致的结果就是只要你的 class 里有我需要调用的方法(在这里是 getContent 方法),那就无论如何也不会出错,至于你是不是实现了什么 interface 接口,都无所谓的。像这样,是无法真正体现依赖倒置原则的。那到底如何才能真正体现依赖倒置呢?秘诀就是我们通过使用PHP的 类型约束 来规定 narrate 函数的 $book 参数必须是一个接口:

  1. class Mother{

  2.    public function narrate(IReader $book){

  3.        echo "妈妈开始讲故事\n";

  4.        echo $book->getContent();

  5.    }

  6. }

在这里,我们规定了 $book 参数必须是一个 IReader 接口,那么凡是需要让妈妈讲的读物都必须是对于 IReader 这个接口的一个实现,否则就会报错。完整代码如下:

  1. php

  2. interface IReader{

  3.    public function getContent();

  4. }

  5. class Book implements IReader {

  6.    public function getContent(){

  7.        return "很久很久以前有一个阿拉伯的故事……\n";

  8.    }

  9. }

  10. class Newspaper implements IReader {

  11.    public function getContent(){

  12.        return "林书豪17+9助尼克斯击败老鹰……\n";

  13.    }

  14. }

  15. class Mother{

  16.    public function narrate(IReader $book){

  17.        echo "妈妈开始讲故事\n";

  18.        echo $book->getContent();

  19.    }

  20. }

  21. class Client{

  22.    







请到「今天看啥」查看全文