go: Monitor Pattern

项目结构:

image

 

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:09
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config

const (
	BufferCapacity   = 3   // 珠宝缓冲区容量
	ProducerCount    = 2   // 工匠(生产者)数量
	ConsumerCount    = 1   // 质检员(消费者)数量
	ProducePerWorker = 5   // 每个工匠生产数量
	ProduceDelayMs   = 300 // 生产模拟耗时
	ConsumeDelayMs   = 500 // 质检模拟耗时
)

 

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:09
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry.go
*/
package domain

// Jewelry 珠宝实体(行业核心对象)
type Jewelry struct {
	ID       int
	Type     string // 钻戒/项链/手镯
	Material string // 材质
}

// 生产类型常量
const (
	JewelryTypeRing     = "钻戒"
	JewelryTypeNecklace = "黄金项链"
	MaterialRing        = "钻石+铂金"
	MaterialNecklace    = "足金999"
)

  

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:10
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : monitor.go
*/
package service

import (
	"godesginpattern/monitor/domain"
)

// JewelryMonitor 监控器接口(监控模式标准接口)
// 职责单一:只定义生产/消费行为,不关心实现
type JewelryMonitor interface {
	// Produce 生产珠宝(生产者)
	Produce(jewelryType, material string) error
	// Consume 消费珠宝(消费者)
	Consume() (*domain.Jewelry, error)
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:11
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_monitor.go
*/
package impl

import (
	"errors"
	"godesginpattern/monitor/domain"
	"godesginpattern/monitor/service"
	"sync"
)

// jewelryMonitor 监控器实现(私有结构体,外部只能通过接口访问)
type jewelryMonitor struct {
	mutex    sync.Mutex
	cond     *sync.Cond
	buffer   []*domain.Jewelry
	capacity int
	seq      int
}

// NewJewelryMonitor 创建监控器实例(依赖注入)
func NewJewelryMonitor(capacity int) service.JewelryMonitor {
	jm := &jewelryMonitor{
		capacity: capacity,
	}
	// 条件变量绑定互斥锁(监控模式核心)
	jm.cond = sync.NewCond(&jm.mutex)
	return jm
}

// ==================== 生产者实现 ====================
func (jm *jewelryMonitor) Produce(jewelryType, material string) error {
	jm.mutex.Lock()
	defer jm.mutex.Unlock()

	// 必须用 for 循环:防止虚假唤醒(企业级规范)
	for len(jm.buffer) == jm.capacity {
		jm.cond.Wait()
	}

	// 生产
	jm.seq++
	j := &domain.Jewelry{
		ID:       jm.seq,
		Type:     jewelryType,
		Material: material,
	}
	jm.buffer = append(jm.buffer, j)

	// 通知消费者
	jm.cond.Signal()
	return nil
}

// ==================== 消费者实现 ====================
func (jm *jewelryMonitor) Consume() (*domain.Jewelry, error) {
	jm.mutex.Lock()
	defer jm.mutex.Unlock()

	for len(jm.buffer) == 0 {
		jm.cond.Wait()
	}

	// 消费
	if len(jm.buffer) == 0 {
		return nil, errors.New("buffer empty")
	}

	j := jm.buffer[0]
	jm.buffer = jm.buffer[1:]

	// 通知生产者
	jm.cond.Signal()
	return j, nil
}

  

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:12
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : producer.go
*/
package worker

import (
	"godesginpattern/monitor/config"
	"godesginpattern/monitor/domain"
	"godesginpattern/monitor/service"
	"log"
	"time"
)

// StartProducer 启动生产者协程
func StartProducer(
	monitor service.JewelryMonitor,
	workerID int,
	produceCount int,
) {
	for i := 0; i < produceCount; i++ {
		// 按工匠ID分配生产类型
		jType, material := domain.JewelryTypeRing, domain.MaterialRing
		if workerID == 2 {
			jType, material = domain.JewelryTypeNecklace, domain.MaterialNecklace
		}

		_ = monitor.Produce(jType, material)
		log.Printf("[工匠%d] 生产完成: %s | %s", workerID, jType, material)

		time.Sleep(time.Millisecond * time.Duration(config.ProduceDelayMs))
	}

	log.Printf("[工匠%d] ✅ 全部生产任务完成", workerID)
}


/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:12
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : consumer.go
*/
package worker

import (
	"godesginpattern/monitor/config"
	"godesginpattern/monitor/service"
	"log"
	"time"
)

// StartConsumer 启动消费者协程
func StartConsumer(
	monitor service.JewelryMonitor,
	totalConsume int,
) {
	for i := 0; i < totalConsume; i++ {
		j, _ := monitor.Consume()
		log.Printf("[质检员] 质检完成: ID=%d | %s | %s", j.ID, j.Type, j.Material)

		time.Sleep(time.Millisecond * time.Duration(config.ConsumeDelayMs))
	}

	log.Println("[质检员] ✅ 全部质检任务完成")
}

  

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/5/17 20:13
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : monitorbll.go

monitor/
├── config/              # 配置定义
├── domain/              # 领域模型(核心业务实体)
├── service/             # 业务服务(监控模式核心实现)
│   ├── monitor.go       # 监控器接口定义
│   └── impl/
│       └── jewelry_monitor.go  # 互斥锁+条件变量 实现
├── worker/              # 生产者/消费者工作协程
│   ├── producer.go       # 监控器接口定义
│   └── consumer.go
├── cmd/                 # 项目启动入口
│   └── main.go
├── go.mod
└── go.sum
*/
package bll

import (
	"godesginpattern/monitor/config"
	"godesginpattern/monitor/service/impl"
	"godesginpattern/monitor/worker"
	"log"
	"sync"
)

func MonitorMain() {
	log.Println("=== 珠宝生产-质检系统 启动 ===")

	// 1. 创建监控器(依赖注入)
	monitor := impl.NewJewelryMonitor(config.BufferCapacity)

	// 2. 等待组
	var wg sync.WaitGroup

	// 3. 启动生产者
	totalProduce := 0
	wg.Add(config.ProducerCount)
	for i := 1; i <= config.ProducerCount; i++ {
		go func(id int) {
			defer wg.Done()
			worker.StartProducer(monitor, id, config.ProducePerWorker)
		}(i)
		totalProduce += config.ProducePerWorker
	}

	// 4. 启动消费者
	wg.Add(1)
	go func() {
		defer wg.Done()
		worker.StartConsumer(monitor, totalProduce)
	}()

	// 5. 等待全部完成
	wg.Wait()

	log.Println("=== 🎉 珠宝生产-质检全流程完成 ===")
}

  

输出:

image

 

 

 

posted @ 2026-05-17 20:20  ®Geovin Du Dream Park™  阅读(12)  评论(0)    收藏  举报