在《使用Golang实现一套流程可配置,适用于广告、推荐系统的业务性框架——简单应用》中,我们看到了各种组合Handler的组件,如HandlerGroup和Layer。这些组件下面的子模块又是不同组件,比如LayerCenter的子组件是Layer。如果此时我们希望某个Layer只要执行一个HandlerGroup,还需要设计一个Divider来满足Layer的设计。这样就会导致整个框架非常难以使用。
为了解决这个问题,我们让所有组件(除了Divider)都继承了HandlerBaseInterface。
type HandlerBaseInterface interface {
ConcreteInterface
Handle(context *ghgroupscontext.GhGroupsContext) bool
}
这样我们就可以保证各个组件可以通过统一的接口调用。更进一步,我们在组织它们关系时,Handler、HandlerGroup、AsyncHandlerGroup、Layer和LayerCenter都是等价的,即它们可以相互替换。
举个例子,LayerCenter下每个Layer可以不是Layer,而是上述任何一个组件。
再比如Layer下每个组件,也不必是Handler,也可以上上述任何组件。
HandlerGroup、AsyncHandlerGroup下也不用是Handler,而是上述其他组件。
正是这种随意组合的特性,让这个框架更加灵活。
组合用法
在github中,我们展示了几个组合。其中一个配置如下。
# layer_center_main.yaml
type: LayerCenter
name: layer_center_main
layers:
- layer_c
- handler_group_e
- async_handler_group_f
- layer_g
- example_layer_center_a
- ExampleDHandler
运行结果如下:
layer_center_main
layer_c
ExampleCDivider
ExampleC1Handler
ExampleC2Handler
handler_group_e
ExampleE1Handler
ExampleE2Handler
async_handler_group_f
ExampleF1Handler
ExampleF2Handler
layer_g
ExampleGDivider
ExampleG1Handler
ExampleG2Handler
example_layer_center_a
layer_a
ExampleADivider
ExampleA1Handler
ExampleA2Handler
layer_b
ExampleBDivider
ExampleB1Handler
ExampleB2Handler
ExampleDHandler
run ExampleC2Handler
run ExampleE1Handler
run ExampleE2Handler
run ExampleF2Handler
run ExampleF1Handler
run ExampleG1Handler
run ExampleA2Handler
run ExampleB1Handler
run ExampleDHandler