定制化:资源服务的再实现
美到极致不是无可增加,而是无可减少。 -- Antonie de Saint-Exupery
2.18.1 资源服务
资源可以理解成接口开发过程中所使用到的第三方系统、功能,如数据库,COOKIE、缓存;而服务则是指领域驱动设计中无状态的服务操作,如加密、过滤器、加载器等。
而在PhalApi中,资源和服务更多是通过DI来统一进行管理。并且我们使用资源服务来统称这两者。
在使用PhalApi进行开发时,应该分别从以下三个层面来使用资源服务。
- 1、基本使用
- 2、高级应用
- 3、定制扩展
其中,基本使用是指使用框架默认提供的特性、功能,只需要稍微修改调整一下配置(甚至连配置都不需要修改)即可使用; 高级应用是指切换使用具有同类特性、功能的资源服务,对客户端而言,其实现的功能是等价的,只在于内部实现不同,通常此层面适用于有不同需求的应用场景; 最后是,定制扩展则是充满活力、生气的做法,对于项目需要用到而框架未提供的,都可以通过此方式进行定制、扩展。
2.18.2 仍然以缓存为例
下面以大家熟悉的缓存为例,分别说明这三个层面的演进使用。
(1)基本使用
在./Public/init.php初始化文件中,我们可以去掉对Memcache的注释,从而在项目启用cache这一资源服务。
//缓存 - Memcache/Memcached
DI()->cache = function () {
return new PhalApi_Cache_Memcache(DI()->config->get('sys.mc'));
};
或者,我们还需要根据配置的MC不同,稍微更改一下./Config/sys.php中对应的配置:
/**
* MC缓存服务器参考配置
*/
'mc' => array(
'host' => '127.0.0.1',
'port' => 11211,
),
然后,就可以在项目中如前面说的那样使用cache进行对缓存进行操作。
//设置缓存
DI()->cache->set($key, $value, $expireTime);
//读取缓存
$rs = DI()->cache->get($key);
(2)高级应用
但是我们都知道,缓存的实现方案以及存储的方式多种多样,包括但不限于:数据库缓存、文件缓存、COOKIE/session缓存、Redis缓存、APC缓存。
假设我们需要切换到Redis缓存,则可以在init.php初始化中,把DI()->cache注册成Redis缓存即可。
DI()->cache = function () {
return new PhalApi_Cache_Redis(DI()->config->get('sys.redis'));
};
同时,在./Config/sys.php中添加对应的配置:
'redis' => array(
'host' => '127.0.0.1',
'port' => 9527,
),
(3)定制扩展
毫无疑义,实际项目需要面对的开发场景更为复杂,可能需要使用到加密、压缩、分片或者其他处理手段,又可能使用其他存储媒介。
当框架基本的特性无法满足时,这时就需要考虑进行定制扩展了。值得庆幸的是,实现这一点并不难。一如往常那样,我们需要 先实现、再注册 。
实现资源服务接口
很多通常的资源服务,我们都统一了接口规约。在[1.19]-DI服务速查:各资源服务一览表 中可以查到每个资源服务所需要实现的接口。
如这次的缓存接口类是:
<?php
interface PhalApi_Cache {
/**
* 设置缓存
*
* @param string $key 缓存key
* @param mixed $value 缓存的内容
* @param int $expire 缓存有效时间,单位秒,非时间戳
*/
public function set($key, $value, $expire = 600);
/**
* 读取缓存
*
* @param string $key 缓存key
* @return mixed 失败情况下返回NULL
*/
public function get($key);
/**
* 删除缓存
*
* @param string $key
*/
public function delete($key);
}
我们可以先在项目中,实现此接口,如:
class Common_MyCache implements PhalApi_Cache {
// ... ...
}
具体的实现,这里不再举例。
再注册
当实现好子类后,我们便可以在init.php初始化文件中,切换到我们自己的定制类。
DI()->cache = 'Common_MyCache';
2.18.3 实现、定制化你的资源服务
正如《项目百态》书中隐藏的美模式一节中写道的“恰恰相反,只有减少特性才能提升设计的美感。最好的设计都是功能明确又留有答题,也是易于测试的,即使要作修改,也不会带来新的麻烦。”
是以,作为一个框架,我们应当以发散的方式去设计;但为了能为应用提供可用的功能,我们又应当以收敛的方式去实现。如果我们提供的功能不足以满足大部分主流的业务场景,那么我们至少需要提供可扩展的空间。
类似的场景,还包括有接口签名、对接口参数的获取与接口结果的返回。当大家在进行项目开发过程中,有不同的场景需求时,可以按上面介绍的三个层面分别进行。
先尝试使用简单、默认的方式进行配置解决,再切换到框架或已有的解决方案,最后再尝试扩展自己的定制类。