【架构师训练营】第二期作业

发布于: 2020 年 06 月 17 日
  • 请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?

依赖倒置原则是程序依赖于抽象接口,不依赖于具体实现,降低了客户与实现模块之间的耦合。

好莱坞原则的解释是别调用我们,我们会调用你。要求我们将底层组件挂钩到系统上,高层组件决定什么时候和怎样使用这些底层组件。所以此时我们在写高层组件时,需要利用接口优先定义出底层的调用方式。这里就用到了依赖倒置原则。

  • 请描述一个你熟悉的框架,是如何实现依赖倒置原则的。

我工作中使用的是PHP语言的Laravel框架,框架中有一个TokenGuard类,负责验证用户登录,代码如下:

<?php
namespace Illuminate\Auth;
class TokenGuard implements Guard
{
use GuardHelpers;
protected $request;
protected $inputKey;
protected $storageKey;
public function __construct(UserProvider $provider, Request $request)
{
$this->request = $request;
$this->provider = $provider;
$this->inputKey = 'api_token';
$this->storageKey = 'api_token';
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
$user = null;
$token = $this->getTokenForRequest();
if (! empty($token)) {
$user = $this->provider->retrieveByCredentials(
[$this->storageKey => $token]
);
}
return $this->user = $user;
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
if (empty($credentials[$this->inputKey])) {
return false;
}
$credentials = [$this->storageKey => $credentials[$this->inputKey]];
if ($this->provider->retrieveByCredentials($credentials)) {
return true;
}
return false;
}
}

这里高层模块(TokenGuard类)直接依赖了底层模块(UserProvider接口),而UserProvider接口定义了获取用户对象的接口,代码如下:

<?php
namespace Illuminate\Contracts\Auth;
interface UserProvider
{
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
}

我们可以根据UserProvider的声明,来定制自己获取用户对象的类,然后将自定义的类注入到框架中即可。比如在框架中有两个默认的,从数据库获取User对象的类:

<?php
class EloquentUserProvider implements UserProvider
{
}
class DatabaseUserProvider implements UserProvider
{
}

  • 请用接口隔离原则优化 Cache 类的设计,画出优化后的类图

用户头像

云064

关注

还未添加个人签名 2018.05.24 加入

还未添加个人简介

评论

发布
暂无评论
【架构师训练营】第二期作业