以前接触过的一个 Java 项目,实现了一种在我看来很新的做法:
- 代码生成的协议类,里面自带了一个未实现的 process 方法
public class Echo extend Msg {
String msg;
public void decode(){}
public void encode(){}
public void process() throws Exception {
throw new UnsupportedOperationException();
}
}
- 代码生成的协议处理类,格式是这样的
@MsgProcess
public static boolean process(Echo echo) {
return true;
}
- 框架启动的时候,会反射获取到注解
@MsgProcess 的 Metchod 和他的参数,然后用 javaassist 的字节码操作,将协议类Echo 的process 方法给替换掉!这样框架层调用协议的msg.process() 就可以直接执行业务逻辑!
Java 写了 10 年,一说起框架,自然想到的就是各种设计模式抽象继承与反射之类,当写 Go 的时候,也受到影响,我现在想用 Go 实现类似的操作,实践的效果如下
- 代码生成了 Echo 协议类
package proto
type Echo struct {
BaseMsg
Msg string
}
func (msg *Echo) Decode(src *bytes.Buffer) error {}
func (msg *Echo) Encode(dst *bytes.Buffer) error {}
func (msg *Echo) Process() {
panic("implement me")
}
- 代码生成了业务逻辑类
package logic
import proto
func ProcessEcho(msg *proto.Echo) {}
- 使用 ast/parser 将
Echo 的process 的方法体替换为ProcessEcho
func (msg *Echo) Process() {
logic.ProcessEcho(msg)
}
但重新生成的 Echo 类,有一些问题,首先生成出来的文件,我将其保存为echo_override.go 放在另一个 package ,相关的 import 都可能有问题,然后Process import 了 logic ,而 logic 自然要 import echo ,非常经典的 import cycle 。
这是第一步遇到的问题,我打算先用 interface 解决看看,为什么不用 func 替换,我觉得好丑啊!各位 Go 大神有没有什么建议?我这种思路,符合 Go 的设计哲学吗?
|