The Clean Architecture in PHP 讀書筆記(五)

interface

上篇最重要的是介紹了去耦的工具之一依賴注入,本篇將繼續(xù)介紹去耦工具:接口和適配器,本文是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 讀書筆記(五)

先介紹接口原則,在介紹適配器。

通過接口來定義契約

前面幾部分我們一直在討論如何去耦這個(gè)主題,前篇最后我們的寫出的代碼如下:

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

此處我們只是將對(duì)CustomerRepository從方法viewAction轉(zhuǎn)移到了構(gòu)造函數(shù),整個(gè)類CustomerController還是對(duì)CustomerRepository有依賴,并且由于類CustomerRepository實(shí)現(xiàn)上是從數(shù)據(jù)庫讀取數(shù)據(jù),意味著CustomerController還依賴于數(shù)據(jù)庫。

因此我們需要對(duì)CustomerRepository在做一次抽象:接口。下面先介紹PHP中的接口。

PHP中的接口

interface Automobile {
    public function drive();
    public function idle();
    public function park();
}

任何實(shí)現(xiàn)該接口的類,都需要實(shí)現(xiàn)3個(gè)方法。

使用接口來做類型提示

PHP7后我們可以通過類型來對(duì)函數(shù)的輸入輸出做出約束,此時(shí)我們的CustomerController變?yōu)槿缦拢?/p>

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;
    }
}

只要實(shí)現(xiàn)滿足CustomerRepositoryInterface接口即可,我們不再關(guān)心數(shù)據(jù)源是數(shù)據(jù)庫還是web了。

使用接口來定義契約

另一種思考接口的角度是:接口是一種契約,定義了使用方和提供方之間的契約,只要滿足契約,就ok。

讓第三方庫符合契約

我們自己來實(shí)現(xiàn)接口非常簡單,但是如果是第三方代碼怎么辦呢?這就是我們下面要介紹的適配器模式。

通過適配器進(jìn)行抽象

接口幫我們能夠徹底的去耦,不再依賴于具體實(shí)現(xiàn),但是這些代碼如果都是我們自己寫的沒問題,但是我們?nèi)绻玫搅说谌降膸?,那怎么辦呢?

看下面的代碼:

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來進(jìn)行位置驗(yàn)證,我們通過依賴注入的方式來注入BillsGeocoder,這很好,但是如果以后我們找到了更好的驗(yàn)證方式,我們不得不修改代碼。此處的問題是我們強(qiáng)依賴于BillsGeocoder類,那怎么解決呢?

建立適配器

通過建立適配器,將第三方庫包裝起來,代碼如下:

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去除了核心邏輯對(duì)外部庫的依賴,有效的進(jìn)行了去耦。

怎么起作用?

通過使用適配器模式,我們能夠很方便的替換或者升級(jí)第三方庫,同時(shí)不影響我們核心應(yīng)用的邏輯。

以上就是我們所有的去耦工具了,此處總結(jié)下,我們又5大去耦工具:

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

其中第一個(gè)工具設(shè)計(jì)模式是在The Clean Architecture in PHP 讀書筆記(二)中介紹的;

第二個(gè)SOLID設(shè)計(jì)模式是在The Clean Architecture in PHP 讀書筆記(三)中介紹,

第三個(gè)依賴注入則是在The Clean Architecture in PHP 讀書筆記(四)中介紹,

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

前面幾篇介紹的這些都是為了下面將要展開的Clean Architecture做準(zhǔn)備,下一篇將開始介紹最核心的Clean Architecture,非常激動(dòng)!

這是The Clean Architecture in PHP的第五篇,你的鼓勵(lì)是我繼續(xù)寫下去的動(dòng)力,期待我們共同進(jìn)步。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容