Skip to content

接口组合

1. 概述

接口组合是 Go 语言中一种强大的特性,它允许通过嵌套其他接口来创建新的接口。这种方式可以实现接口的复用和扩展,使代码更加模块化和可维护。本知识点承接接口定义与实现的概念,为后续的空接口和类型嵌入等内容奠定基础。

2. 基本概念

2.1 语法

接口组合语法

go
// 接口组合
type 新接口名 interface {
    接口1
    接口2
    // ...
    额外方法
}

// 示例:组合 Reader 和 Writer 接口
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

// 组合成 ReadWriter 接口
type ReadWriter interface {
    Reader
    Writer
}

2.2 语义

  • 接口组合:通过嵌套多个接口来创建新的接口,新接口包含所有被嵌套接口的方法
  • 接口复用:避免重复定义相同的方法集,提高代码的可维护性
  • 接口扩展:在组合现有接口的基础上添加新的方法,实现接口的扩展
  • 隐式实现:如果一个类型实现了所有被组合接口的方法,那么它也隐式实现了组合后的接口

2.3 规范

  • 命名规范:组合接口的名称应该清晰表达其组合的接口功能
  • 接口设计:组合接口应该保持简洁,避免过度组合导致接口过大
  • 单一职责:每个接口应该专注于单一职责,通过组合实现复杂功能

3. 原理深度解析

3.1 接口组合的底层实现

接口组合在编译时会被展开,组合接口包含所有被嵌套接口的方法。从底层实现来看,组合接口与普通接口没有本质区别,都是方法签名的集合。

3.2 接口组合与类型实现

当一个类型实现了组合接口中所有被嵌套接口的方法时,它就自动实现了组合接口。Go 语言的编译器会检查类型是否实现了组合接口中的所有方法。

3.3 接口组合的继承关系

接口组合不是继承,而是组合关系。组合接口只是包含了其他接口的方法,而不是继承它们的行为。这种组合关系更加灵活,避免了继承带来的问题。

4. 常见错误与踩坑点

4.1 错误表现:接口方法冲突

产生原因:组合的多个接口中存在同名方法,导致方法冲突 解决方案:避免组合具有同名方法的接口,或重新设计接口结构

4.2 错误表现:过度组合导致接口过大

产生原因:组合了过多的接口,导致新接口包含过多方法,违反单一职责原则 解决方案:合理设计接口,保持接口的单一职责,避免过度组合

4.3 错误表现:接口实现不完整

产生原因:类型只实现了组合接口中的部分方法,导致编译错误 解决方案:确保类型实现了组合接口中的所有方法

5. 常见应用场景

5.1 场景描述:标准库中的接口组合

使用方法:Go 标准库中广泛使用接口组合,如 io.ReadWriter、io.ReadCloser 等 示例代码

go
// 标准库中的接口组合
package io

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

type Closer interface {
    Close() error
}

// 组合接口
type ReadWriter interface {
    Reader
    Writer
}

type ReadCloser interface {
    Reader
    Closer
}

type WriteCloser interface {
    Writer
    Closer
}

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}

5.2 场景描述:业务接口组合

使用方法:在业务逻辑中组合多个接口,创建更复杂的接口 示例代码

go
// 定义基础接口
type Repository interface {
    Save(data interface{}) error
    Find(id string) (interface{}, error)
}

type Logger interface {
    Log(message string)
}

type Validator interface {
    Validate(data interface{}) error
}

// 组合接口
type Service interface {
    Repository
    Logger
    Validator
    Process(data interface{}) error
}

// 实现组合接口
type UserService struct {
    repo      Repository
    logger    Logger
    validator Validator
}

func (s *UserService) Save(data interface{}) error {
    return s.repo.Save(data)
}

func (s *UserService) Find(id string) (interface{}, error) {
    return s.repo.Find(id)
}

func (s *UserService) Log(message string) {
    s.logger.Log(message)
}

func (s *UserService) Validate(data interface{}) error {
    return s.validator.Validate(data)
}

func (s *UserService) Process(data interface{}) error {
    // 处理逻辑
    return nil
}

5.3 场景描述:插件系统接口

使用方法:通过接口组合定义插件的能力 示例代码

go
// 定义插件基础接口
type Plugin interface {
    Name() string
    Initialize() error
}

// 定义可配置插件接口
type Configurable interface {
    Configure(config map[string]interface{}) error
}

// 定义可执行插件接口
type Executable interface {
    Execute(data interface{}) error
}

// 定义可清理插件接口
type Cleanable interface {
    Cleanup() error
}

// 组合接口
type FullPlugin interface {
    Plugin
    Configurable
    Executable
    Cleanable
}

// 实现组合接口
type MyPlugin struct {
    name string
}

func (p *MyPlugin) Name() string {
    return p.name
}

func (p *MyPlugin) Initialize() error {
    // 初始化
    return nil
}

func (p *MyPlugin) Configure(config map[string]interface{}) error {
    // 配置
    return nil
}

func (p *MyPlugin) Execute(data interface{}) error {
    // 执行
    return nil
}

func (p *MyPlugin) Cleanup() error {
    // 清理
    return nil
}

5.4 场景描述:HTTP 处理接口

使用方法:组合多个 HTTP 相关接口,创建完整的 HTTP 处理器 示例代码

go
// 定义 HTTP 处理接口
type HTTPHandler interface {
    ServeHTTP(w http.ResponseWriter, r *http.Request)
}

// 定义中间件接口
type Middleware interface {
    Handle(next HTTPHandler) HTTPHandler
}

// 定义路由接口
type Router interface {
    Register(path string, handler HTTPHandler)
    ServeHTTP(w http.ResponseWriter, r *http.Request)
}

// 定义完整的 HTTP 服务器接口
type HTTPServer interface {
    Router
    Middleware
    Start(addr string) error
    Stop() error
}

5.5 场景描述:数据访问接口

使用方法:组合多个数据访问相关接口,创建完整的数据访问层 示例代码

go
// 定义基础数据访问接口
type DataAccess interface {
    Connect() error
    Disconnect() error
}

// 定义查询接口
type Queryable interface {
    Query(sql string, args ...interface{}) (*sql.Rows, error)
}

// 定义执行接口
type Executable interface {
    Exec(sql string, args ...interface{}) (sql.Result, error)
}

// 定义事务接口
type Transactional interface {
    Begin() (*sql.Tx, error)
}

// 组合接口
type Database interface {
    DataAccess
    Queryable
    Executable
    Transactional
}

// 实现组合接口
type MySQLDatabase struct {
    db *sql.DB
}

func (m *MySQLDatabase) Connect() error {
    // 连接数据库
    return nil
}

func (m *MySQLDatabase) Disconnect() error {
    return m.db.Close()
}

func (m *MySQLDatabase) Query(sql string, args ...interface{}) (*sql.Rows, error) {
    return m.db.Query(sql, args...)
}

func (m *MySQLDatabase) Exec(sql string, args ...interface{}) (sql.Result, error) {
    return m.db.Exec(sql, args...)
}

func (m *MySQLDatabase) Begin() (*sql.Tx, error) {
    return m.db.Begin()
}

6. 企业级进阶应用场景

6.1 场景描述:微服务接口设计

使用方法:通过接口组合定义微服务的能力,实现服务间的解耦 示例代码

go
// 定义服务基础接口
type Service interface {
    HealthCheck() error
    Version() string
}

// 定义用户服务接口
type UserService interface {
    CreateUser(user User) (string, error)
    GetUser(id string) (User, error)
    UpdateUser(id string, user User) error
    DeleteUser(id string) error
}

// 定义订单服务接口
type OrderService interface {
    CreateOrder(order Order) (string, error)
    GetOrder(id string) (Order, error)
    UpdateOrder(id string, order Order) error
    DeleteOrder(id string) error
}

// 组合接口
type ECommerceService interface {
    Service
    UserService
    OrderService
}

// 实现组合接口
type ECommerceServiceImpl struct {
    userService  UserService
    orderService OrderService
}

func (s *ECommerceServiceImpl) HealthCheck() error {
    // 健康检查
    return nil
}

func (s *ECommerceServiceImpl) Version() string {
    return "1.0.0"
}

// 实现 UserService 方法
func (s *ECommerceServiceImpl) CreateUser(user User) (string, error) {
    return s.userService.CreateUser(user)
}

func (s *ECommerceServiceImpl) GetUser(id string) (User, error) {
    return s.userService.GetUser(id)
}

func (s *ECommerceServiceImpl) UpdateUser(id string, user User) error {
    return s.userService.UpdateUser(id, user)
}

func (s *ECommerceServiceImpl) DeleteUser(id string) error {
    return s.userService.DeleteUser(id)
}

// 实现 OrderService 方法
func (s *ECommerceServiceImpl) CreateOrder(order Order) (string, error) {
    return s.orderService.CreateOrder(order)
}

func (s *ECommerceServiceImpl) GetOrder(id string) (Order, error) {
    return s.orderService.GetOrder(id)
}

func (s *ECommerceServiceImpl) UpdateOrder(id string, order Order) error {
    return s.orderService.UpdateOrder(id, order)
}

func (s *ECommerceServiceImpl) DeleteOrder(id string) error {
    return s.orderService.DeleteOrder(id)
}

6.2 场景描述:事件驱动架构接口

使用方法:通过接口组合定义事件处理的能力,实现事件驱动架构 示例代码

go
// 定义事件接口
type Event interface {
    Type() string
    Payload() interface{}
}

// 定义事件处理器接口
type EventHandler interface {
    Handle(event Event) error
}

// 定义事件发布器接口
type EventPublisher interface {
    Publish(event Event) error
}

// 定义事件订阅器接口
type EventSubscriber interface {
    Subscribe(eventType string, handler EventHandler) error
    Unsubscribe(eventType string, handler EventHandler) error
}

// 组合接口
type EventBus interface {
    EventPublisher
    EventSubscriber
    Start() error
    Stop() error
}

// 实现组合接口
type InMemoryEventBus struct {
    handlers map[string][]EventHandler
    mutex    sync.RWMutex
}

func (eb *InMemoryEventBus) Publish(event Event) error {
    eb.mutex.RLock()
    defer eb.mutex.RUnlock()
    
    if handlers, ok := eb.handlers[event.Type()]; ok {
        for _, handler := range handlers {
            if err := handler.Handle(event); err != nil {
                return err
            }
        }
    }
    
    return nil
}

func (eb *InMemoryEventBus) Subscribe(eventType string, handler EventHandler) error {
    eb.mutex.Lock()
    defer eb.mutex.Unlock()
    
    if eb.handlers == nil {
        eb.handlers = make(map[string][]EventHandler)
    }
    
    eb.handlers[eventType] = append(eb.handlers[eventType], handler)
    return nil
}

func (eb *InMemoryEventBus) Unsubscribe(eventType string, handler EventHandler) error {
    eb.mutex.Lock()
    defer eb.mutex.Unlock()
    
    if handlers, ok := eb.handlers[eventType]; ok {
        for i, h := range handlers {
            if h == handler {
                eb.handlers[eventType] = append(handlers[:i], handlers[i+1:]...)
                break
            }
        }
    }
    
    return nil
}

func (eb *InMemoryEventBus) Start() error {
    // 启动事件总线
    return nil
}

func (eb *InMemoryEventBus) Stop() error {
    // 停止事件总线
    return nil
}

7. 行业最佳实践

7.1 实践内容:接口应该小而专一

推荐理由:小接口更容易实现和测试,通过组合可以构建更复杂的接口

7.2 实践内容:合理使用接口组合

推荐理由:接口组合可以实现接口的复用和扩展,避免代码重复

7.3 实践内容:避免方法冲突

推荐理由:组合的接口之间应该避免同名方法,防止方法冲突

7.4 实践内容:接口命名应该清晰表达其功能

推荐理由:清晰的接口命名可以提高代码的可读性和可维护性

8. 常见问题答疑(FAQ)

8.1 问题描述:接口组合与继承有什么区别?

回答内容:接口组合是通过嵌套接口来创建新接口,而继承是通过扩展类来创建新类。接口组合更加灵活,避免了继承带来的问题,如钻石继承等 示例代码

go
// 接口组合
type ReadWriter interface {
    Reader
    Writer
}

// 而不是继承
// type ReadWriter extends Reader, Writer {}

8.2 问题描述:如何处理接口组合中的方法冲突?

回答内容:避免组合具有同名方法的接口,或重新设计接口结构,将冲突的方法提取到单独的接口中 示例代码

go
// 避免这种情况
type Interface1 interface {
    Method()
}

type Interface2 interface {
    Method() // 同名方法
}

// 错误:方法冲突
type BadInterface interface {
    Interface1
    Interface2
}

// 正确的设计
type MethodInterface interface {
    Method()
}

type GoodInterface interface {
    MethodInterface
    // 其他方法
}

8.3 问题描述:接口组合有什么优势?

回答内容:接口组合可以实现接口的复用和扩展,使代码更加模块化和可维护,避免了代码重复 示例代码

go
// 复用接口
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

// 扩展接口
type ReadWriter interface {
    Reader
    Writer
}

8.4 问题描述:一个类型需要实现组合接口中的所有方法吗?

回答内容:是的,一个类型需要实现组合接口中所有被嵌套接口的方法,才能说该类型实现了组合接口 示例代码

go
type ReadWriter interface {
    Reader
    Writer
}

type MyReaderWriter struct{}

// 必须实现 Reader 和 Writer 的所有方法
func (m *MyReaderWriter) Read(p []byte) (n int, err error) {
    // 实现
    return 0, nil
}

func (m *MyReaderWriter) Write(p []byte) (n int, err error) {
    // 实现
    return len(p), nil
}

8.5 问题描述:接口组合可以嵌套多层吗?

回答内容:是的,接口组合可以嵌套多层,形成复杂的接口层次结构 示例代码

go
type A interface {
    MethodA()
}

type B interface {
    A
    MethodB()
}

type C interface {
    B
    MethodC()
}

8.6 问题描述:如何设计良好的接口组合?

回答内容

  1. 每个接口应该专注于单一职责
  2. 接口应该小而简洁
  3. 避免方法冲突
  4. 合理命名接口,清晰表达其功能
  5. 通过组合实现复杂功能,而不是创建过大的接口

9. 实战练习

9.1 基础练习:实现标准库风格的接口组合

解题思路:参考标准库 io 包,实现类似的接口组合 常见误区:方法签名不一致,导致接口实现失败 分步提示

  1. 定义 Reader 接口,包含 Read 方法
  2. 定义 Writer 接口,包含 Write 方法
  3. 定义 Closer 接口,包含 Close 方法
  4. 组合这些接口,创建 ReadWriter、ReadCloser、WriteCloser 和 ReadWriteCloser 接口
  5. 实现一个文件处理器,实现所有接口 参考代码
go
package main

import (
    "fmt"
    "io"
    "os"
)

// 定义基础接口
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

type Closer interface {
    Close() error
}

// 组合接口
type ReadWriter interface {
    Reader
    Writer
}

type ReadCloser interface {
    Reader
    Closer
}

type WriteCloser interface {
    Writer
    Closer
}

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}

// 实现文件处理器
type FileHandler struct {
    file *os.File
}

func NewFileHandler(path string, mode int) (*FileHandler, error) {
    file, err := os.OpenFile(path, mode, 0644)
    if err != nil {
        return nil, err
    }
    return &FileHandler{file: file}, nil
}

func (fh *FileHandler) Read(p []byte) (n int, err error) {
    return fh.file.Read(p)
}

func (fh *FileHandler) Write(p []byte) (n int, err error) {
    return fh.file.Write(p)
}

func (fh *FileHandler) Close() error {
    return fh.file.Close()
}

func main() {
    // 创建文件处理器
    fh, err := NewFileHandler("test.txt", os.O_RDWR|os.O_CREATE)
    if err != nil {
        fmt.Println("创建文件失败:", err)
        return
    }
    defer fh.Close()
    
    // 写入数据
    data := []byte("Hello, Interface Composition!")
    n, err := fh.Write(data)
    if err != nil {
        fmt.Println("写入失败:", err)
        return
    }
    fmt.Printf("写入 %d 字节\n", n)
    
    // 读取数据
    buffer := make([]byte, 100)
    fh.file.Seek(0, io.SeekStart)
    n, err = fh.Read(buffer)
    if err != nil {
        fmt.Println("读取失败:", err)
        return
    }
    fmt.Printf("读取 %d 字节: %s\n", n, string(buffer[:n]))
}

9.2 进阶练习:实现业务服务接口组合

解题思路:创建一个业务服务,组合多个功能接口 常见误区:接口设计不合理,导致实现复杂 分步提示

  1. 定义 UserRepository 接口,包含用户数据访问方法
  2. 定义 Logger 接口,包含日志记录方法
  3. 定义 Validator 接口,包含数据验证方法
  4. 组合这些接口,创建 UserService 接口
  5. 实现 UserService 接口 参考代码
go
package main

import "fmt"

// 定义用户结构
type User struct {
    ID   string
    Name string
    Email string
}

// 定义用户仓库接口
type UserRepository interface {
    Save(user User) error
    FindByID(id string) (User, error)
    Update(user User) error
    Delete(id string) error
}

// 定义日志接口
type Logger interface {
    Info(message string)
    Error(message string)
}

// 定义验证接口
type Validator interface {
    Validate(user User) error
}

// 组合接口
type UserService interface {
    UserRepository
    Logger
    Validator
    Register(user User) error
    GetUser(id string) (User, error)
    UpdateUser(user User) error
    DeleteUser(id string) error
}

// 实现用户仓库
type InMemoryUserRepository struct {
    users map[string]User
}

func NewInMemoryUserRepository() *InMemoryUserRepository {
    return &InMemoryUserRepository{
        users: make(map[string]User),
    }
}

func (r *InMemoryUserRepository) Save(user User) error {
    r.users[user.ID] = user
    return nil
}

func (r *InMemoryUserRepository) FindByID(id string) (User, error) {
    user, ok := r.users[id]
    if !ok {
        return User{}, fmt.Errorf("用户不存在")
    }
    return user, nil
}

func (r *InMemoryUserRepository) Update(user User) error {
    if _, ok := r.users[user.ID]; !ok {
        return fmt.Errorf("用户不存在")
    }
    r.users[user.ID] = user
    return nil
}

func (r *InMemoryUserRepository) Delete(id string) error {
    if _, ok := r.users[id]; !ok {
        return fmt.Errorf("用户不存在")
    }
    delete(r.users, id)
    return nil
}

// 实现日志器
type ConsoleLogger struct{}

func (l *ConsoleLogger) Info(message string) {
    fmt.Printf("[INFO] %s\n", message)
}

func (l *ConsoleLogger) Error(message string) {
    fmt.Printf("[ERROR] %s\n", message)
}

// 实现验证器
type UserValidator struct{}

func (v *UserValidator) Validate(user User) error {
    if user.Name == "" {
        return fmt.Errorf("用户名不能为空")
    }
    if user.Email == "" {
        return fmt.Errorf("邮箱不能为空")
    }
    return nil
}

// 实现用户服务
type UserServiceImpl struct {
    repo      UserRepository
    logger    Logger
    validator Validator
}

func NewUserService(repo UserRepository, logger Logger, validator Validator) *UserServiceImpl {
    return &UserServiceImpl{
        repo:      repo,
        logger:    logger,
        validator: validator,
    }
}

func (s *UserServiceImpl) Save(user User) error {
    return s.repo.Save(user)
}

func (s *UserServiceImpl) FindByID(id string) (User, error) {
    return s.repo.FindByID(id)
}

func (s *UserServiceImpl) Update(user User) error {
    return s.repo.Update(user)
}

func (s *UserServiceImpl) Delete(id string) error {
    return s.repo.Delete(id)
}

func (s *UserServiceImpl) Info(message string) {
    s.logger.Info(message)
}

func (s *UserServiceImpl) Error(message string) {
    s.logger.Error(message)
}

func (s *UserServiceImpl) Validate(user User) error {
    return s.validator.Validate(user)
}

func (s *UserServiceImpl) Register(user User) error {
    s.Info("注册用户: " + user.Name)
    if err := s.Validate(user); err != nil {
        s.Error("验证失败: " + err.Error())
        return err
    }
    if err := s.Save(user); err != nil {
        s.Error("保存失败: " + err.Error())
        return err
    }
    s.Info("注册成功: " + user.Name)
    return nil
}

func (s *UserServiceImpl) GetUser(id string) (User, error) {
    s.Info("获取用户: " + id)
    user, err := s.FindByID(id)
    if err != nil {
        s.Error("获取失败: " + err.Error())
        return User{}, err
    }
    return user, nil
}

func (s *UserServiceImpl) UpdateUser(user User) error {
    s.Info("更新用户: " + user.ID)
    if err := s.Validate(user); err != nil {
        s.Error("验证失败: " + err.Error())
        return err
    }
    if err := s.Update(user); err != nil {
        s.Error("更新失败: " + err.Error())
        return err
    }
    s.Info("更新成功: " + user.ID)
    return nil
}

func (s *UserServiceImpl) DeleteUser(id string) error {
    s.Info("删除用户: " + id)
    if err := s.Delete(id); err != nil {
        s.Error("删除失败: " + err.Error())
        return err
    }
    s.Info("删除成功: " + id)
    return nil
}

func main() {
    // 创建依赖
    repo := NewInMemoryUserRepository()
    logger := &ConsoleLogger{}
    validator := &UserValidator{}
    
    // 创建服务
    service := NewUserService(repo, logger, validator)
    
    // 测试注册
    user := User{ID: "1", Name: "Alice", Email: "alice@example.com"}
    if err := service.Register(user); err != nil {
        fmt.Println("注册失败:", err)
        return
    }
    
    // 测试获取
    user, err := service.GetUser("1")
    if err != nil {
        fmt.Println("获取失败:", err)
        return
    }
    fmt.Printf("获取用户: %v\n", user)
    
    // 测试更新
    user.Email = "alice Updated@example.com"
    if err := service.UpdateUser(user); err != nil {
        fmt.Println("更新失败:", err)
        return
    }
    
    // 测试删除
    if err := service.DeleteUser("1"); err != nil {
        fmt.Println("删除失败:", err)
        return
    }
}

9.3 挑战练习:实现事件总线接口组合

解题思路:创建一个事件总线,组合多个事件相关接口 常见误区:并发安全问题,事件处理顺序问题 分步提示

  1. 定义 Event 接口,包含事件类型和负载
  2. 定义 EventHandler 接口,包含事件处理方法
  3. 定义 EventPublisher 接口,包含事件发布方法
  4. 定义 EventSubscriber 接口,包含事件订阅和取消订阅方法
  5. 组合这些接口,创建 EventBus 接口
  6. 实现 EventBus 接口,确保并发安全 参考代码
go
package main

import (
    "fmt"
    "sync"
)

// 定义事件接口
type Event interface {
    Type() string
    Payload() interface{}
}

// 实现事件
type SimpleEvent struct {
    eventType string
    payload   interface{}
}

func NewEvent(eventType string, payload interface{}) *SimpleEvent {
    return &SimpleEvent{
        eventType: eventType,
        payload:   payload,
    }
}

func (e *SimpleEvent) Type() string {
    return e.eventType
}

func (e *SimpleEvent) Payload() interface{} {
    return e.payload
}

// 定义事件处理器接口
type EventHandler interface {
    Handle(event Event) error
}

// 实现事件处理器
type LoggingEventHandler struct{}

func (h *LoggingEventHandler) Handle(event Event) error {
    fmt.Printf("处理事件: %s, 负载: %v\n", event.Type(), event.Payload())
    return nil
}

// 定义事件发布器接口
type EventPublisher interface {
    Publish(event Event) error
}

// 定义事件订阅器接口
type EventSubscriber interface {
    Subscribe(eventType string, handler EventHandler) error
    Unsubscribe(eventType string, handler EventHandler) error
}

// 组合接口
type EventBus interface {
    EventPublisher
    EventSubscriber
    Start() error
    Stop() error
}

// 实现事件总线
type InMemoryEventBus struct {
    handlers map[string][]EventHandler
    mutex    sync.RWMutex
    running  bool
}

func NewInMemoryEventBus() *InMemoryEventBus {
    return &InMemoryEventBus{
        handlers: make(map[string][]EventHandler),
        running:  false,
    }
}

func (eb *InMemoryEventBus) Publish(event Event) error {
    if !eb.running {
        return fmt.Errorf("事件总线未启动")
    }
    
    eb.mutex.RLock()
    defer eb.mutex.RUnlock()
    
    if handlers, ok := eb.handlers[event.Type()]; ok {
        for _, handler := range handlers {
            if err := handler.Handle(event); err != nil {
                return err
            }
        }
    }
    
    return nil
}

func (eb *InMemoryEventBus) Subscribe(eventType string, handler EventHandler) error {
    eb.mutex.Lock()
    defer eb.mutex.Unlock()
    
    if eb.handlers == nil {
        eb.handlers = make(map[string][]EventHandler)
    }
    
    eb.handlers[eventType] = append(eb.handlers[eventType], handler)
    return nil
}

func (eb *InMemoryEventBus) Unsubscribe(eventType string, handler EventHandler) error {
    eb.mutex.Lock()
    defer eb.mutex.Unlock()
    
    if handlers, ok := eb.handlers[eventType]; ok {
        for i, h := range handlers {
            if h == handler {
                eb.handlers[eventType] = append(handlers[:i], handlers[i+1:]...)
                break
            }
        }
    }
    
    return nil
}

func (eb *InMemoryEventBus) Start() error {
    eb.mutex.Lock()
    defer eb.mutex.Unlock()
    
    if eb.running {
        return fmt.Errorf("事件总线已启动")
    }
    
    eb.running = true
    fmt.Println("事件总线启动")
    return nil
}

func (eb *InMemoryEventBus) Stop() error {
    eb.mutex.Lock()
    defer eb.mutex.Unlock()
    
    if !eb.running {
        return fmt.Errorf("事件总线未启动")
    }
    
    eb.running = false
    fmt.Println("事件总线停止")
    return nil
}

func main() {
    // 创建事件总线
    bus := NewInMemoryEventBus()
    
    // 启动事件总线
    if err := bus.Start(); err != nil {
        fmt.Println("启动失败:", err)
        return
    }
    defer bus.Stop()
    
    // 创建事件处理器
    handler := &LoggingEventHandler{}
    
    // 订阅事件
    if err := bus.Subscribe("user.created", handler); err != nil {
        fmt.Println("订阅失败:", err)
        return
    }
    
    // 发布事件
    event := NewEvent("user.created", map[string]string{"id": "1", "name": "Alice"})
    if err := bus.Publish(event); err != nil {
        fmt.Println("发布失败:", err)
        return
    }
    
    // 取消订阅
    if err := bus.Unsubscribe("user.created", handler); err != nil {
        fmt.Println("取消订阅失败:", err)
        return
    }
    
    // 再次发布事件(不会被处理)
    event2 := NewEvent("user.created", map[string]string{"id": "2", "name": "Bob"})
    if err := bus.Publish(event2); err != nil {
        fmt.Println("发布失败:", err)
        return
    }
}

10. 知识点总结

10.1 核心要点

  • 接口组合是通过嵌套其他接口来创建新接口的特性
  • 组合接口包含所有被嵌套接口的方法
  • 如果一个类型实现了所有被组合接口的方法,那么它也隐式实现了组合接口
  • 接口组合不是继承,而是组合关系,更加灵活
  • 接口组合可以实现接口的复用和扩展,使代码更加模块化和可维护

10.2 易错点回顾

  • 接口组合中的方法冲突:避免组合具有同名方法的接口
  • 过度组合导致接口过大:保持接口的单一职责,避免过度组合
  • 接口实现不完整:确保类型实现了组合接口中的所有方法
  • 接口命名不清晰:使用清晰的命名表达接口的功能

11. 拓展参考资料

11.1 官方文档链接

11.2 进阶学习路径建议

  • 学习空接口的使用
  • 深入理解类型断言和类型判断
  • 学习类型嵌入和组合
  • 探索反射在接口中的应用

本知识点承接《接口定义与实现》,后续延伸至《空接口》,建议学习顺序:接口定义与实现 → 接口组合 → 空接口 → 类型嵌入