前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >The Clean Architecture in PHP 读书笔记(五)The Clean Architecture in PHP 读书笔记(五)

The Clean Architecture in PHP 读书笔记(五)The Clean Architecture in PHP 读书笔记(五)

作者头像
zhuanxu
发布2018-08-23 12:52:24
3710
发布2018-08-23 12:52:24
举报
文章被收录于专栏:进击的程序猿

interface

上篇最重要的是介绍了去耦的工具之一依赖注入,本篇将继续介绍去耦工具:接口和适配器,本文是The Clean Architecture in PHP的第5篇。

本文为系列文章的第五篇,前4篇地址是

The Clean Architecture in PHP 读书笔记(一)

The Clean Architecture in PHP 读书笔记(二)

The Clean Architecture in PHP 读书笔记(三)

The Clean Architecture in PHP 读书笔记(四)

The Clean Architecture in PHP 读书笔记(五)

先介绍接口原则,在介绍适配器。

通过接口来定义契约

前面几部分我们一直在讨论如何去耦这个主题,前篇最后我们的写出的代码如下:

代码语言:javascript
复制
class CustomerController {
    protected $repository;
    public function __construct( CustomerRepository $repo )
    {
        $this->repository = $repo;
    }
    public function viewAction()
    {
        $customer = $this->repository->getById( 1001 );
        return $customer;
    }
}

此处我们只是将对CustomerRepository从方法viewAction转移到了构造函数,整个类CustomerController还是对CustomerRepository有依赖,并且由于类CustomerRepository实现上是从数据库读取数据,意味着CustomerController还依赖于数据库。

因此我们需要对CustomerRepository在做一次抽象:接口。下面先介绍PHP中的接口。

PHP中的接口

代码语言:javascript
复制
interface Automobile {
    public function drive();
    public function idle();
    public function park();
}

任何实现该接口的类,都需要实现3个方法。

使用接口来做类型提示

PHP7后我们可以通过类型来对函数的输入输出做出约束,此时我们的CustomerController变为如下:

代码语言:javascript
复制
interface CustomerRepositoryInterface {
    public function getById( $id );
}

class CustomerController {
    protected $repository;
    public function __construct( CustomerRepositoryInterface $repo )
    {
        $this->repository = $repo;
    }
    public function viewAction()
    {
        $customer = $this->repository->getById( 1001 );
        return $customer;
    }
}

只要实现满足CustomerRepositoryInterface接口即可,我们不再关心数据源是数据库还是web了。

使用接口来定义契约

另一种思考接口的角度是:接口是一种契约,定义了使用方和提供方之间的契约,只要满足契约,就ok。

让第三方库符合契约

我们自己来实现接口非常简单,但是如果是第三方代码怎么办呢?这就是我们下面要介绍的适配器模式。

通过适配器进行抽象

接口帮我们能够彻底的去耦,不再依赖于具体实现,但是这些代码如果都是我们自己写的没问题,但是我们如果用到了第三方的库,那怎么办呢?

看下面的代码:

代码语言:javascript
复制
class AddressController extends AbstractController {
    protected $geocoder;
    public function __construct( BillsGeocoder $geocoder )
    {
        $this->geocoder = $geocoder;
    }
    public function validateAddressAction()
    {
        $address = $this->vars()->fromPost( 'address' );
        $isValid = $this->geocoder->geocode( $address ) !== false;
    }
}

我们使用Bill's Geocoder来进行位置验证,我们通过依赖注入的方式来注入BillsGeocoder,这很好,但是如果以后我们找到了更好的验证方式,我们不得不修改代码。此处的问题是我们强依赖于BillsGeocoder类,那怎么解决呢?

建立适配器

通过建立适配器,将第三方库包装起来,代码如下:

代码语言:javascript
复制
interface GeocoderInterface {
    public function geocode( $address );
}

class BillsGeocoderAdapter implements GeocoderInterface {
    protected $geocoder;
    public function __construct( BillsGeocoder $geocoder )
    {
        $this->geocoder = $geocoder;
    }
    public function geocode( $address )
    {
        return $this->geocoder->geocode( $address );
    }
}

class AddressController extends AbstractController {

    protected $geocoder;

    public function __construct( GeocoderInterface $geocoder )
    {
        $this->geocoder = $geocoder;
    }

    public function validateAddressAction()
    {
        $address = $this->vars()->fromPost( 'address' );
        $isValid = $this->geocoder->geocode( $address ) !== false;
    }
}

此处我们通过定义接口,声明了契约,通过适配器BillsGeocoderAdapter去除了核心逻辑对外部库的依赖,有效的进行了去耦。

怎么起作用?

通过使用适配器模式,我们能够很方便的替换或者升级第三方库,同时不影响我们核心应用的逻辑。

以上就是我们所有的去耦工具了,此处总结下,我们又5大去耦工具:

  • Design Patterns,A Primer
  • SOLID Design Principles
  • Depedency Injection
  • Defining a Contract with Interfaces
  • Abstracting with Adapters

其中第一个工具设计模式是在The Clean Architecture in PHP 读书笔记(二)中介绍的;

第二个SOLID设计模式是在The Clean Architecture in PHP 读书笔记(三)中介绍,

第三个依赖注入则是在The Clean Architecture in PHP 读书笔记(四)中介绍,

第四和五在本文中介绍了。

前面几篇介绍的这些都是为了下面将要展开的Clean Architecture做准备,下一篇将开始介绍最核心的Clean Architecture,非常激动!

这是The Clean Architecture in PHP的第五篇,你的鼓励是我继续写下去的动力,期待我们共同进步。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.11.04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • The Clean Architecture in PHP 读书笔记(五)
    • 通过接口来定义契约
      • PHP中的接口
      • 使用接口来做类型提示
      • 使用接口来定义契约
      • 让第三方库符合契约
    • 通过适配器进行抽象
      • 建立适配器
      • 怎么起作用?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档