当前位置: 首页 > wzjs >正文

网站投票功能做一个销售网站需要多少钱

网站投票功能,做一个销售网站需要多少钱,广州市网络预约出租汽车综合业务管理平台,广西网站建设软件推广基于 govaluate 的监控系统中,如何设计灵活可扩展的自定义表达式函数体系 背景(Situation) 在现代监控系统中,用户往往需要通过灵活的表达式语言来定义告警规则、指标计算和复杂条件判断。govaluate 是 Go 语言中一个强大的表达式…

基于 govaluate 的监控系统中,如何设计灵活可扩展的自定义表达式函数体系


背景(Situation)

在现代监控系统中,用户往往需要通过灵活的表达式语言来定义告警规则、指标计算和复杂条件判断。govaluate 是 Go 语言中一个强大的表达式求值库,支持自定义函数扩展,满足复杂业务需求。

然而,随着监控场景和产品线的多样化,单一的表达式函数集合难以满足所有业务需求:

  • 不同产品或模块需要注册不同的自定义函数集合
  • 业务上下文(如实例、任务、策略ID)会影响函数的行为
  • 需要动态加载和扩展函数,避免代码耦合和重复

如果直接在代码中硬编码所有函数,维护成本高,扩展困难,且难以支持多产品多策略。


目标(Task)

设计一个灵活、可扩展的自定义表达式函数注册体系,满足以下需求:

  • 支持多产品、多策略的函数注册和调用
  • 允许根据业务上下文动态创建函数实例
  • 统一管理函数注册,方便维护和扩展
  • 利用 govaluate 执行表达式时,能调用对应的自定义函数
  • 设计清晰,易于理解和使用

解决方案(Action)

1. 设计接口和结构体

定义统一接口 GoValuateServiceInterface,包含注册函数方法 RegistryFunc,不同产品实现该接口,注册各自的函数集合。

type GoValuateServiceInterface interface {RegistryFunc(funcMap map[string]govaluate.ExpressionFunction) map[string]govaluate.ExpressionFunction
}

定义结构体 GoValuateService,携带业务上下文(实例、任务、策略ID等),函数实现依赖上下文。

2. 设计全局注册表和注册函数

使用全局 map GoValuateServiceMap,key 为产品名,value 为服务构造函数。通过注册函数 RegistryGoValuateServiceMap 注册不同产品的构造函数。

var GoValuateServiceMap map[string]func(*GoValuateService) GoValuateServiceInterfacefunc RegistryGoValuateServiceMap(product string, service func(*GoValuateService) GoValuateServiceInterface) {if GoValuateServiceMap == nil {GoValuateServiceMap = make(map[string]func(*GoValuateService) GoValuateServiceInterface)}GoValuateServiceMap[product] = service
}

3. 实现服务构造函数和函数注册

实现构造函数 NewGoValuateService,返回实现了接口的服务实例。

RegistryFunc 中注册自定义函数,如 lenisStringHasPrefixtoFloat 等。

4. 运行时动态加载函数

在业务代码中,根据产品名从注册表获取构造函数,创建服务实例,调用 RegistryFunc 注册函数到 funcMap

使用 govaluate 创建表达式,传入自定义函数映射,执行表达式。


完整示例代码

package mainimport ("fmt""github.com/Knetic/govaluate""strings"
)// --------------------
// 1. 定义接口和结构体
// --------------------type GoValuateServiceInterface interface {RegistryFunc(funcMap map[string]govaluate.ExpressionFunction) map[string]govaluate.ExpressionFunction
}type GoValuateService struct {// 业务上下文示例字段Ins         stringTask        stringStrategyID  stringConditionID string
}// --------------------
// 2. 实现自定义函数
// --------------------func (g *GoValuateService) GetValueLen(args ...interface{}) (interface{}, error) {if len(args) != 1 {return nil, fmt.Errorf("len expects exactly 1 argument")}switch v := args[0].(type) {case string:return float64(len(v)), nilcase []interface{}:return float64(len(v)), nildefault:return nil, fmt.Errorf("unsupported type for len")}
}func (g *GoValuateService) IsStringHasPrefix(args ...interface{}) (interface{}, error) {if len(args) != 2 {return nil, fmt.Errorf("isStringHasPrefix expects exactly 2 arguments")}str, ok1 := args[0].(string)prefix, ok2 := args[1].(string)if !ok1 || !ok2 {return nil, fmt.Errorf("arguments must be strings")}return strings.HasPrefix(str, prefix), nil
}func (g *GoValuateService) ToFloat(args ...interface{}) (interface{}, error) {if len(args) != 1 {return nil, fmt.Errorf("toFloat expects exactly 1 argument")}switch v := args[0].(type) {case float64:return v, nilcase int:return float64(v), nilcase string:var f float64_, err := fmt.Sscanf(v, "%f", &f)if err != nil {return nil, err}return f, nildefault:return nil, fmt.Errorf("unsupported type for toFloat")}
}// --------------------
// 3. 实现 RegistryFunc 注册函数
// --------------------func (g *GoValuateService) RegistryFunc(funcMap map[string]govaluate.ExpressionFunction) map[string]govaluate.ExpressionFunction {funcMap["len"] = g.GetValueLenfuncMap["isStringHasPrefix"] = g.IsStringHasPrefixfuncMap["toFloat"] = g.ToFloatreturn funcMap
}// --------------------
// 4. 定义全局注册表和注册函数
// --------------------var GoValuateServiceMap map[string]func(*GoValuateService) GoValuateServiceInterfacefunc RegistryGoValuateServiceMap(product string, service func(*GoValuateService) GoValuateServiceInterface) {if GoValuateServiceMap == nil {GoValuateServiceMap = make(map[string]func(*GoValuateService) GoValuateServiceInterface)}GoValuateServiceMap[product] = service
}// --------------------
// 5. 实现服务构造函数
// --------------------func NewGoValuateService(goValuateService *GoValuateService) GoValuateServiceInterface {return goValuateService
}// --------------------
// 6. main 演示流程
// --------------------func main() {// 6.1 注册服务构造函数RegistryGoValuateServiceMap("default", NewGoValuateService)// 6.2 创建上下文数据goValuateService := &GoValuateService{Ins:         "instance1",Task:        "taskA",StrategyID:  "strategy123",ConditionID: "condition456",}// 6.3 初始化函数映射funcMap := make(map[string]govaluate.ExpressionFunction)// 6.4 遍历注册表,调用 RegistryFunc 注册所有函数for _, serviceConstructor := range GoValuateServiceMap {serviceInstance := serviceConstructor(goValuateService)funcMap = serviceInstance.RegistryFunc(funcMap)}// 6.5 定义表达式,调用自定义函数expressionStr := "len('hello') > 3 && isStringHasPrefix('golang', 'go') && toFloat('3.14') > 3"expression, err := govaluate.NewEvaluableExpressionWithFunctions(expressionStr, funcMap)if err != nil {panic(err)}// 6.6 计算表达式result, err := expression.Evaluate(nil)if err != nil {panic(err)}fmt.Printf("表达式结果: %v\n", result) // 期望输出: true
}

结果(Result)

通过该设计,监控系统实现了:

  • 灵活扩展:新增产品只需注册对应构造函数和函数集合,无需修改核心代码
  • 解耦清晰:函数注册和业务逻辑分离,代码结构清晰,易于维护
  • 动态上下文支持:函数实现可访问业务上下文,支持复杂业务需求
  • 统一管理:全局注册表集中管理所有产品的函数构造,方便查找和调用
  • 高复用性:公共函数可复用,不同产品可定制专属函数,满足多样化需求

设计模式分析

  • 工厂模式:通过注册表和构造函数动态创建服务实例
  • 策略模式:不同产品实现不同函数注册策略,接口统一调用
  • 单例模式(变体):全局注册表唯一管理构造函数
  • 依赖注入:构造函数注入业务上下文,函数实现依赖上下文数据

总结

在复杂的监控系统中,表达式函数的灵活扩展和管理是关键。通过结合工厂、策略等设计模式,利用注册表集中管理构造函数,实现了高内聚低耦合的自定义函数体系。

该方案不仅提升了代码的可维护性和扩展性,也为业务快速迭代和多产品支持提供了坚实基础。


文章转载自:

http://KVBUx3eY.ygqhd.cn
http://wKWK5s7a.ygqhd.cn
http://uH9EmTdK.ygqhd.cn
http://zHaJ5sYc.ygqhd.cn
http://KJ9YgqUc.ygqhd.cn
http://jDhgGxFB.ygqhd.cn
http://oQb73UHI.ygqhd.cn
http://Q24JkN2X.ygqhd.cn
http://OF2M3VXP.ygqhd.cn
http://hnvREy2a.ygqhd.cn
http://oveE9xJ4.ygqhd.cn
http://GybWgBna.ygqhd.cn
http://RNdi1w1u.ygqhd.cn
http://AL0zqv9n.ygqhd.cn
http://FY4QPe0T.ygqhd.cn
http://fLyRluHf.ygqhd.cn
http://XsTMxpXf.ygqhd.cn
http://PXCxfLcU.ygqhd.cn
http://4qSh5ls0.ygqhd.cn
http://dghhQ9pM.ygqhd.cn
http://INFMA08o.ygqhd.cn
http://wH5if1Y5.ygqhd.cn
http://1o5pCZ5n.ygqhd.cn
http://gvmfD3wQ.ygqhd.cn
http://9LVkcwHX.ygqhd.cn
http://HaZ4rrv7.ygqhd.cn
http://5gEyIXYu.ygqhd.cn
http://OowHmDoR.ygqhd.cn
http://NdqcPHZu.ygqhd.cn
http://WUojN742.ygqhd.cn
http://www.dtcms.com/wzjs/702508.html

相关文章:

  • 网站建设项目规划书案例通辽公司做网站
  • 郑州高端网站建设团队茌平网站建设价格
  • 襄阳网站建设知名品牌线上装修平台有哪些
  • 做微信公众号网站08影院wordpress影视主题源码
  • 大连网站排名系统今天刚刚发生的重大新闻
  • 有自己的域名怎么建立网站100m光纤做网站
  • 网站功能模块表格任丘做网站
  • 网站计算机培训机构哪个最好网站建设公司代理
  • 佛山新网站建设服务公司内蒙古建设工程交易中心网站
  • 美食怎么做的小视频网站安庆哪里做网站
  • 如何建立小企业网站项目管理软件是用来干嘛的
  • app网站多少钱金螳螂家装官网
  • 做ppt卖给网站代理网站是什么
  • 如何查看网站 是哪家做的建筑工程教育网官方网站
  • 廊坊网站建设案例建站之星
  • 网站建设技术清单网络工程师的前景
  • 做买鞋网站的论文wordpress当面付回调地址
  • 娄底建设局官方网站北京响应式网站建设费用
  • 民政网站建设情况汇报大连 网站维护
  • 广州市建设厅官方网站右玉网站建设
  • 做网站 卖会员室内装饰设计公司
  • 全flash网站制作wordpress 地图
  • 常见的网站空间服务商邯郸市城乡建设管理局网站
  • wap网站代码北京网站建设公司排名浩森宇特
  • 插画师个人网站是怎么做的深圳龙岗属于什么风险
  • 网站代码 字体wordpress可以生成静态吗
  • 中小企业的网站建设方案免费做抽奖的h5网站
  • 织梦做的网站图片显示不了宁波企业品牌网站建设
  • 西安 网站空间开发前端和后端的区别
  • 网站用的什么字体网页设计与网站开发的卷子