V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dzdh
V2EX  ›  Go 编程语言

仿佛把自己坑到了不得了的地步。关于 interface

  •  
  •   dzdh · 20 小时 14 分钟前 · 2136 次点击

    做多渠道适配。其他语言的时候,基本上都是起个 interface ,实现个抽象然后改抽象。

    go 也按这么来了

    // 定义个接口
    type I interface {
       Retrieve(s string) error
    }
    // 有个抽象实现
    type Abstract struct {
    }
    func (self *Abstract) Retrieve(s string) error {
        这里有坑
    }
    

    因为是多渠道。但是各个渠道只是 api 地址不一样接口大差不差。但是多多少少有差别,但是行业标准参数名起码都一样。 然后就

    type Channel1 struct { *Abstract }
    type Channel2 struct { *Abstract }
    type Channel3 struct { *Abstract }
    
    func GetChan(s string) {
        switch s {
           case "1":
           	return &Channel1{&Abstract{url, apikey, mode:ws, ....}
        }
    }
    

    今天接了个需求。有 3 个渠道变了,人家比较牛逼,人家自己魔改了协议,需要重新适配。

    但是,也只是修改了 2 个参数名和 URL 或者是编码。但是其他都一样。

    所以。问题来了。我怎么在 Abstract.Retrieve 获取当前的实例名知道是谁被调用了(获取 str=Channel1) 😂

    还是,干脆就重新写,相同的逻辑,尽管 c+v 吧。

    9 条回复    2025-01-23 14:25:25 +08:00
    zeromake
        1
    zeromake  
       20 小时 0 分钟前   ❤️ 1
    Abstract 上挂个 Channel1 的字符串字段不行?
    RayR
        2
    RayR  
       19 小时 54 分钟前   ❤️ 1
    接口的实现还要考虑调用者的信息。那是不是设计需要改了?
    fgwmlhdkkkw
        3
    fgwmlhdkkkw  
       19 小时 44 分钟前 via Android
    反射或者 ctx value
    pkoukk
        4
    pkoukk  
       19 小时 19 分钟前   ❤️ 1
    改架构,因为不同渠道的协议已经不一样了,Abstract 已经不 Abstract 了
    wangym20804
        5
    wangym20804  
       19 小时 5 分钟前
    Channel 里面 override 啊
    zacard
        6
    zacard  
       18 小时 55 分钟前   ❤️ 1
    在 Abstract.Retrieve 中耦合具体渠道的逻辑,明显违反了抽象原则了。直接在 channel1 ,2 ,3 覆盖 Retrieve 方法更合理,或者再抽象出个 XxxProtoAbstract ,统一处理 channel1 ,2 ,3 中相似的逻辑
    zizon
        7
    zizon  
       17 小时 7 分钟前   ❤️ 1
    go 的抽象/interface 是面向过程/行为的.不是面向类别的.

    你想复用要考虑的是一个业务逻辑里的共同行为模式.
    比如
    ···
    func Retrieve(r Retrievable) error{ .
    ...
    }
    ···
    linhaijian
        8
    linhaijian  
       15 小时 26 分钟前
    // 定义个接口
    type I interface {
    Retrieve(s string) error
    Name() string
    }
    // 有个抽象实现
    type Abstract struct {
    name string
    }

    func (self *Abstract) Retrieve(s string) error {
    这里有坑
    }
    func (self *Abstract) Name(s string) string {
    return self.name
    }

    在 Retrieve 里获取 self.Name?
    NessajCN
        9
    NessajCN  
       15 小时 9 分钟前
    go interface 不这么用的

    type I interface {
    Retrieve(s string) error
    }

    type Channel1 struct {...}
    func (c Channel1) Retrieve(s string) error {
    return nil
    }

    type Channel2struct {...}
    func (c Channel2) Retrieve(s string) error {
    return nil
    }

    type Channel3 struct {...}
    func (c Channel3) Retrieve(s string) error {
    return nil
    }

    func GetChan(s string, c I) {
    c.Retrieve(s)
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   909 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 18ms · UTC 21:34 · PVG 05:34 · LAX 13:34 · JFK 16:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.