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

输出:

相关推荐
mumu_wangwei5 小时前
【QFS】Golang自研的QFS分布式文件系统,QFS文件系统使用
开发语言·后端·golang
老码观察7 小时前
设计模式实战解读(一):单例模式——全局唯一实例的正确打开方式
单例模式·设计模式
老码观察7 小时前
设计模式实战解读(二):工厂模式——对象创建的解耦艺术
设计模式·log4j
codeejun8 小时前
每日一Go-66、K8s 蓝绿发布 & 金丝雀发布实战:Service 切流量 + Ingress 灰度一次讲透
开发语言·golang·kubernetes
看山是山_Lau9 小时前
原型模式:当复制比重新创建更高效时
设计模式·原型模式
用户356302904879 小时前
【设计模式】观察者模式——事件通知机制
设计模式
青春喂了后端9 小时前
Go Sidecar Repository 并发锁改造:让并发请求安全地进入 Git 仓库层
git·安全·golang
追烽少年x9 小时前
STL中的设计模式(二)
c++·设计模式
2501_9318037510 小时前
Go 接口学习笔记:从语法到心法
笔记·学习·golang
pixcarp10 小时前
Redis ZSet:底层设计与实践
数据库·redis·后端·学习·golang·web