重构 golang 函数 - 应该使用什么类型?

分享于2023年05月08日 go kubernetes 问答
【问题标题】:Refactor golang function - what type should be used?重构 golang 函数 - 应该使用什么类型?
【发布时间】:2023-05-05 06:13:01
【问题描述】:

请大家告诉我如何重构以下函数?

我想要一个功能,例如。 getResource(name string, resourceType ????) []v1.????? ,但不知道它的返回类型是什么。

func getPods(name string) []v1.Pod {
    pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), getListOption(name))

    if err != nil {
        panic(err.Error())
    }
    return pods.Items
}

func getServices(name string) []v1.Service {
    services, err := clientset.CoreV1().Services(namespace).List(context.TODO(), getListOption(name))

    if err != nil {
        panic(err.Error())
    }
    return services.Items
}


【解决方案1】:

虽然调用几乎相同,内容也几乎相同,但它们的类型不同。 CoreV1().Pods(namespace).List 是:

List(ctx context.Context, opts metav1.ListOptions) (*v1.PodList, error)

CoreV1().Services(namespace).List

List(ctx context.Context, opts metav1.ListOptions) (*v1.ServiceList, error)

一个返回 *v1.PodList ,另一个返回 *v1.ServiceList 。这两个不同的对象都有 Items ,但一个是 []*Service ,另一个是 []*Pod

我个人也会考虑不包装。我会改为调用底层函数,在这两种情况下都使用相同的 CoreV1 客户端。 我当然不会尝试将它们组合成一个函数。

如果这里有什么要组合的话,就是命名空间和名称:

type ByName struct {
   Name string
   Namespace string
   v1 corev1.CoreV1Interface
}

func (b *ByName)Services(ctx context.Context) []v1.Service , error {
   return b.v1.Services(namespace).List(ctx,  getListOption(b.Name))
}

func (b *ByName)Pods(ctx context.Context) []v1.Pod, error {
  return b.v1.Pods(b.Namespace).List(ctx, getListOption(b.Name))
}

现在您不必传递名称和命名空间:

b := &ByName{
  Name: name,
  Namespace: namespace,
  v1: clientset.CoreV1(),
}

if svcs, err :=  b.Services(); err != nil {
   return nil, err
} else if pods, err := b.Pods(); err != nil {
  return nil, err
} else {
  ... continue processing
}

而且您无需进行大量类型检查即可获得所需的简洁性。

【讨论】: