适配器 | Adapter

Adapter / 适配器

Adapter 是用来解决一类功能的多种实现,这些实现提供一套相同的接口,类似设计模式里的工厂模式。如:支持多种数据库,支持多种模版引擎等。通过这种方式,可以很方便的在不同的类型中进行切换。Adapter 一般配合 Extend 一起使用。

框架默认提供了很多种 Adapter,如: View、Model、Cache、Session、Websocket,项目中也可以根据需要进行扩展,也可以引入第三方的 Adapter。

Adapter 配置

Adapter 的配置文件为 src/config/adapter.js(多模块项目文件为 src/common/config/adapter.js),格式如下:

const nunjucks = require('think-view-nunjucks' const ejs = require('think-view-ejs' const path = require('path' exports.view = { type: 'nunjucks', // 默认的模板引擎为 nunjucks common: { //通用配置 viewPath: path.join(think.ROOT_PATH, 'view'), sep: '_', extname: '.html' }, nunjucks: { // nunjucks 的具体配置 handle: nunjucks }, ejs: { // ejs 的具体配置 handle: ejs, viewPath: path.join(think.ROOT_PATH, 'view/ejs/'), } } exports.cache = { ... }

  • type 默认使用 Adapter 的类型,具体调用时可以传递参数改写

Adapter 配置支持运行环境,可以根据不同的运行环境设置不同的配置,如:在开发环境和生产环境的数据库一般都是不一样的,这时候可以通过 adapter.development.jsadapter.production.js 存放有差异的配置,系统启动后会读取对应的运行环境配置和默认配置进行合并。

如:现在是在生产环境下,那么会读取 adapter.production.jsadapter.js 配置进行合并生成最终的 adapter 配置。

Adapter 的配置读取和合并在项目启动时就已经执行,对于上面的配置,最终合并的配置如下:

exports.view = { type: 'nunjucks', // 默认的模板引擎为 nunjucks nunjucks: { // nunjucks 的具体配置 handle: nunjucks, viewPath: path.join(think.ROOT_PATH, 'view'), sep: '_', extname: '.html' }, ejs: { // ejs 的具体配置 handle: ejs, viewPath: path.join(think.ROOT_PATH, 'view/ejs/'), viewPath: path.join(think.ROOT_PATH, 'view'), sep: '_', extname: '.html' } }

可以看到,common 里的配置会被合并到 nunjucks 和 ejs 中,后续再获取的时候就不用再合并 common 里的配置了。

Adapter 配置解析

Adapter 配置存储了所有类型下的详细配置,具体使用时需要对其解析,选择对应的一种进行使用。比如上面的配置文件中,配置了 nunjucks 和 ejs 二种模板引擎的详细配置,但具体使用时一种场景下肯定只会用其一种模板引擎。

Adapter 的配置解析是通过 think-helper 模块中的 parseAdapterConfig 方法来完成的,如:

const helper = require('think-helper' const viewConfig = think.config('view' // 获取 view adapter 的详细配置 const nunjucks = helper.parseAdatperConfig(viewConfig // 获取 nunjucks 的配置,默认 type 为 nunjucks /** { type: 'nunjucks', handle: nunjucks, viewPath: path.join(think.ROOT_PATH, 'view'), sep: '_', extname: '.html' } */ const ejs = helper.parseAdatperConfig(viewConfig, 'ejs') // 获取 ejs 的配置 /** { handle: ejs, type: 'ejs', viewPath: path.join(think.ROOT_PATH, 'view/ejs/'), viewPath: path.join(think.ROOT_PATH, 'view'), sep: '_', extname: '.html' } */

通过 parseAdapterConfig 方法就可以拿到对应类型的配置,然后就可以调用对应的 handle,传入配置然后执行了。

当然,配置解析并不需要使用者在项目中具体调用,一般都是在插件对应的方法里已经处理。

Adapter 使用

Adapter 都是一类功能的不同实现,一般是不能独立使用的,而是配合对应的扩展一起使用。如:view Adapter(think-view-nunjucks、think-view-ejs)配合 think-view 扩展进行使用。

项目安装 think-view 扩展后,提供了对应的方法来渲染模板,但渲染不同的模板需要的模板引擎有对应的 Adapter 来实现,也就是配置中的 handle 字段。

项目中创建 Adapter

除了引入外部的 Adapter 外,项目内也可以创建 Adapter 来使用。Adapter 文件放在 src/adapter/ 目录下(多模块项目放在 src/common/adapter/),如:src/adapter/cache/xcache.js,表示加了一个名为 xcache 的 cache Adapter 类型,然后该文件实现 cache 类型一样的接口即可。

实现完成后,就可以直接通过字符串引用这个 Adapter 了,如:

exports.cache = { type: 'file', xcache: { handle: 'xcache', //这里配置字符串,项目启动时会自动查找 src/adapter/cache/xcache.js 文件 ... } }

推荐的 Adapter

框架推荐的 Adapter 为 https://github.com/thinkjs/think-awesome#adapters