doutuzhuohao6449 2016-12-30 21:47
浏览 39
已采纳

在Go中获得不同但相似类型的类似数组行为的最佳方法?

Scenario: I have a few different clients, each interacting with a different API.

The data fields of these clients are the same:

type clientX struct {
   key string
   secret string
   client *http.Client
}

However these clients each have many methods (all different from each other):

func (c *ClientX) someMethod() (*ResponseType, error) {
    //code
}

The amount of clients may change over time, as support for new APIs is added, or some number of APIs go offline. Therefore, all functions in the main package need to be modular and adaptable to accept a variable number of clients as arguments.

What is the best way to go about this problem? I can't put the clients in an array because they are different types.

Ideas I'm toying around with:

  1. The first solution that comes to mind is an array of type interface{}. However I'm concerned of the performance of an []interface{} as well as the code-bloat I'll have from identifying client types when iterating through the array (type-assertions).

  2. I'm not as educated on inheritance as I'd like to be, so I'm not sure if this works. I'm envisioning creating a parent class Client containing the key, secret, and client data fields. The specific clients will be subclasses inheriting from the parent class Client, and then defining all the methods specific to that client. From my basic understanding, I could then put all of these clients into an array by defining the array type as Client. This leaves me a bit confused on how the elements in the array would behave as the would not be of type ClientX but of the more general type Client. Would this lead to having to type assert all over again aka the same problem as in solution 1? If Im going to have to ID and assert the type anyway are there any performance benefits to having an array of type Client over an array of type interface?

  3. Have the clients (clientA, clientB, clientC) be global variables. Any function can access them so I won't have to pass them as arguments. In order to handle variable clients (the number is decided at runtime) I would have a clientsEnabled map[string]bool for functions to identify which clients to use and which to ignore. This seems like it would have minimal code-bloat. However, I'm wary of using globals, and was always taught to avoid unless absolutely necessary.

  4. Another solution that the SO community has

Would love to have some feedback, thank you.

  • 写回答

2条回答 默认 最新

  • douchuose2514 2016-12-30 23:22
    关注

    First of, there is no inheritance in golang. Also, I'd highly recommend reading about interfaces in golang.

    As for this problem specifically, instead of storing interface{} instances, I'd introduce a command interface and implement it for each API with which the application would have to work. Something like this: https://play.golang.org/p/t5Kldpbu-P.

    Since you mentioned that there is no common behaviour amongst the client commands, I wouldn't introduce interfaces for their methods unless there are inter-dependencies amongst them. Interfaces in that case would make them easy to unit test (create a mock that implements the interface).

    This is simple and easy to extend.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥30 python代码,帮调试,帮帮忙吧