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))
 
}

输出:

相关推荐
青春喂了后端22 分钟前
Go Sidecar Status 性能优化
开发语言·性能优化·golang
我登哥MVP28 分钟前
走进 Gang of Four 设计模式:装饰器模式
java·spring boot·设计模式·装饰器模式
A__tao1 小时前
告别手写 Go 结构体!推荐一个支持注释解析的 YAML 转 Struct 在线工具
开发语言·后端·golang
何以解忧,唯有..1 小时前
Go 语言语句分隔符详解:分号、换行与代码规范
开发语言·golang·代码规范
秋漓2 小时前
软件设计模式
设计模式
许彰午2 小时前
36_Java设计模式之代理模式
java·设计模式·代理模式
许彰午2 小时前
35_Java设计模式之工厂模式
java·开发语言·设计模式
uoKent2 小时前
项目整理——设计模式
设计模式·软件需求
踏着七彩祥云的小丑3 小时前
Go学习第8天:接口 + 泛型 + 错误处理
开发语言·学习·golang·go
折哥的程序人生 · 物流技术专研3 小时前
Java 23 种设计模式:从踩坑到精通 | 番外:编排器+策略模式在多平台电子面单中的实战(含性能压测)
设计模式·策略模式·代码重构·java设计模式·编排器·电子面单·从踩坑到精通