package main
import ( "fmt" "reflect" "runtime" )
type Context struct{}
type Component interface { Mount(c Component, components ...Component) error Remove(c Component) error Do(ctx *Context) error }
type BaseComponent struct { ChildComponents []Component }
func (bc *BaseComponent) Mount(c Component, components ...Component) (err error) { bc.ChildComponents = append(bc.ChildComponents, c) if len(components) == 0 { return } bc.ChildComponents = append(bc.ChildComponents, components...) return }
func (bc *BaseComponent) Remove(c Component) (err error) { if len(bc.ChildComponents) == 0 { return } for k, childComponent := range bc.ChildComponents { if c == childComponent { fmt.Println(runFuncName(), "移除:", reflect.TypeOf(childComponent)) bc.ChildComponents = append(bc.ChildComponents[:k], bc.ChildComponents[k+1:]...) } } return }
func (bc *BaseComponent) Do(ctx *Context) (err error) { return }
func (bc *BaseComponent) ChildsDo(ctx *Context) (err error) { for _, childComponent := range bc.ChildComponents { if err = childComponent.Do(ctx); err != nil { return err } } return }
type CheckoutPageComponent struct { BaseComponent }
func (bc *CheckoutPageComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "订单结算页面组件...")
bc.ChildsDo(ctx)
return }
type AddressComponent struct { BaseComponent }
func (bc *AddressComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "地址组件...")
bc.ChildsDo(ctx)
return }
type PayMethodComponent struct { BaseComponent }
func (bc *PayMethodComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "支付方式组件...")
bc.ChildsDo(ctx)
return }
type StoreComponent struct { BaseComponent }
func (bc *StoreComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "店铺组件...")
bc.ChildsDo(ctx)
return }
type SkuComponent struct { BaseComponent }
func (bc *SkuComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "商品组件...")
bc.ChildsDo(ctx)
return }
type PromotionComponent struct { BaseComponent }
func (bc *PromotionComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "优惠信息组件...")
bc.ChildsDo(ctx)
return }
type ExpressComponent struct { BaseComponent }
func (bc *ExpressComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "物流组件...")
bc.ChildsDo(ctx)
return }
type AftersaleComponent struct { BaseComponent }
func (bc *AftersaleComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "售后组件...")
bc.ChildsDo(ctx)
return }
type InvoiceComponent struct { BaseComponent }
func (bc *InvoiceComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "发票组件...")
bc.ChildsDo(ctx)
return }
type CouponComponent struct { BaseComponent }
func (bc *CouponComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "优惠券组件...")
bc.ChildsDo(ctx)
return }
type GiftCardComponent struct { BaseComponent }
func (bc *GiftCardComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "礼品卡组件...")
bc.ChildsDo(ctx)
return }
type OrderComponent struct { BaseComponent }
func (bc *OrderComponent) Do(ctx *Context) (err error) { fmt.Println(runFuncName(), "订单金额详细信息组件...")
bc.ChildsDo(ctx)
return }
func main() { checkoutPage := &CheckoutPageComponent{}
storeComponent := &StoreComponent{} skuComponent := &SkuComponent{} skuComponent.Mount( &PromotionComponent{}, &AftersaleComponent{}, ) storeComponent.Mount( skuComponent, &ExpressComponent{}, )
checkoutPage.Mount( &AddressComponent{}, &PayMethodComponent{}, storeComponent, &InvoiceComponent{}, &CouponComponent{}, &GiftCardComponent{}, &OrderComponent{}, )
checkoutPage.Do(&Context{}) }
func runFuncName() string { pc := make([]uintptr, 1) runtime.Callers(2, pc) f := runtime.FuncForPC(pc[0]) return f.Name() }
|