插件工厂和AOP拦截器机制

一. 插件工厂

基于接口机制的插件工厂是一种设计模式,用于创建和管理插件。插件是独立的模块,可以动态加载和卸载,以扩展应用程序的功能。
通过使用接口,插件工厂可以提供一种统一的方式来创建和管理这些插件,而不需要了解插件的具体实现细节。
具体实现来说,实现一个插件工厂通过哈希记录所有名字和插件的映射,实现一个插件接口,进一步对于插件工厂可以实现注册函数给工厂注册插件,通过工厂获取创建插件。

package main

import (
    "fmt"
)

// Plugin 是所有插件必须实现的接口
type Plugin interface {
    DoSomething() string
}

// PluginFactory 是一个插件工厂,用于创建插件
type PluginFactory struct {
    plugins map[string]func() Plugin
}

// RegisterPlugin 注册一个插件
func (f *PluginFactory) RegisterPlugin(name string, factory func() Plugin) {
    if f.plugins == nil {
        f.plugins = make(map[string]func() Plugin)
    }
    f.plugins[name] = factory
}

// CreatePlugin 创建一个插件
func (f *PluginFactory) CreatePlugin(name string) (Plugin, error) {
    if factory, ok := f.plugins[name]; ok {
        return factory(), nil
    }
    return nil, fmt.Errorf("plugin not found: %s", name)
}

// ExamplePlugin 是一个示例插件
type ExamplePlugin struct{}

func (p *ExamplePlugin) DoSomething() string {
    return "ExamplePlugin doing something"
}

func main() {
    factory := &PluginFactory{}

    // 注册插件
    factory.RegisterPlugin("example", func() Plugin {
        return &ExamplePlugin{}
    })

    // 创建并使用插件
    plugin, err := factory.CreatePlugin("example")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println(plugin.DoSomething())
}

二. 拦截器

AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在通过分离横切关注点(如日志记录、事务管理、权限控制等)来提高代码的模块化。
拦截器是 AOP 的一种实现方式,用于在方法调用的前后执行额外的逻辑
具体实现来说,以日志拦截器为例,日志拦截器可以对服务进行拦截,同时返回一个封装了对应服务的日志实例,这样可以通过该实例执行服务前日志,再执行服务,接着执行服务后日志。
就结果而言,跟微服务中间件的链式执行类似,。

package main

import (
    "fmt"
)

// Service 是一个示例服务接口
type Service interface {
    DoSomething() string
}

// RealService 是 Service 的具体实现
type RealService struct{}

func (s *RealService) DoSomething() string {
    return "RealService doing something"
}

// Interceptor 是一个拦截器接口
type Interceptor interface {
    Intercept(Service) Service
}

// LoggingInterceptor 是一个日志拦截器
type LoggingInterceptor struct{}

func (i *LoggingInterceptor) Intercept(service Service) Service {
    return &loggingService{service}
}

type loggingService struct {
    Service
}

func (s *loggingService) DoSomething() string {
    fmt.Println("Before DoSomething")
    result := s.Service.DoSomething()
    fmt.Println("After DoSomething")
    return result
}

func main() {
    service := &RealService{}
    interceptor := &LoggingInterceptor{}

    // 使用拦截器包装服务
    wrappedService := interceptor.Intercept(service)

    // 调用方法
    fmt.Println(wrappedService.DoSomething())
}

posted @ 2024-11-12 10:46  失控D大白兔  阅读(8)  评论(0编辑  收藏  举报