
python 的逻辑大致如下,但在 go 中不知道怎么做
class A(object): def run(self): pass class B(object): def run(self): pass all_classes = {"a": A, "b": B} for class_type, args in read_config("config_file"): instance = all_classes[class_type](**args) # 或者 instance = getattr(sys.modules[__name__], class_type.upper()) instance.run() 现在能想到的就是写一堆的 if else,然后返回一个 interface{},有更合理的方式吗?
func LoadClass(class_type string, args map[string]string) interface{} { if class_type == "a" { ... } else if ... } 1 hjc4869 2018-01-30 19:28:39 +08:00 via iPhone map |
3 naiba 2018-01-30 19:32:13 +08:00 via Android reflect |
4 rrfeng 2018-01-30 19:33:24 +08:00 via Android 写一个 newstruct 方法,用 map string func 存起来。 |
5 rrfeng 2018-01-30 19:35:23 +08:00 感觉应该从需求上去重新考虑一下。 如果 A 和 B 完全没任何关系,为什么要这样写?如果两者很类似,是不是有更好的数据结构? |
6 douglarek 2018-01-30 20:21:32 +08:00 via iPhone 定义一个接口 Runner 里面有一个方法 run,让不同的 struct 去实现 Runner 然后 loadclass 返回 Runner |
8 looplj 2018-01-30 23:41:21 +08:00 Go 不能通过一个字符串反射出一个对象,所以先要将一个 struct 的构造方式注册。 我们用的是 Model 接口有一个 New 方法,直接返回 new(Model),注册 model 到 factory,然后 factory 通过字符串返回 model 实例。 |
9 Morriaty OP |
11 Morriaty OP @ZSeptember 注册 model 到 factory,这点能说详细点,或者给个示例代码吗? |
12 iRiven 2018-01-31 10:43:17 +08:00 via Android 你姿势不对。 |
14 fortunezhang 2018-01-31 10:58:41 +08:00 简单点就是用 map 复杂点就上设计模式。 |
15 nekoyaki 2018-02-23 13:14:38 +08:00 你的思路不对,go 里不是这么考虑问题的,我提几个提示。 1、golang 不是面向对象的语言,不要套用面向对象语言的设计模式。 2、golang 如果想要实现类似根据不同的类实现多个逻辑的需求,你需要把它转换成结构体来考虑。 3、func 在 golang 里是一等结构,因此结构体上可以有一些成员,这些成员的类型,是特定类型的 func。 4、读取配置文件后,如果是 A 情况,则把该成员赋值为方法 A,如果是 B 情况,则把该成员赋值为方法 B。 |
16 nekoyaki 2018-02-23 13:21:05 +08:00 接上条,手滑发出去了…… 5、这样实例 A 的 run 方法和实例 B 的 run 方法就可以实现不同的逻辑。 伪代码举例如下: ``` type Person Struct { name string tell func()(xxx) } zhangxiaojie = Person{ "baohua", func()(xxx) { fmt.println("Mr. dong lianren ? ") } } jiangxiansheng = Person { "takumin", func()(xxx) { fmt.println("Hou wa! ") }} zhangxiaojie.tell() jiangxiansheng.tell() ``` 这样两个人都是 person 实例,但 tell 方法的逻辑是不同的,不需要在方法逻辑里面来暴力 if else。 |