golang变相实现抽象类
golang里的struct只能有属性, interface只能有方法定义。这点在java里很好实现的abstract class在这里就不能直接实现, 可以通过struct和interface的结合定义,实现抽象类的类似的功能。
直接上代码:
代码都来之与项目
GitHub - golang fot xxl-job executor
在这个项目里,重构了executor和默认的RestfulExecutor的实现方式, 就是采用了上述的方式。
先定义接口 // executor 执行器 type executor interface { // Init // 初始化执行器 Init(opts ...Option) // Run 启动服务 Run() error // Registry 注册执行器到调度中心 Registry() // UnRegistry 从调度中心在注销执行器 UnRegistry() error // SetLogHandler 日志handler SetLogHandler(handler LogHandler) // Stop 停止服务 Stop() // RequestCallback 执行后回调请求给调度中心 RequestCallback(task *Task, code int64, msg string) // RegTask // 注册任务 RegTask(pattern string, task TaskFunc) }
然后定义我们需要的抽象类 type Executor struct { executor // private opts Options address string regList *taskPool //注册任务列表 runList *taskPool //正在执行任务列表 log log4go.Logger logHandler LogHandler //日志查询handler // inner _impl executor // 这里很关键,是实现抽象类的重要地方 } // 这里很关键,是实现抽象类的重要地方,封装一个wrap方法, func (e *Executor) wrap(_wrap executor) { e._impl = _wrap }
实现抽象类里的主要方法 func (e *Executor) Init(opts ...Option) { for _, o := range opts { o(&e.opts) } e.log = e.opts.logger e.regList = &taskPool{ data: make(map[string]*Task), } e.runList = &taskPool{ data: make(map[string]*Task), } e.address = e.opts.ExecutorIp + ":" + e.opts.ExecutorPort e.log.Info("%v %v", EXECUTOR4G_VERSION, e.address) go e.Registry() // 这里的Regstry是子类需要实现的方法 } // Registry 注册执行器到调度中心 func (e *Executor) Registry() { /// 用wrap方式把调用交换具体的子类 e._impl.Registry() }
子类实现 type RestFulExecutor struct { Executor mu sync.RWMutex } // Registry // 注册执行器到调度中心 func (e *RestFulExecutor) Registry() { t := time.NewTimer(time.Second * 0) //初始立即执行 defer t.Stop() .... }
最关键的地方,调用 func newExecutor(opts ...Option) executor { //var exec executor options := newOptions(opts...) if options.executorImpl == nil { // 变相的抽象类的实现 e := &RestFulExecutor{} e.wrap(e) // 最关键的地方,使用wrap把具体实现子类包装进返回接口 e.opts = options return e } else { return options.executorImpl } }
具体代码可以查看项目中的源码
项目地址
GitHub - gohutool/boot4go-xxljob-executor: golang fot xxl-job executor
推荐几个好工具 GitHub - gohutool/boot4go: a bootstrap framework for golang like as spring-boot
GitHub - gohutool/log4go: a logkit like as log4j with go language golang里的日志工具log4go - 知乎
golang中的表达式解析-expression4go 简单的EL - 知乎