go - 创建需要其他可重复逻辑作为先决条件的函数(干净的代码)
问题描述
我有以下我需要的 yaml 文件parse
(解析按预期工作)并且需要data
从 yaml 文件内容中提供一个应该由以下解耦函数公开的内容
我需要提供以下功能(这里是其中一些功能的示例,需要更多具有相同模式的功能......)
获取应用程序()
获取服务()
获取应用程序(应用程序名称)
GetServiceForApp(应用程序名称)
这是代码(有效......)
var DMZ = []byte(`
applications:
- name: app1
type: php
src: /app1
host: us
use:
- redis
- mysql
- name: app2
type: rust
src: /app2
host: eu
use:
- mongo
- mysql
- name: app3
type: golang
src: /app3
host: us
use:
- postgress
- mysql
services:
- name: mongo
type: db
host: us
- name: mysql
type: db
host: eu
- name: postgress
type: db
host: us
- name: redis
type: db
host: us
`)
这是结构
type DMZ struct {
Applications []*Applications `yaml:"applications,omitempty"`
Services []*Services `yaml:"services,omitempty"`
}
type Applications struct {
Name string
Type string
Src string `yaml:"src,omitempty"`
use []Use `yaml:"use,omitempty"`
}
type Services struct {
Name string
Type string
Host string `yaml:"host,omitempty"`
}
type Use struct {
Name string `yaml:"name,omitempty"`
host string `yaml:"host,omitempty"`
Type string `yaml:"type,omitempty"`
}
// Parse file
func Parse(yamlContent []byte) (out DMZ, err error) {
dmz := DMZ{}
err = yaml.Unmarshal([]byte(yamlContent), &dmz)
if err != nil {
logs.Error("Yaml file is not valid, Error: " + err.Error())
}
return dmz, err
}
由于该Parse
函数是所有需要的函数(我在上面列出的)的必要条件,我想知道如何最好地创建它们,创建简单的函数,每次调用 函数然后执行逻辑(不是问题)但是我想知道是否有更好的方法遵循 Golang 的干净代码原则,使用“接口/依赖注入”?parse
更新:
我想避免做类似下面的事情,假设我需要从不同的包甚至不同的 GitHub 存储库调用这些函数, 如何最好使用 Golang干净的代码来做到这一点。
func getApps(){
dmz := Parse()
....
}
func getServices(){
dmz := Parse()
....
}
func getApp(appname string){
dmz := Parse()
....
}
func GetServiceForApp(appname string){
dmz := Parse()
....
}
而且我需要更多具有相同模式的功能......
我需要一些使用接口/依赖注入的清洁代码解决方案,例如 Golang 中的最佳实践代码示例
如果有不清楚的地方请告诉我:)
解决方案
您可以在结构中定义接口并提供实现
type DMZI interface {
GetApps() []Application
GetService() []Service
GetApp(name string) (Application, error)
GetServiceForApp(name string) ([]string, error)
}
type DMZ struct {
Application []Application `yaml:"applications,omitempty"`
Service []Service `yaml:"services,omitempty"`
}
func (dmz DMZ) GetApps() []Application {
return dmz.Application
}
func (dmz DMZ) GetService() []Service {
return dmz.Service
}
func (dmz DMZ) GetApp(name string) (Application, error) {
for _, app := range dmz.Application {
if app.Name == name {
return app, nil
}
}
return Application{}, fmt.Errorf("Did not find application with name %s", name)
}
func (dmz DMZ) GetServiceForApp(name string) ([]string, error) {
app, err := dmz.GetApp(name)
if err != nil {
return []string{}, err
}
return app.Use, nil
}
type Application struct {
Name string
Type string
Src string `yaml:"src,omitempty"`
Use []string `yaml:"use,omitempty"`
}
type Service struct {
Name string
Type string
Host string `yaml:"host,omitempty"`
}
// Parse file
func Parse(yamlContent []byte) (out DMZI, err error) {
dmz := DMZ{}
err = yaml.Unmarshal([]byte(yamlContent), &dmz)
if err != nil {
fmt.Println("Yaml file is not valid, Error: " + err.Error())
}
return dmz, err
}
因此,您可以在返回的接口上调用方法,例如
fmt.Printf("Apps : %+v\n", dmz.GetApps())
fmt.Printf("Service : %+v\n", dmz.GetService())
更新
评论中要求的主要方法
func main() {
dmz, err := Parse([]byte(ymlStr))
if err != nil {
panic(err)
}
fmt.Printf("Apps : %+v\n", dmz.GetApps())
fmt.Printf("Service : %+v\n", dmz.GetService())
}
将打印
Apps : [{Name:app1 Type:php Src:/app1 Use:[redis mysql]} {Name:app2 Type:rust Src:/app2 Use:[mongo mysql]} {Name:app3 Type:golang Src:/app3 Use:[postgress mysql]}]
Service : [{Name:mongo Type:db Host:us} {Name:mysql Type:db Host:eu} {Name:postgress Type:db Host:us} {Name:redis Type:db Host:us}]
推荐阅读
- typescript - 打字稿中对象文字的类型安全合并
- python - 如何在nodeJS后端执行python脚本
- angular - Angular Textinput 组件不适用于数组
- webpack - 如何配置 webpack - libraryTarget + splitChunks 在另一个项目中导入块
- python - 问题从 Python 中的 CSV 文件中提取列表(Selenium)
- javascript - 普通表单提交时AJAX不提交
- python - 如何使组合框选择填充tkinter上的输入框?
- bash - Bash如何打印命令行参数的下一个元素
- android-softkeyboard - Detox - 如何关闭安卓软键盘?
- r - 由于工作目录中的 .RData ,RGui 加载过时的 .Rprofile