首页 > 解决方案 > 创建需要其他可重复逻辑作为先决条件的函数(干净的代码)

问题描述

我有以下我需要的 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 中的最佳实践代码示例

如果有不清楚的地方请告诉我:)

标签: godependency-injectioninterface

解决方案


您可以在结构中定义接口并提供实现

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}]

推荐阅读