必须用适配器模式当出现类型不匹配编译错误且无法修改被调用方代码时,典型场景包括接入第三方SDK、新旧系统对接、数据格式转换,关键判断标准是转换逻辑是否需与业务逻辑解耦。
当你遇到 cannot use ... as ... value in assignment: wrong type 这类编译错误,且不能改被调用方代码时,适配器就是最直接的解法。典型场景有三类:
SendSms vs 腾讯云 SendSMS),但业务层只认统一的 SMSSender.Send
OldCalculator.Add)要对接新计算库(NewMathLib.Sum),又不想动原有调用链[]byte,而你定义的接口要求 string 或 json.Ra
wMessage
关键判断标准不是“能不能写 if-else”,而是“这个转换逻辑是否该和业务逻辑解耦”。如果到处散落 string(x.Display()),就该抽成适配器。
Go 没有继承,所以对象适配器靠组合实现,但匿名嵌入(embedding)容易误用。常见错误是把被适配者暴露出去,导致调用方绕过适配逻辑直接调用原方法。
display *LegacyDisplay,不是 *LegacyDisplay)type Adapter struct{ *LegacyDisplay } —— 这会让 adapter.Display() 直接生效,破坏封装nil 时 panic 或返回 error,避免运行时 panic示例中 DisplayAdapter 的 Print() 方法里调用 da.display.Display(),而不是 da.Display(),就是为控制入口唯一性。
是的,尤其适合 HTTP 中间件、回调函数等一次性转换场景。但要注意隐式接口满足带来的“假实现”风险。
HandlerFuncAdapter 只要实现了 ServeHTTP 就算满足 http.Handler,但若漏写 ServeHTTP 方法,编译不报错,运行时报 nil pointer dereference
runtime.Caller 层级偏移像 http.HandlerFunc(func(...){}) 本身就是个函数适配器,Go 标准库大量使用,说明它在简单场景下足够可靠。
应该,而且只需测两件事:输入是否被正确转发、输出是否符合目标接口契约。不用测被适配者本身。
nil 输入、超长 byte sliceerror 被透传或按约定包装,别吞掉最容易被忽略的是并发安全:多个 goroutine 同时调用适配器时,若内部缓存了非线程安全的状态(比如 map 未加锁),就会静默出错。