如何在Golang中根据参数调用不同的函数代码(可插拔)

huangapple go评论74阅读模式
英文:

How to call different function code based on parameters(Pluggable) in Golang

问题

我想实现一个项目,根据不同的启动参数或配置文件,实现几个不同的功能,即一个可插拔的功能集合。期望的效果是,main.go 可以根据参数调用 cmd/<feature>/<feature>.go 中的 run function

项目比较复杂,需要进行扩展。

是否有可以学习的 设计模式现有项目,如果有的话,希望能给予建议。

非常感谢您的帮助。

英文:

I would like to implement a project that enables several different features based on different startup parameters or configuration files, a pluggable feature set. The desired effect is that main.go can call the run function in cmd/&lt;feature&gt;/&lt;feature&gt;.go according to the parameters

├── cmd
│&#160;&#160; ├── feature1
│&#160;&#160; │&#160;&#160; └── feature1.go
│&#160;&#160; └── feature2
│&#160;&#160;     └── feature2.go
├── pkg
│&#160;&#160; ├── feature1
│&#160;&#160; │&#160;&#160; └── feature1.go
│&#160;&#160; └── feature2
│&#160;&#160;     └── feature2.go
└── main.go

Projects are complex and need to be extended

Is there a design pattern or an existing project that can be learned, if there is hope you can give advice

I really appreciate any help with this.

答案1

得分: 1

这里有两个需要讨论的事情。

  1. 项目结构
  2. 可扩展性和可维护性

如果你想构建一个单一的应用程序,我建议你在cmd目录下有一个模块,所有的功能都在pkg目录下(每个应用程序一个cmd目录/文件):

├── cmd
│   └── main.go
└── pkg
    ├── features
    │   ├── feature1.go
    │   ├── feature2.go
    │   └── feature3.go
    └── service
        └── service.go

如果功能集应该是可扩展的,你可能需要一个接口,所有的功能都将实现该接口,例如:

type Feature interface {
    Run(context.Context) error
}

此外,你将拥有一个应该使用提供的功能构建的服务:

// pkg/service/service.go

type Service interface {
    Run(context.Context) error
}

// service是Service的实现
type service struct {
    features []Feature
}

// Run运行服务。服务运行功能。
func (s *service) Run(ctx context.Context) error {
    for _, f := range s.features {
        err := f.Run(ctx)
        // 检查错误
    }
    // 你的其余代码
}

创建一个具有任意功能集的服务应该很容易。最简单的方法是将功能切片传递给服务构造函数:

func NewService(features []Feature) Service {
    return &service{features: features}
}

将功能传递给服务构造函数的更优雅的方法是使用函数选项模式

英文:

There're two things that should be discussed here.

  1. Project structure
  2. Extendability and maintainability

If you want to build a single application, I would recommend you to have one module in the cmd directory and all features in the pkg directory (one cmd dir/file per application):

├── cmd
│   └── main.go
└── pkg
    ├── features
    │   ├── feature1.go
    │   ├── feature2.go
    │   └── feature3.go
    └── service
        └── service.go

If the feature set should be extendable, you probably will need an interface, that will be implemented by all features, for example:

type Feature interface {
    Run(context.Context) error
}

Also, you will have a service that should be constructed with provided features:

// pkg/service/service.go

type Service interface {
    Run(context.Context) error
}

// service is the Service implementation
type service struct {
    features []Feature
}

// Run runs the service. The service runs the features.
func (s *service) Run (ctx context.Context) error {
    for _, f := range s.features {
        err := f.Run(ctx)
        // check the error
    }
    // the rest of your code 
}

It should be easy to create a service with an arbitrary set of features. The simplest way is to pass a slice of features to the service constructor function:

func NewService(features []Feature) Service {
    return &amp;service{features: features}
}

A more elegant way to pass your features to the service constructor is to use functional options pattern.

huangapple
  • 本文由 发表于 2022年2月23日 21:10:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/71237561.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定