业务逻辑需要“规格化”是因为它能解决复杂规则带来的代码混乱和维护困难。1. 规格模式将每个独立规则封装为独立对象,实现解耦与复用;2. 通过and、or、not等组合方式提升可读性与灵活性;3. 支持规则的模块化测试与扩展,使复杂条件清晰表达并易于维护。

Golang实现规格模式,核心在于定义一个统一的
Specification
IsSatisfiedBy

在Golang中实现规格模式,我们首先定义一个接口,然后创建具体的规格实现,最后提供组合这些规格的方法。
package main
import "fmt"
// User 是我们业务中需要被过滤的对象
type User struct {
ID string
Name string
Age int
Status string // e.g., "active", "inactive", "pending"
}
// Specification 接口定义了检查一个对象是否满足特定条件的方法
type Specification interface {
IsSatisfiedBy(user User) bool
}
// AgeGreaterThanSpecification 检查用户年龄是否大于某个值
type AgeGreaterThanSpecification struct {
Age int
}
func (s AgeGreaterThanSpecification) IsSatisfiedBy(user User) bool {
return user.Age > s.Age
}
// UserStatusSpecification 检查用户状态是否匹配
type UserStatusSpecification struct {
Status string
}
func (s UserStatusSpecification) IsSatisfiedBy(user User) bool {
return user.Status == s.Status
}
// AndSpecification 组合多个规格,要求所有规格都满足
type AndSpecification struct {
Specs []Specification
}
func (s AndSpecification) IsSatisfiedBy(user User) bool {
for _, spec := range s.Specs {
if !spec.IsSatisfiedBy(user) {
return false
}
}
return true
}
// OrSpecification 组合多个规格,要求至少一个规格满足
type OrSpecification struct {
Specs []Specification
}
func (s OrSpecification) IsSatisfiedBy(user User) bool {
for _, spec := range s.Specs {
if spec.IsSatisfiedBy(user) {
return true
}
}
return false
}
// NotSpecification 对一个规格取反
type NotSpecification struct {
Spec Specification
}
func (s NotSpecification) IsSatisfiedBy(user User) bool {
return !s.Spec.IsSatisfiedBy(user)
}
func main() {
users := []User{
{ID: "1", Name: "Alice", Age: 25, Status: "active"},
{ID: "2", Name: "Bob", Age: 30, Status: "inactive"},
{ID: "3", Name: "Charlie", Age: 20, Status: "active"},
{ID: "4", Name: "David", Age: 35, Status: "pending"},
}
// 查找年龄大于28岁且状态为"active"的用户
ageSpec := AgeGreaterThanSpecification{Age: 28}
activeSpec := UserStatusSpecification{Status: "active"}
combinedSpec := AndSpecification{Specs: []Specification{ageSpec, activeSpec}}
fmt.Println("年龄大于28岁且状态为'active'的用户:")
for _, user := range users {
if combinedSpec.IsSatisfiedBy(user) {
fmt.Printf("- %s (ID: %s, Age: %d, Status: %s)\n", user.Name, user.ID, user.Age, user.Status)
}
}
// 预期输出: - Bob (ID: 2, Age: 30, Status: inactive) -- 实际不会,因为Bob状态是inactive
// 预期输出: (无,因为没有用户同时满足这两个条件)
fmt.Println("\n年龄大于28岁或状态为'active'的用户:")
orSpec := OrSpecification{Specs: []Specification{ageSpec, activeSpec}}
for _, user := range users {
if orSpec.IsSatisfiedBy(user) {
fmt.Printf("- %s (ID: %s, Age: %d, Status: %s)\n", user.Name, user.ID, user.Age, user.Status)
}
}
// 预期输出:
// - Alice (ID: 1, Age: 25, Status: active)
// - Bob (ID: 2, Age: 30, Status: inactive)
// - Charlie (ID: 3, Age: 20, Status: active)
fmt.Println("\n非活跃状态的用户:")
notActiveSpec := NotSpecification{Spec: activeSpec}
for _, user := range users {
if notActiveSpec.IsSatisfiedBy(user) {
fmt.Printf("- %s (ID: %s, Age: %d, Status: %s)\n", user.Name, user.ID, user.Age, user.Status)
}
}
// 预期输出:
// - Bob (ID: 2, Age: 30, Status: inactive)
// - David (ID: 4, Age: 35, Status: pending)
}说实话,我见过太多项目,业务规则一旦复杂起来,代码里就是一堆
if-else if-else
立即学习“go语言免费学习笔记(深入)”;

规格模式,在我看来,就是为了解决这个痛点。它把每一个独立的业务规则(比如“用户年龄大于18岁”、“用户是高级会员”)封装成一个独立的“规格”对象。这样做的好处显而易见:
AndSpecification{Specs: []Specification{ageSpec, activeSpec}}if user.Age > 18 && user.Status == "active"
And
Or
它就像是把复杂的业务规则拆解成了最基本的原子操作,然后提供了一套机制,让你能像搭积木一样,随意组合这些原子操作,来构建任何你想要的复杂逻辑。
本文档主要讲述的是SCA介绍及应用实例;SCA(Service Component Architecture)是针对SOA提出的一套服务体系构建框架协议,内部既融合了IOC的思想,同时又把面向对象的复用由代码复用上升到了业务模块组件复用,同时将服务接口,实现,部署,调用完全分离,通过配置的形式灵活的组装,绑定。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
0

在Go里实现规格模式,有几个点我觉得特别值得注意,它们关系到代码的优雅和实用性:
IsSatisfiedBy
User
interface{}Filterable
AndSpecification
OrSpecification
NotSpecification
Specification
IsSatisfiedBy
IsSatisfiedBy
bool
IsSatisfiedBy
(bool, error)
bool
规格模式并非万金油,但它在某些特定场景下,能显著提升代码质量。
常见应用场景:
UserStatusSpecification
WHERE status = 'active'
潜在挑战:
if
IsSatisfiedBy
IsSatisfiedBy
总的来说,规格模式是一个非常实用的设计模式,尤其适用于那些业务规则复杂、多变且需要高度可组合性的场景。在Golang中,利用其简洁的接口和结构体特性,实现起来也相当直观。
以上就是怎样用Golang实现规格模式 构建灵活可组合的业务过滤逻辑的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号