go: Mediator Pattern

项目结构:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式  go get -u go.uber.org/zap
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:02
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config
 
const (
    AppName   = "jewelry-trading-system"
    LogLevel  = "info"
    MonitorOn = true
)
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:06
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : errors.go
*/
package errs
 
import "errors"
 
var (
    InvalidArgument = errors.New("invalid argument")
    NotFound        = errors.New("not found")
    InternalError   = errors.New("internal error")
)
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:05
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : logger.go
*/
package logger
 
import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "godesginpattern/mediator/config"
    "os"
)
 
var log *zap.Logger
 
func Init() {
    encoderCfg := zapcore.EncoderConfig{
        TimeKey:       "time",
        LevelKey:      "level",
        NameKey:       "logger",
        CallerKey:     "caller",
        MessageKey:    "msg",
        StacktraceKey: "stack",
        EncodeTime:    zapcore.ISO8601TimeEncoder,
        EncodeLevel:   zapcore.LowercaseLevelEncoder,
        EncodeCaller:  zapcore.ShortCallerEncoder,
    }
 
    core := zapcore.NewCore(
        zapcore.NewConsoleEncoder(encoderCfg),
        zapcore.AddSync(os.Stdout),
        zap.InfoLevel,
    )
 
    log = zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))
    defer log.Sync()
 
    Info(config.AppName + " logger initialized")
}
 
func Info(msg string, fields ...zap.Field)  { log.Info(msg, fields...) }
func Error(msg string, fields ...zap.Field) { log.Error(msg, fields...) }
func Debug(msg string, fields ...zap.Field) { log.Debug(msg, fields...) }
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:04
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : errors.go
*/
package mediator
 
import "godesginpattern/mediator/common/errs"
 
var (
    ErrTraderNotFound = errs.NotFound
    ErrEmptyMessage   = errs.InvalidArgument
)
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:03
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : interface.go
*/
package mediator
 
// Trader 所有交易角色必须实现
type Trader interface {
    Name() string
    Receive(message string) error
}
 
// Mediator 中介者抽象
type Mediator interface {
    Register(t Trader)
    Send(from, to, msg string) error
}
 
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:03
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : mediator.go
*/
package mediator
 
import (
    "go.uber.org/zap"
    "godesginpattern/mediator/common/logger"
    "sync"
)
 
type jewelryMediator struct {
    traders map[string]Trader
    mu      sync.RWMutex
}
 
func NewJewelryMediator() Mediator {
    return &jewelryMediator{
        traders: make(map[string]Trader),
    }
}
 
func (m *jewelryMediator) Register(t Trader) {
    m.mu.Lock()
    defer m.mu.Unlock()
    m.traders[t.Name()] = t
    logger.Info("trader registered", zap.String("name", t.Name()))
}
 
func (m *jewelryMediator) Send(from, to, msg string) error {
    IncMessage()
 
    if msg == "" {
        IncError()
        logger.Error("empty message not allowed")
        return ErrEmptyMessage
    }
 
    m.mu.RLock()
    target, ok := m.traders[to]
    m.mu.RUnlock()
 
    if !ok {
        IncError()
        logger.Error("trader not found", zap.String("to", to))
        return ErrTraderNotFound
    }
 
    forwardMsg := "[转发] " + from + " → " + msg
    if err := target.Receive(forwardMsg); err != nil {
        IncError()
        logger.Error("receive failed", zap.String("trader", to), zap.Error(err))
        return err
    }
 
    logger.Info("message sent", zap.String("from", from), zap.String("to", to))
    return nil
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:04
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : monitor.go
*/
package mediator
 
import (
    "godesginpattern/mediator/config"
    "sync/atomic"
)
 
var (
    totalMsg atomic.Int64
    errorMsg atomic.Int64
)
 
func IncMessage() {
    if config.MonitorOn {
        totalMsg.Add(1)
    }
}
 
func IncError() {
    if config.MonitorOn {
        errorMsg.Add(1)
    }
}
 
func GetMetrics() (total int64, err int64) {
    return totalMsg.Load(), errorMsg.Load()
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:04
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : appraiser.go
*/
package trader
 
import (
    "go.uber.org/zap"
    "godesginpattern/mediator/common/logger"
    "godesginpattern/mediator/mediator"
)
 
type Appraiser struct{ BaseTrader }
 
func NewAppraiser(name string, m mediator.Mediator) mediator.Trader {
    a := &Appraiser{BaseTrader: NewBaseTrader(name, m)}
    m.Register(a)
    return a
}
func (a *Appraiser) Receive(msg string) error {
    logger.Info("appraiser received", zap.String("name", a.Name()), zap.String("msg", msg))
    return nil
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:05
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : auction.go
*/
package trader
 
import (
    "go.uber.org/zap"
    "godesginpattern/mediator/common/logger"
    "godesginpattern/mediator/mediator"
)
 
type AuctionHouse struct{ BaseTrader }
 
func NewAuctionHouse(name string, m mediator.Mediator) mediator.Trader {
    ah := &AuctionHouse{BaseTrader: NewBaseTrader(name, m)}
    m.Register(ah)
    return ah
}
func (ah *AuctionHouse) Receive(msg string) error {
    logger.Info("auction received", zap.String("name", ah.Name()), zap.String("msg", msg))
    return nil
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:04
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : base.go
*/
package trader
 
import "godesginpattern/mediator/mediator"
 
type BaseTrader struct {
    name string
    m    mediator.Mediator
}
 
func NewBaseTrader(name string, m mediator.Mediator) BaseTrader {
    return BaseTrader{name: name, m: m}
}
 
func (b *BaseTrader) Name() string {
    return b.name
}
 
func (b *BaseTrader) Send(to, msg string) error {
    return b.m.Send(b.name, to, msg)
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:04
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : buyer.go
*/
package trader
 
import (
    "go.uber.org/zap"
    "godesginpattern/mediator/common/logger"
    "godesginpattern/mediator/mediator"
)
 
type Buyer struct{ BaseTrader }
 
func NewBuyer(name string, m mediator.Mediator) mediator.Trader {
    b := &Buyer{BaseTrader: NewBaseTrader(name, m)}
    m.Register(b)
    return b
}
 
func (b *Buyer) Receive(msg string) error {
    logger.Info("buyer received", zap.String("name", b.Name()), zap.String("msg", msg))
    return nil
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:04
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : seller.go
*/
package trader
 
import (
    "go.uber.org/zap"
    "godesginpattern/mediator/common/logger"
    "godesginpattern/mediator/mediator"
)
 
type Seller struct{ BaseTrader }
 
func NewSeller(name string, m mediator.Mediator) mediator.Trader {
    s := &Seller{BaseTrader: NewBaseTrader(name, m)}
    m.Register(s)
    return s
}
func (s *Seller) Receive(msg string) error {
    logger.Info("seller received", zap.String("name", s.Name()), zap.String("msg", msg))
    return nil
}

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Mediator Pattern 中介者模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/22 22:33
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : mediatorbll.go
 
mediator
├── go.mod
├── go.sum
├── config/              # 配置
│   └── config.go
├── internal/               # 内部包(外部不可访问)
│   ├── mediator/           # 中介者核心层(协调层)
│   │   ├── interface.go    # 中介者 + 同事接口
│   │   ├── mediator.go     # 中介者实现
│   │   └── errors.go       # 错误定义
│   │   └── monitor.go   # 监控
│   ├── trader/             # 交易角色层(买家/卖家/鉴定师/拍卖行)
│   │   ├── base.go         # 公共角色基类
│   │   ├── buyer.go
│   │   ├── seller.go
│   │   ├── appraiser.go
│   │   └── auction.go
│   └── common/             # 公共包
│       ├── logger/logger.go      # 日志
│       └── errs/errors.go       # 统一错误
├── main.go
└── main_test.go         # 单元测试 + Mock
*/
package bll
 
import (
    "go.uber.org/zap"
    "godesginpattern/mediator/common/logger"
    "godesginpattern/mediator/mediator"
    "godesginpattern/mediator/trader"
)
 
func MediatorMain() {
    logger.Init()
    m := mediator.NewJewelryMediator()
 
    // 自动注册
    buyer := trader.NewBuyer("张三", m)
    seller := trader.NewSeller("李四", m)
    appraiser := trader.NewAppraiser("王鉴定师", m)
    auction := trader.NewAuctionHouse("高端珠宝行", m)
 
    // 交易流程
    _ = seller.(*trader.Seller).Send("王鉴定师", "请求鉴定翡翠手镯")
    _ = appraiser.(*trader.Appraiser).Send("李四", "A货,估值50万")
    _ = appraiser.(*trader.Appraiser).Send("高端珠宝行", "可上拍")
    _ = auction.(*trader.AuctionHouse).Send("张三", "下周三拍卖,起拍价30万")
    _ = buyer.(*trader.Buyer).Send("李四", "我出价40万收购")
 
    // 监控输出
    total, err := mediator.GetMetrics()
    logger.Info("monitor metrics", zap.Int64("total_msg", total), zap.Int64("error", err))
 
}

输出:

相关推荐
kyriewen7 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
Pkmer16 小时前
古法编程: 适配器模式
java·设计模式
研究点啥好呢18 小时前
滴滴Go后端开发工程师面试题精选:10道高频考题+答案解析
java·开发语言·golang
NEGl DRYN19 小时前
Go基础之环境搭建
开发语言·后端·golang
初心未改HD19 小时前
Go Modules:依赖管理的完全指南
开发语言·golang
rOuN STAT19 小时前
Golang 构建学习
开发语言·学习·golang
不甘先生20 小时前
Go context 实战指南:从入门到生产级并发控制(架构师避坑手册)
开发语言·后端·golang
初心未改HD20 小时前
Go 泛型完全指南:从入门到实战
开发语言·golang
止语Lab1 天前
从手动到框架:Go DI 演进的三个拐点
开发语言·后端·golang