跳转至正文

Facade(门面) ​


PrismGo 的 Facade 为 服务容器 中注册的服务提供了"静态"访问接口。Facade 充当服务容器中底层类的"静态代理",提供简洁、富有表现力的语法,同时保持比传统静态方法更好的可测试性和灵活性。


简介 ​

在 PrismGo 的文档和源码中,你会看到通过包级函数与框架功能交互的代码示例。例如:

go
import "github.com/prismgo/framework/cache"

// 使用 Cache Facade 写入缓存
if err := cache.Put(ctx, "site.name", "PrismGo", 10*time.Minute); err != nil {
    return err
}

// 使用 Cache Facade 读取缓存
name, err := cache.Get[string](ctx, "site.name", cache.Value("Default Name"))

这里的 cache.Put 和 cache.Get 并不是某个结构体上的方法,而是 cache 包提供的包级便利函数。它们内部通过 facade.Resolve 从当前 Application 的容器中解析出底层的缓存 Manager,再委托给该实例执行实际操作。

Facade 的核心价值在于:

  • 简洁语法:无需手动注入或获取服务实例,直接通过包级函数调用。
  • 类型安全:通过 Go 泛型提供强类型返回值。
  • 可测试性:底层服务由容器管理,可在测试中替换实现。
  • 统一入口:所有模块遵循相同的解析模式,降低学习成本。

Facade 的工作原理 ​

PrismGo 的 Facade 实现位于 github.com/prismgo/framework/facade 包,核心逻辑是一个泛型函数:

go
// Resolve 从当前 Application 容器解析服务。
// 容器未装配、key 无绑定、类型不匹配或 factory 返回错误时,统一 panic 暴露装配问题。
func Resolve[T any](key string) T

它的工作流程如下:

  1. 调用 container.Make[T](key),从当前 Application 的容器中按 key 解析服务。
  2. 如果容器未装配(没有当前 Application)、key 未绑定、类型不匹配或 factory 返回错误,container.Make 返回 error。
  3. facade.Resolve 将这些错误转换为 panic,确保装配问题在开发期立刻暴露,避免调用方拿到零值后继续执行。

每个功能模块(cache、config、route、logger 等)在其包内定义一个 facade.go 文件,通过 facade.Resolve 获取底层服务实例,再提供一组包级便利函数。调用链如下:

业务代码 → cache.Put(ctx, key, val, ttl) 
         → cache.Default() → cache.Resolve().Default() 
         → facade.Resolve[*Manager]("cache.manager") 
         → container.Make[*Manager]("cache.manager") 
         → 当前 Application 容器返回已注册的 Manager 实例

核心 Facade:facade.Resolve ​

facade.Resolve 是所有模块 Facade 的基础。如果你需要直接获取容器中的一个服务,可以像这样使用:

go
import "github.com/prismgo/framework/facade"

// 从容器解析 *cache.Manager
manager := facade.Resolve[*cache.Manager]("cache.manager")

参数说明:

参数类型说明
T泛型参数期望返回的服务类型
keystring服务在容器中注册的键名

行为说明:

  • 服务存在且类型匹配:返回该服务的指针/值。
  • 服务不存在、类型不匹配或 factory 返回错误:panic(非 error 返回)。
  • 当前无 Application 容器:panic。

这种设计是有意为之的:Facade 是严格便捷入口,解析错误如果被吞掉会让调用方拿到零值继续执行。因此 facade 层统一 panic 暴露装配问题,让错误尽早显现。

可用 Facade ​

Cache Facade ​

包路径: github.com/prismgo/framework/cache

服务键名: "cache.manager"

底层类型: *Manager

Cache Facade 提供了对缓存系统的便捷访问。它管理多个缓存存储(Memory、Redis、File、Failover),每个存储通过 Repository 暴露读写操作。

解析方法 ​

go
// Resolve 返回缓存 Factory 契约
func Resolve() cachecontract.Factory

配置参数 ​

缓存配置在 config/cache.go 中注册。主要参数:

参数路径环境变量默认值说明
cache.defaultCACHE_STORE"memory"默认缓存存储名称
cache.encodingCACHE_ENCODING""编码方式:msgpack 或 json
cache.prefixCACHE_PREFIX"workorder_cache"全局缓存 key 前缀

详细配置参数请参考 Cache 文档。

可用函数 ​

存储选择与基本信息:

函数签名说明
DefaultName() string返回默认 store 名称
Default() cachecontract.Repository返回默认 store 对应的 Repository
Store(name string) cachecontract.Repository按名称返回 Repository;name 为空时返回默认 store
Name() string返回默认 store 的 Repository 名称
Close() error释放已构建 store 持有的外部资源

写入操作:

函数签名说明
Put(ctx, key, value, ttl) error写入默认 store
PutFrom(ctx, storeName, key, value, ttl) error写入指定 store
Set(ctx, key, value, ttl) errorPut 的别名
SetFrom(ctx, storeName, key, value, ttl) errorPutFrom 的别名
Forever(ctx, key, value) error永久写入默认 store
ForeverFrom(ctx, storeName, key, value) error永久写入指定 store
Add(ctx, key, value, ttl) (bool, error)仅当 key 不存在时写入
AddFrom(ctx, storeName, key, value, ttl) (bool, error)仅当 key 不存在时写入指定 store
PutMany(ctx, values, ttl) error批量写入默认 store
PutManyFrom(ctx, storeName, values, ttl) error批量写入指定 store
SetMultiple(ctx, values, ttl) errorPutMany 的别名
SetMultipleFrom(ctx, storeName, values, ttl) errorPutManyFrom 的别名

读取操作:

函数签名说明
Get[T](ctx, key, fallback...) (T, error)读取并解码为泛型 T
GetFrom[T](ctx, storeName, key, fallback...) (T, error)从指定 store 读取并解码
String(ctx, key, fallback...) (string, error)读取字符串值
StringFrom(ctx, storeName, key, fallback...) (string, error)从指定 store 读取字符串
Integer(ctx, key, fallback...) (int, error)读取整数值
IntegerFrom(ctx, storeName, key, fallback...) (int, error)从指定 store 读取整数
Float(ctx, key, fallback...) (float64, error)读取 float64 值
FloatFrom(ctx, storeName, key, fallback...) (float64, error)从指定 store 读取 float64
Boolean(ctx, key, fallback...) (bool, error)读取布尔值
BooleanFrom(ctx, storeName, key, fallback...) (bool, error)从指定 store 读取布尔值
Has(ctx, key) (bool, error)判断 key 是否存在
HasFrom(ctx, storeName, key) (bool, error)判断指定 store 中 key 是否存在
Missing(ctx, key) (bool, error)判断 key 是否不存在
MissingFrom(ctx, storeName, key) (bool, error)判断指定 store 中 key 是否不存在
Many[T](ctx, keys, fallback...) (map[string]T, error)批量读取并解码
ManyFrom[T](ctx, storeName, keys, fallback...) (map[string]T, error)从指定 store 批量读取
GetMultiple[T](ctx, keys, fallback...) (map[string]T, error)Many 的别名
GetMultipleFrom[T](ctx, storeName, keys, fallback...) (map[string]T, error)ManyFrom 的别名

读取与存入(Remember 模式):

函数签名说明
Remember[T](ctx, key, ttl, loader) (T, error)读取默认 store;未命中时执行 loader 并写入
RememberFrom[T](ctx, storeName, key, ttl, loader) (T, error)读取指定 store;未命中时执行 loader 并写入
RememberForever[T](ctx, key, loader) (T, error)读取;未命中时执行 loader 并永久写入
RememberForeverFrom[T](ctx, storeName, key, loader) (T, error)读取指定 store;未命中时永久写入
Sear[T](ctx, key, loader) (T, error)RememberForever 的别名
SearFrom[T](ctx, storeName, key, loader) (T, error)RememberForeverFrom 的别名
Flexible[T](ctx, key, window, loader) (T, error)热点缓存两段式刷新
FlexibleFrom[T](ctx, storeName, key, window, loader) (T, error)指定 store 的热点缓存

TTL 操作:

函数签名说明
Touch(ctx, key, ttl) (bool, error)延长已存在 key 的 TTL
TouchFrom(ctx, storeName, key, ttl) (bool, error)延长指定 store 中 key 的 TTL

计数器:

函数签名说明
Increment(ctx, key, delta...) (int64, error)原子递增默认 store 中的整数
IncrementFrom(ctx, storeName, key, delta...) (int64, error)原子递增指定 store 中的整数
Decrement(ctx, key, delta...) (int64, error)原子递减默认 store 中的整数
DecrementFrom(ctx, storeName, key, delta...) (int64, error)原子递减指定 store 中的整数

读取与删除:

函数签名说明
Pull[T](ctx, key, fallback...) (T, error)读取值并立即删除
PullFrom[T](ctx, storeName, key, fallback...) (T, error)从指定 store 读取并删除

删除与清空:

函数签名说明
Forget(ctx, key) error删除指定 key
ForgetFrom(ctx, storeName, key) error删除指定 store 中的 key
Delete(ctx, key) errorForget 的别名
ForgetMany(ctx, keys) error批量删除
ForgetManyFrom(ctx, storeName, keys) error批量删除指定 store 中的 key
DeleteMultiple(ctx, keys) errorForgetMany 的别名
DeleteMultipleFrom(ctx, storeName, keys) errorForgetManyFrom 的别名
Flush(ctx) error清空默认 store
FlushFrom(ctx, storeName) error清空指定 store
Clear(ctx) errorFlush 的别名
ClearFrom(ctx, storeName) errorFlushFrom 的别名

原子锁:

函数签名说明
Lock(name string, ttl time.Duration) cachecontract.Lock创建带 TTL 的锁
LockFrom(storeName, name string, ttl time.Duration) cachecontract.Lock基于指定 store 创建锁
LockWithOwner(name string, ttl time.Duration, owner string) cachecontract.Lock创建指定 owner 的锁
LockWithOwnerFrom(storeName, name string, ttl time.Duration, owner string) cachecontract.Lock基于指定 store 创建指定 owner 的锁
RestoreLock(name, owner string) cachecontract.Lock恢复一个可释放的锁
RestoreLockFrom(storeName, name, owner string) cachecontract.Lock恢复指定 store 的锁
FlushLocks(ctx) error清理锁命名空间
FlushLocksFrom(ctx, storeName) error清理指定 store 的锁命名空间

并发限制:

函数签名说明
Funnel(name string) cachecontract.FunnelLimiter创建并发限制器
FunnelFrom(storeName, name string) cachecontract.FunnelLimiter基于指定 store 创建并发限制器

标签缓存:

函数签名说明
Tags(tags ...string) cachecontract.TaggedRepository创建 tagged cache 操作入口
TagsFrom(storeName string, tags ...string) cachecontract.TaggedRepository基于指定 store 创建 tagged cache

记忆化缓存:

函数签名说明
Memo() cachecontract.MemoRepository请求/任务内记忆化缓存入口
MemoFrom(storeName string) cachecontract.MemoRepository基于指定 store 的记忆化缓存

关闭选项:

go
func ManagerCloseOption() containercontract.BindingOption

返回缓存 Manager 的关闭选项,供 bootstrap 注册时使用。


Config Facade ​

包路径: github.com/prismgo/framework/config

服务键名: "config.default"

底层类型: *Config

Config Facade 提供对应用配置的便捷访问。配置数据来源于 config/ 目录下的 Go 文件和 .env 文件。

解析方法 ​

go
func Resolve() *Config

可用函数 ​

函数签名说明
Clone() *Config复制当前配置访问器,返回持有独立配置仓库的新实例
Empty() bool判断当前配置访问器是否尚未持有任何配置项
Reload() error从项目根目录 .env 重新加载当前配置对象
Get(path string, defaultValue ...any) string读取字符串配置,缺失时回退到默认值
GetString(path string, defaultValue ...any) string读取字符串配置
GetInt(path string, defaultValue ...any) int读取整型配置
GetFloat64(path string, defaultValue ...any) float64读取 float64 配置
GetInt64(path string, defaultValue ...any) int64读取 int64 配置
GetUint(path string, defaultValue ...any) uint读取 uint 配置
GetBool(path string, defaultValue ...any) bool读取布尔配置
GetStringMapString(path string) map[string]string读取 map[string]string 配置
GetStringMap(path string) map[string]any读取 map[string]any 配置

使用示例:

go
import "github.com/prismgo/framework/config"

// 读取字符串配置
appName := config.Get("app.name", "PrismGo")

// 读取整数配置
port := config.GetInt("app.port", 8080)

// 读取布尔配置
debug := config.GetBool("app.debug", false)

// 重新加载 .env
if err := config.Reload(); err != nil {
    // 处理错误
}

Route Facade ​

包路径: github.com/prismgo/framework/route

服务键名: "route.router"

底层类型: *Router

Route Facade 提供 HTTP 路由注册和管理的便捷访问。底层基于 Gin 框架。

解析方法 ​

go
func Resolve() *Router

可用函数 ​

路由注册:

函数签名说明
Get(uri string, handlers ...HandlerFunc) *Route注册 GET 路由
Post(uri string, handlers ...HandlerFunc) *Route注册 POST 路由
Put(uri string, handlers ...HandlerFunc) *Route注册 PUT 路由
Patch(uri string, handlers ...HandlerFunc) *Route注册 PATCH 路由
Delete(uri string, handlers ...HandlerFunc) *Route注册 DELETE 路由
Options(uri string, handlers ...HandlerFunc) *Route注册 OPTIONS 路由
Match(methods []string, uri string, handlers ...HandlerFunc) *Route注册匹配多个方法的路由
Any(uri string, handlers ...HandlerFunc) *Route注册匹配所有 HTTP 方法的路由
Redirect(uri, destination string, status ...int) *Route注册重定向路由
PermanentRedirect(uri, destination string) *Route注册永久重定向路由
Static(uri, root string) *Route注册静态文件路由
Fallback(handler HandlerFunc) *Route注册 fallback 路由

路由组与属性:

函数签名说明
Prefix(prefix string) *Registrar设置路由前缀
Name(name string) *Registrar设置路由名称
Domain(domain string) *Registrar设置路由域名
Middleware(handlers ...HandlerFunc) *Registrar设置路由中间件
WithoutMiddleware(names ...string) *Registrar排除指定中间件
Controller(controller any) *Registrar绑定控制器
Group(fn func())创建路由组

参数绑定:

函数签名说明
Bind(param string, binder Binder)绑定参数解析器
Model(param string, binder Binder)绑定模型解析器
Pattern(param, expr string)设置参数正则约束

路由信息:

函数签名说明
Mount(engine *gin.Engine) error将路由挂载到 Gin 引擎
List() []RouteInfo列出所有已注册路由
URL(name string, params map[string]any) (string, error)根据路由名和参数生成 URL

使用示例:

go
import "github.com/prismgo/framework/route"

// 注册路由
route.Get("/users", func(ctx *gin.Context) {
    ctx.JSON(200, gin.H{"message": "Hello"})
})

// 路由组
route.Prefix("/api").Group(func() {
    route.Get("/users", ListUsers)
    route.Post("/users", CreateUser)
})

// 命名路由生成 URL
url, _ := route.URL("user.profile", map[string]any{"id": 123})

Logger Facade ​

包路径: github.com/prismgo/framework/logger

服务键名: "logger.manager"

底层类型: *Manager

Logger Facade 提供结构化日志记录的便捷访问。底层基于 logrus,支持多通道(Channel)日志输出。

解析方法 ​

go
func Resolve() *Manager

可用函数 ​

函数签名说明
DefaultName() string返回默认通道名称
Close() error释放已构造通道的底层驱动资源
Channel(name string) Logger按名称获取通道 Logger
Debug(args ...any)通过默认通道记录 debug 日志
Debugf(format string, args ...any)按格式记录 debug 日志
Info(args ...any)记录 info 日志
Infof(format string, args ...any)按格式记录 info 日志
Warn(args ...any)记录 warn 日志
Warnf(format string, args ...any)按格式记录 warn 日志
Error(args ...any)记录 error 日志
Errorf(format string, args ...any)按格式记录 error 日志
Fatal(args ...any)记录 fatal 日志
Fatalf(format string, args ...any)按格式记录 fatal 日志
WithField(key string, value any) Logger附加单个上下文字段
WithFields(fields map[string]any) Logger附加多个上下文字段
WithError(err error) Logger附加错误上下文
WithContext(ctx context.Context) Logger附加 context 关联字段

使用示例:

go
import "github.com/prismgo/framework/logger"

// 基本日志
logger.Info("Server started on port", port)
logger.Infof("Server started on port %d", port)

// 带字段的结构化日志
logger.WithField("request_id", reqID).Info("Processing request")

// 使用指定通道
logger.Channel("stack").Debug("debug message")

// 错误日志
logger.WithError(err).Error("Failed to process")

Database Facade ​

包路径: github.com/prismgo/framework/database

服务键名: "database.default"

底层类型: *gorm.DB

Database Facade 提供 GORM 数据库连接的便捷访问。

解析方法 ​

go
func Resolve() *gorm.DB

可用函数 ​

函数签名说明
DBCloseOption() containercontract.BindingOption返回数据库连接的关闭选项,供 bootstrap 注册时使用

使用示例:

go
import "github.com/prismgo/framework/database"

// 获取 GORM DB 实例
db := database.Resolve()

// 执行查询
var users []User
db.Find(&users)

Filesystem Facade ​

包路径: github.com/prismgo/framework/filesystem

服务键名: "filesystem.manager"

底层类型: *Manager

Filesystem Facade 提供文件存储操作的便捷访问。支持本地磁盘和云存储(如 S3、OSS 等)。

解析方法 ​

go
func Resolve() *Manager

可用函数 ​

磁盘选择与基本信息:

函数签名说明
DefaultName() string返回默认磁盘名称
CloudName() string返回配置的云磁盘名称
Default() fscontract.Repository返回默认磁盘对应的 Repository
Disk(name string) fscontract.Repository返回指定名称的全局磁盘
Name() string返回默认磁盘的仓储名称
Close() error关闭全局管理器中已创建的磁盘实例

写入操作:

函数签名说明
Put(ctx, key, value any, opts ...PutOptions) error写入内容
PutReader(ctx, key string, reader io.Reader, opts ...PutOptions) error写入 Reader 内容
PutFile(ctx, dir string, file *multipart.FileHeader, opts ...PutOptions) (string, error)按原文件名保存上传文件
PutFileAs(ctx, dir string, file *multipart.FileHeader, name string, opts ...PutOptions) (string, error)按指定文件名保存上传文件

读取操作:

函数签名说明
Get(ctx, key string) ([]byte, error)读取文件内容
OpenStream(ctx, key string) (io.ReadCloser, FileInfo, error)以流式方式打开文件
Download(ctx, key string, w io.Writer) error将文件内容复制到指定 Writer

文件检查与操作:

函数签名说明
Exists(ctx, key string) (bool, error)判断文件是否存在
Delete(ctx, keys ...string) error删除文件
Copy(ctx, src, dst string) error复制文件
Move(ctx, src, dst string) error移动文件
Path(key string) string返回物理路径或逻辑路径
Size(ctx, key string) (int64, error)返回文件大小
LastModified(ctx, key string) (time.Time, error)返回最后修改时间
LastModifiedInfo(ctx, key string) (FileInfo, error)返回完整文件元信息

目录操作:

函数签名说明
MakeDirectory(ctx, dir string) error创建目录
DeleteDirectory(ctx, dir string) error删除目录
Files(ctx, dir string) ([]string, error)列出当前层文件
AllFiles(ctx, dir string) ([]string, error)递归列出文件
Directories(ctx, dir string) ([]string, error)列出当前层目录
AllDirectories(ctx, dir string) ([]string, error)递归列出目录

URL 与可见性:

函数签名说明
URL(key string) (string, error)生成公开访问地址
TemporaryURL(ctx, key string, expiry time.Time) (string, error)生成临时签名地址
SetVisibility(ctx, key, visibility string) error设置文件可见性
GetVisibility(ctx, key string) (string, error)获取文件可见性

临时 URL 校验:

go
func VerifyTemporaryURL(disk, key string, expires time.Time, signature string) error

校验本地临时链接的签名和过期时间。

关闭选项:

go
func ManagerCloseOption() containercontract.BindingOption

返回文件系统 Manager 的关闭选项,供 bootstrap 注册时使用。

使用示例:

go
import "github.com/prismgo/framework/filesystem"

// 写入文件
if err := filesystem.Put(ctx, "avatars/user1.jpg", data); err != nil {
    return err
}

// 读取文件
content, err := filesystem.Get(ctx, "avatars/user1.jpg")

// 使用指定磁盘
repo := filesystem.Disk("s3")
if err := repo.Put(ctx, "docs/report.pdf", pdfData); err != nil {
    return err
}

// 生成临时 URL
url, err := filesystem.TemporaryURL(ctx, "docs/report.pdf", time.Now().Add(1*time.Hour))

Facade 类参考 ​

下表汇总了所有可用的 Facade 及其底层类和服务容器绑定键:

Facade(包路径)底层类型服务容器绑定键
github.com/prismgo/framework/cache*Manager"cache.manager"
github.com/prismgo/framework/config*Config"config.default"
github.com/prismgo/framework/route*Router"route.router"
github.com/prismgo/framework/logger*Manager"logger.manager"
github.com/prismgo/framework/database*gorm.DB"database.default"
github.com/prismgo/framework/filesystem*Manager"filesystem.manager"

Laravel Facade 映射 ​

如果你熟悉 Laravel 的 Facade 系统,下表可以帮助你快速找到 PrismGo 中对应的 Facade:

Laravel FacadePrismGo 包说明
Cachecache缓存管理(Memory / Redis / File / Failover)
Configconfig配置管理
Routeroute路由注册与管理
Loglogger结构化日志
DBdatabase数据库查询(GORM)
Storagefilesystem文件存储(本地 / 云存储)