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设计原则。

相关文章
相关标签/搜索