Laravel深刻學習11 - 接口分離原則

聲明:本文並不是博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,固然也不是原汁原味的翻譯,能保證90%的原汁性,另外由於是理解翻譯,確定會有錯誤的地方,歡迎指正。數據庫

歡迎轉載,轉載請註明出處,謝謝!session

接口分離原則

介紹

接口分離原則指在實現類中對於接口中的方法並不強制去實現使用不到的方法。事實上,在平時的代碼中,你也難道也實現了那些你不須要使用的接口方法?若是是,也是流程空方法吧。這其實已經違背了接口分離原則。函數

實際上,本原則要求接口必須是粒度明確的。聽起來是否似曾相識?是的,SOLID原則都是相關的,打破其中一條,基本上你也就打破了其餘原則。當你的代碼不符合接口分離原則時,那也確定違背了單一責任原則。this

代替這種在實現類中包含不少「笨重」方法的接口,咱們把他劃分紅不少細小須要集成的多個接口。經過把臃腫的接口切成小的,細分的約定,使代碼能夠繼承較小的接口,而不需建立引用中不須要依賴的部分。翻譯

接口分離原則設計

本原則是指在實現類中對於接口中的方法並不強制去實現使用不到的方法。code

實探

爲了闡述該原則,咱們來以會話處理類庫舉例。實際上,咱們參考PHP自帶的SessionHandlerInterface接口。下面是PHP5.4中接口定義的方法:繼承

interface SessionHandlerInterface {
    public function close();
    public function destroy($sessionId);
    public function gc($maxLiftetime);
    public function open($savePath, $name);
    public function read($sessionId);
    public function write($sessionId, $sessionData);
}

這些接口中的方法很熟悉了吧,考慮基於Memcached實現的解決方案。是否是以Memcached實現的接口類必須將全部方法實現?咱們不只不須要實現全部的方法,其中通常都不須要處理!接口

Memcached有本身的自動過時機制,所以咱們不須要實現接口的gc方法,也不須要實現open或者close方法。這裏咱們只需定義一個空方法。爲了糾正這個問題,咱們來定義一個更小,更專一的接口來進行session垃圾回收:rem

interface GarbageCollectorInterface {
    public function gc($maxLifetime);
}

如今接口已經很小,全部相關代碼都能依賴這個專們的約定,它定義了一個專門的函數無需處理全部的session操做。

咱們來以另一個例子來加深對該原則的理解。這裏有一個ContactEloquent類是這樣定義的:

class Contact extends Eloquent {

    public function getNameAttribute()
    {
        return $this->attributes['name'];
    }

    public function getEmailAttribute()
    {
        return $this->attributes['email'];
    }

}

如今,假定應用一樣使用了PasswordReminder類來發送密碼提醒郵件給用戶。下面是PasswordReminder可能的一種實現類:

class PasswordReminder {

    public function remind(Contact $contact, $view)
    {
        // Send password reminder e-mail...
    }

}

你應該已經注意到,PasswordReminder以來了Contact類,也就意味着他依賴了Eloquent ORM。這種特殊的以ORM實現的密碼提醒系統來講是不合理也是不須要的。在這種依賴以外,咱們能自由的切換後臺存儲機制或者ORM而不用改變現有的密碼提醒組件。又一次,咱們破壞了SOLID原則,現有的類對應用中的其餘「認知」知道的太多了。

爲了打破這種依賴,咱們來建立一個RemindableInterface接口。實際上,這個接口已經包含在Laravel中了,默認已經實如今User模型中了:

interface RemindableInterface {
    public function getReminderEmail();
}

接口一旦建立完畢,咱們就能夠在模型中來實現他:

class Contact extends Eloquent implements RemindableInterface {

    public function getReminderEmail()
    {
        return $this->email;
    }

}

最終,咱們只需要依賴這個結構更小,功能更專一的PasswordReminder接口:

class PasswordReminder {

    public function remind(RemindableInterface $remindable, $view)
    {
        // Send password reminder e-mail...
    }

}

簡單的改變,咱們的類實現新的RemindableInterface以後,咱們就將密碼提醒組件中不須要的依賴剔除,相對ORM就更加具備靈活性了。這也是Laravel在數據庫和ORM以外對密碼提醒組件的實現。

只是就是力量

再次地,咱們發現類中太多的實現細節帶來的陷阱。對類中給定的職責多加註意,咱們就能很好的遵照SOLID設計原則。

相關文章
相關標籤/搜索