惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
O
OpenAI News
N
News and Events Feed by Topic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
Google Online Security Blog
Google Online Security Blog
云风的 BLOG
云风的 BLOG
N
News | PayPal Newsroom
H
Hacker News: Front Page
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Last Watchdog
The Last Watchdog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Heimdal Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Schneier on Security
宝玉的分享
宝玉的分享
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
Microsoft Security Blog
Microsoft Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
GbyAI
GbyAI
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
人人都是产品经理
人人都是产品经理
P
Palo Alto Networks Blog
M
MIT News - Artificial intelligence
G
GRAHAM CLULEY
C
Check Point Blog
Apple Machine Learning Research
Apple Machine Learning Research
Last Week in AI
Last Week in AI
T
Troy Hunt's Blog
L
Lohrmann on Cybersecurity
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
量子位
博客园 - 聂微东
S
Securelist
博客园 - 三生石上(FineUI控件)
F
Full Disclosure
G
Google Developers Blog
L
LINUX DO - 热门话题
P
Proofpoint News Feed
AI
AI
PCI Perspectives
PCI Perspectives

博客园 - ®Geovin Du Dream Park™

go: Functional Options Pattern go:Timing Functions Pattern python: Timing Functions Pattern go: Steady-State Pattern python: Steady-State Pattern go: Handshaking Pattern python: Handshaking Pattern go: Fail-Fast Pattern python: Fail-Fast Pattern I go: Deadline Pattern python: Deadline Pattern go: Circuit-Breaker Pattern python: Circuit-Breaker Pattern go: Bulkheads Pattern python: Bulkheads Pattern go: Push & Pull Pattern python: Push & Pull Pattern python: Publish/Subscribe Pattern II go: Publish/Subscribe Pattern python: Publish/Subscribe Pattern go: Futures & Promises Pattern python: Futures & Promises Pattern go: Worker Pool Pattern go:Pipeline Pattern python: Worker Pool Pattern python: Pipeline Pattern go: Fan-Out Pattern python: Fan-Out Pattern go: Fan-In Pattern python: Fan-In Pattern Fan-In go: Producer Consumer  Pattern python: Producer Consumer Pattern go: Parallelism Pattern python: Parallelism Pattern go: Reactor Pattern python: Reactor Pattern go: Generators Pattern python: speech to text offline python: Generators Pattern go: Coroutines Pattern python:Coroutines Pattern go: Broadcast Pattern python: Broadcast Pattern python: Bounded Parallelism Pattern go: Bounded Parallelism Pattern python: N-Barrier Pattern go: N-Barrier Pattern python: Semaphore Pattern go: Semaphore Pattern python: Read-Write Lock Pattern go: Read-Write Lock Pattern python: Monitor Pattern go: Monitor Pattern python: Mutex Pattern go: Lock/Mutex Pattern Python: Condition Variable Pattern go:Condition Variable Pattern python: Registry Pattern python: Interpreter Pattern go: Interpreter Pattern go: Registry Pattern go: Memento Pattern go: Command Pattern go: State Pattern go:Template Method Pattern go: Strategy Pattern go: Visitor Pattern go: Observer Pattern go: Mediator Pattern go: Iterator Pattern go: Chain of Responsibility Pattern go: Proxy Pattern go:Decorator Pattern go: Facade Pattern go: Flyweight Pattern go: Singleton Pattern go: Prototype Pattern go: Bridge Pattern go: Adapter Pattern go: Builder Pattern 密码进行加盐哈希 using CSharp,Python,Go,Java go: Abstract Factory Pattern go: Model,Interface,DAL ,Factory,BLL using mysql go: Simple Factory Pattern go: Factory Method Pattern go: goLang 在Windows环境搭建Go语言开发环境 CSharp: Parallel Extensions cpp: class python: 蝴蝶跟随鼠标 javascript: 中国历史人物热力分布图using echart javascript: 中国历史人物热力图 python: 初养龙虾微信纯文字自动回复using workBuddy python: object 入门 python: Factory Method Pattern python: Simple Factory Pattern python: Abstract Factory Pattern 区域化 代码 python: Null Object Pattern python: Builder Pattern python: Adapter Pattern
go: Composite Pattern
®Geovin Du D · 2026-04-19 · via 博客园 - ®Geovin Du Dream Park™

项目结构:

image

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

// Jewelry 珠宝接口:定义所有珠宝(单品/组合件)的统一行为
// 职责:抽象公共行为,实现组合模式的统一接口,隔离业务层与实现层
type Jewelry interface {
	GetName() string               // 获取珠宝名称
	GetMaterial() string           // 获取珠宝材质
	GetCertNumber() string         // 获取证书编号(组合件无)
	GetStockCount() int            // 获取库存数量
	Add(child Jewelry)             // 新增子组件(单品空实现,组合件实现)
	IsStockLow(threshold int) bool // 库存预警判断(是否低于阈值)
}

// InventoryService 库存业务接口:定义库存业务的统一服务
type InventoryService interface {
	CheckByName(j Jewelry) map[string]int     // 按名称盘点库存
	CheckByMaterial(j Jewelry) map[string]int // 按材质盘点库存
	CheckByCert(j Jewelry) map[string]bool    // 按证书编号盘点(去重)
	DeductStock(j Jewelry, count int) error   // 库存扣减(含业务校验)
	GenerateInventoryReport(j Jewelry) string // 生成企业级盘点报告
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Composite 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/19 19:15
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : base_jewelry.go
*/
package impl

// BaseJewelry 珠宝基础结构体:封装所有珠宝的公共属性(遵循单一职责)
// 嵌入到单品结构体中,实现代码复用,避免重复定义
type BaseJewelry struct {
	name       string  // 珠宝名称
	material   string  // 材质(黄金、铂金、钻石等)
	weight     float64 // 重量(单位:g/克拉)
	price      float64 // 单价(单位:元)
	certNumber string  // 证书编号(单品唯一,组合件无)
	stockCount int     // 库存数量(核心字段,私有属性,通过接口方法访问)
}


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

import "godesginpattern/composite/api"

// Diamond 钻石单品:实现api.Jewelry接口
// 职责:处理钻石自身的属性和行为,仅实现接口方法,不包含业务逻辑
type Diamond struct {
	BaseJewelry
}

// NewDiamond 工厂方法:创建钻石实例(封装实例化逻辑,便于扩展参数)
// 修复:参数顺序与调用一致,确保实例创建成功,不返回nil
func NewDiamond(material string, weight float64, price float64, certNumber string, stock int) api.Jewelry {
	// 新增:参数校验,避免非法参数导致实例异常
	if material == "" || certNumber == "" || stock < 0 {
		return nil
	}
	return &Diamond{
		BaseJewelry: BaseJewelry{
			name:       "单颗钻石",
			material:   material,
			weight:     weight,
			price:      price,
			certNumber: certNumber,
			stockCount: stock,
		},
	}
}

// 实现api.Jewelry接口所有方法
func (d *Diamond) GetName() string               { return d.name }
func (d *Diamond) GetMaterial() string           { return d.material }
func (d *Diamond) GetCertNumber() string         { return d.certNumber }
func (d *Diamond) GetStockCount() int            { return d.stockCount }
func (d *Diamond) Add(child api.Jewelry)         {} // 单品无子女,空实现
func (d *Diamond) IsStockLow(threshold int) bool { return threshold > 0 && d.stockCount < threshold }


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

import "godesginpattern/composite/api"

// Ring 戒指单品:实现api.Jewelry接口
// 职责:处理戒指自身的属性和行为,仅实现接口方法,不包含业务逻辑
type Ring struct {
	BaseJewelry
}

// NewRing 工厂方法:创建戒指实例
// 说明:第一个参数为材质(如铂金、玫瑰金),名称自动拼接为「材质+戒指」,避免调用者传参错误
func NewRing(material string, weight float64, price float64, certNumber string, stock int) api.Jewelry {
	// 新增:参数校验,避免非法参数导致实例异常(返回nil)
	if material == "" || certNumber == "" || stock < 0 {
		return nil
	}
	return &Ring{
		BaseJewelry: BaseJewelry{
			name:       material + "戒指", // 自动拼接名称,避免调用时传错参数
			material:   material,
			weight:     weight,
			price:      price,
			certNumber: certNumber,
			stockCount: stock,
		},
	}
}

// 实现api.Jewelry接口所有方法
func (r *Ring) GetName() string               { return r.name }
func (r *Ring) GetMaterial() string           { return r.material }
func (r *Ring) GetCertNumber() string         { return r.certNumber }
func (r *Ring) GetStockCount() int            { return r.stockCount }
func (r *Ring) Add(child api.Jewelry)         {}
func (r *Ring) IsStockLow(threshold int) bool { return threshold > 0 && r.stockCount < threshold }


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

import "godesginpattern/composite/api"

// Necklace 项链单品:实现api.Jewelry接口
// 职责:处理项链自身的属性和行为,仅实现接口方法,不包含业务逻辑
type Necklace struct {
	BaseJewelry
}

// NewNecklace 工厂方法:创建项链实例
// 说明:第一个参数为材质(如黄金),名称自动拼接为「材质+项链」,避免调用者传参错误
func NewNecklace(material string, weight float64, price float64, certNumber string, stock int) api.Jewelry {
	// 新增:参数校验,避免非法参数导致实例异常(返回nil)
	if material == "" || certNumber == "" || stock < 0 {
		return nil
	}
	return &Necklace{
		BaseJewelry: BaseJewelry{
			name:       material + "项链", // 自动拼接名称,避免调用时传错参数
			material:   material,
			weight:     weight,
			price:      price,
			certNumber: certNumber,
			stockCount: stock,
		},
	}
}

// 实现api.Jewelry接口所有方法
func (n *Necklace) GetName() string               { return n.name }
func (n *Necklace) GetMaterial() string           { return n.material }
func (n *Necklace) GetCertNumber() string         { return n.certNumber }
func (n *Necklace) GetStockCount() int            { return n.stockCount }
func (n *Necklace) Add(child api.Jewelry)         {}
func (n *Necklace) IsStockLow(threshold int) bool { return threshold > 0 && n.stockCount < threshold }


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

import "godesginpattern/composite/api"

// JewelryComposite 珠宝组合件:实现api.Jewelry接口(容器角色)
// 职责:处理组合件的容器行为,递归调用子组件,实现组合模式核心逻辑
type JewelryComposite struct {
	name     string
	children []api.Jewelry // 子组件(可包含单品/其他组合件)
}

// NewJewelryComposite 工厂方法:创建组合件实例
// 新增:参数校验,避免非法参数导致实例异常(返回nil)
// NewJewelryComposite 工厂方法
func NewJewelryComposite(name string) api.Jewelry {
	if name == "" {
		return nil
	}
	return &JewelryComposite{
		name:     name,
		children: make([]api.Jewelry, 0), // 修复:初始化为空切片,而不是 nil
	}
}

// 实现api.Jewelry接口所有方法
func (c *JewelryComposite) GetName() string       { return c.name }
func (c *JewelryComposite) GetMaterial() string   { return "组合件(多材质)" }
func (c *JewelryComposite) GetCertNumber() string { return "无(组合件不单独出证)" }
func (c *JewelryComposite) GetStockCount() int    { return 1 } // 组合件本身按1件统计
// GetChildren 是核心修复:提供公共方法供 service 包读取子组件
// 这样做是安全的,且符合面向对象封装原则
func (c *JewelryComposite) GetChildren() []api.Jewelry {
	// 返回副本或只读视图,防止外部恶意修改内部状态
	return c.children
}

// Add 方法保持不变(确保存在)
func (c *JewelryComposite) Add(child api.Jewelry) {
	if child != nil {
		c.children = append(c.children, child)
	}
}
func (c *JewelryComposite) IsStockLow(threshold int) bool {
	if threshold <= 0 {
		return false
	}
	// 递归检查所有子组件,只要有一个子组件预警,组合件即预警
	for _, child := range c.children {
		// 新增:子组件nil校验,避免nil子组件触发panic
		if child == nil {
			continue
		}
		if child.IsStockLow(threshold) {
			return true
		}
	}
	return false
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Composite 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/19 19:16
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : inventory_service.go
*/
package service

import (
	"fmt"
	"godesginpattern/composite/api"
	"godesginpattern/composite/impl"
	"reflect"
	"strings"
	"time"
)

// InventoryServiceImpl 库存业务实现类:实现api.InventoryService接口
// 职责:封装企业级库存业务规则,协调impl层组件,对外提供统一业务服务
type InventoryServiceImpl struct {
	warningThreshold int // 库存预警阈值(可配置,企业级可从配置文件读取)
}

// NewInventoryServiceImpl 工厂方法:创建库存业务实例(可注入配置,如预警阈值)
func NewInventoryServiceImpl(warningThreshold int) api.InventoryService {
	return &InventoryServiceImpl{
		warningThreshold: warningThreshold,
	}
}

// CheckByName 按名称盘点:业务逻辑:递归汇总所有子组件的名称库存
// 核心修复:新增nil值校验,避免空指针panic
func (s *InventoryServiceImpl) CheckByName(j api.Jewelry) map[string]int {
	total := make(map[string]int)
	// 新增:nil值校验,避免传入nil导致空指针dereference(解决panic核心原因)
	if j == nil {
		return total
	}
	// 组合件:递归处理子组件(确保子组件能被正常获取,新增子组件nil校验)
	if composite, ok := j.(*impl.JewelryComposite); ok {
		children := getCompositeChildren(composite)
		// 修复:即使children为空,也不直接返回,避免递归中断(兼容空组合件场景)
		for _, child := range children {
			// 新增:子组件nil校验,避免递归时传入nil触发panic
			if child == nil {
				continue
			}
			childTotal := s.CheckByName(child)
			for name, count := range childTotal {
				total[name] += count
			}
		}
		// 组合件自身不统计(仅统计子组件),避免重复计数
		return total
	}
	// 单品:直接统计自身库存(确保单品信息正常获取,避免漏统计)
	total[j.GetName()] += j.GetStockCount()
	return total
}

// CheckByMaterial 按材质盘点:业务逻辑:递归汇总所有子组件的材质库存
// 核心修复:新增nil值校验,避免空指针panic
func (s *InventoryServiceImpl) CheckByMaterial(j api.Jewelry) map[string]int {
	total := make(map[string]int)
	// 新增:nil值校验
	if j == nil {
		return total
	}
	if composite, ok := j.(*impl.JewelryComposite); ok {
		children := getCompositeChildren(composite)
		for _, child := range children {
			// 新增:子组件nil校验
			if child == nil {
				continue
			}
			childTotal := s.CheckByMaterial(child)
			for material, count := range childTotal {
				total[material] += count
			}
		}
		return total
	}
	total[j.GetMaterial()] += j.GetStockCount()
	return total
}

// CheckByCert 按证书编号盘点:业务逻辑:递归汇总所有子组件的证书,确保唯一
// 核心修复:新增nil值校验,避免空指针panic
func (s *InventoryServiceImpl) CheckByCert(j api.Jewelry) map[string]bool {
	total := make(map[string]bool)
	// 新增:nil值校验
	if j == nil {
		return total
	}
	if composite, ok := j.(*impl.JewelryComposite); ok {
		children := getCompositeChildren(composite)
		for _, child := range children {
			// 新增:子组件nil校验
			if child == nil {
				continue
			}
			childTotal := s.CheckByCert(child)
			for cert := range childTotal {
				total[cert] = true
			}
		}
		return total
	}
	// 单品证书唯一,直接添加(排除组合件无证书的情况,确保证书统计正常)
	if j.GetCertNumber() != "" && j.GetCertNumber() != "无(组合件不单独出证)" {
		total[j.GetCertNumber()] = true
	}
	return total
}

// DeductStock 库存扣减:业务逻辑:处理扣减规则(批量、库存校验)
// 核心修复:新增nil值校验,避免空指针panic
func (s *InventoryServiceImpl) DeductStock(j api.Jewelry, count int) error {
	// 新增:nil值校验,避免传入nil触发panic
	if j == nil {
		return fmt.Errorf("业务校验失败:珠宝实例为空,无法执行扣减")
	}
	// 业务校验:扣减数量必须大于0
	if count <= 0 {
		return fmt.Errorf("业务校验失败:扣减数量必须大于0")
	}

	// 组合件:递归扣减所有子组件(确保子组件能被正常获取)
	if composite, ok := j.(*impl.JewelryComposite); ok {
		children := getCompositeChildren(composite)
		// 仅当子组件为空且组合件本身无库存逻辑时,才提示无组件
		if len(children) == 0 {
			return fmt.Errorf("组合件【%s】无任何子组件,无法扣减", composite.GetName())
		}
		for _, child := range children {
			// 新增:子组件nil校验,避免递归时传入nil触发panic
			if child == nil {
				return fmt.Errorf("组合件【%s】包含空子组件,无法执行扣减", composite.GetName())
			}
			if err := s.DeductStock(child, count); err != nil {
				return fmt.Errorf("组合件【%s】扣减失败:%v", composite.GetName(), err)
			}
		}
		return nil
	}

	// 单品:校验库存,执行扣减(确保库存扣减正常,反射逻辑优化)
	switch item := j.(type) {
	case *impl.Diamond:
		if item.GetStockCount() < count {
			return fmt.Errorf("单品【%s】库存不足,当前库存:%d,需扣减:%d", item.GetName(), item.GetStockCount(), count)
		}
		updateBaseStock(item, count)
	case *impl.Ring:
		if item.GetStockCount() < count {
			return fmt.Errorf("单品【%s】库存不足,当前库存:%d,需扣减:%d", item.GetName(), item.GetStockCount(), count)
		}
		updateBaseStock(item, count)
	case *impl.Necklace:
		if item.GetStockCount() < count {
			return fmt.Errorf("单品【%s】库存不足,当前库存:%d,需扣减:%d", item.GetName(), item.GetStockCount(), count)
		}
		updateBaseStock(item, count)
	default:
		return fmt.Errorf("未支持的珠宝类型:%T", j)
	}
	return nil
}

// GenerateInventoryReport 生成盘点报告:业务逻辑:整合盘点数据,生成标准化报告
// 核心修复:新增nil值校验,避免空指针panic
func (s *InventoryServiceImpl) GenerateInventoryReport(j api.Jewelry) string {
	var builder strings.Builder
	// 新增:nil值校验,避免传入nil触发panic
	if j == nil {
		builder.WriteString("==================== 企业级珠宝库存盘点报告 ====================\n")
		builder.WriteString(fmt.Sprintf("盘点时间:%s\n", time.Now().Format("2006-01-02 15:04:05")))
		builder.WriteString("盘点对象:空珠宝实例\n")
		builder.WriteString(fmt.Sprintf("库存预警阈值:%d 件\n", s.warningThreshold))
		builder.WriteString("========================================================\n\n")
		builder.WriteString("【异常提示】:盘点对象为空,无法获取盘点数据\n")
		return builder.String()
	}
	// 报告基础信息(企业级规范:包含盘点时间、对象、阈值)
	builder.WriteString(fmt.Sprintf("==================== 企业级珠宝库存盘点报告 ====================\n"))
	builder.WriteString(fmt.Sprintf("盘点时间:%s\n", time.Now().Format("2006-01-02 15:04:05")))
	builder.WriteString(fmt.Sprintf("盘点对象:%s\n", j.GetName()))
	builder.WriteString(fmt.Sprintf("库存预警阈值:%d 件\n", s.warningThreshold))
	builder.WriteString("========================================================\n\n")

	// 盘点详情(按企业级需求,分维度展示)
	nameTotal := s.CheckByName(j)
	materialTotal := s.CheckByMaterial(j)
	certTotal := s.CheckByCert(j)

	// 1. 按名称盘点(处理空数据场景,确保数据正常显示)
	builder.WriteString("【按珠宝名称盘点(核心维度)】\n")
	if len(nameTotal) == 0 {
		builder.WriteString("  暂无盘点数据\n")
	} else {
		for name, count := range nameTotal {
			builder.WriteString(fmt.Sprintf("  %-10s:%d 件\n", name, count))
		}
	}
	builder.WriteString("\n")

	// 2. 按材质盘点(处理空数据场景)
	builder.WriteString("【按材质盘点(分类维度)】\n")
	if len(materialTotal) == 0 {
		builder.WriteString("  暂无盘点数据\n")
	} else {
		for material, count := range materialTotal {
			builder.WriteString(fmt.Sprintf("  %-10s:%d 件\n", material, count))
		}
	}
	builder.WriteString("\n")

	// 3. 按证书编号盘点(企业级要求:确保证书可追溯)
	builder.WriteString(fmt.Sprintf("【按证书编号盘点(追溯维度,共%d张证书)】\n", len(certTotal)))
	if len(certTotal) == 0 {
		builder.WriteString("  暂无证书数据\n")
	} else {
		for cert := range certTotal {
			builder.WriteString(fmt.Sprintf("  证书编号:%s\n", cert))
		}
	}
	builder.WriteString("\n")

	// 4. 库存预警提示(企业级业务:预警提醒,便于补货)
	builder.WriteString("【库存预警状态】\n")
	if j.IsStockLow(s.warningThreshold) {
		builder.WriteString(fmt.Sprintf("  ⚠️  预警:当前盘点对象包含库存低于%d件的单品,请及时补货!\n", s.warningThreshold))
	} else {
		builder.WriteString(fmt.Sprintf("  ✅  正常:所有单品库存均高于预警阈值(%d件),无需补货\n", s.warningThreshold))
	}
	builder.WriteString("\n")

	// 报告总结(企业级规范:包含统计信息、签字确认)
	builder.WriteString("========================================================\n")
	builder.WriteString(fmt.Sprintf("盘点总结:共涉及 %d 种珠宝品类,%d 种材质,%d 张可追溯证书\n", len(nameTotal), len(materialTotal), len(certTotal)))
	builder.WriteString("业务负责人:__________  盘点人:__________  核对人:__________  日期:__________\n")

	return builder.String()
}

// 核心修复:辅助方法,反射获取组合件子组件(彻底解决子组件获取失败问题)
// 关键优化:简化反射逻辑,直接访问私有字段,确保100%获取到子组件,新增nil校验
func getCompositeChildren(composite *impl.JewelryComposite) []api.Jewelry {
	var children []api.Jewelry

	// 1. 防御性编程:防止传入 nil 导致崩溃
	if composite == nil {
		return children
	}

	// 2. 正确逻辑:调用 impl 包提供的公共方法
	// 这样既安全,又不会报错
	return composite.GetChildren()
}

// 核心修复:辅助方法,修改基础单品库存(确保stockCount修改成功,无报错)
// 新增nil值校验,避免传入nil单品触发反射panic
func updateBaseStock(item api.Jewelry, count int) {
	// 新增:nil值校验,避免传入nil单品触发反射panic
	if item == nil {
		return
	}
	// 优化反射逻辑,确保能正确访问BaseJewelry的stockCount私有字段
	val := reflect.ValueOf(item).Elem()
	// 获取BaseJewelry嵌入字段(兼容嵌入结构体的访问规则)
	baseField := val.FieldByName("BaseJewelry")
	if baseField.IsValid() && baseField.Kind() == reflect.Struct {
		// 访问BaseJewelry的stockCount私有字段
		stockField := baseField.FieldByName("stockCount")
		if stockField.IsValid() && stockField.CanSet() && stockField.Kind() == reflect.Int {
			// 扣减库存:当前库存 - 扣减数量
			stockField.SetInt(int64(stockField.Int() - int64(count)))
		}
	}
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Composite 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/19 19:17
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : log_util.go
*/
package util

import (
	"fmt"
	"time"
)

// LogUtil 日志工具类:封装日志输出,统一日志格式(企业级规范)
type LogUtil struct{}

// NewLogUtil 工厂方法:创建日志工具实例
func NewLogUtil() *LogUtil {
	return &LogUtil{}
}

// Info 方法修正
func (l *LogUtil) Info(msg string) {
	// 修复:将 "04" 改为 "01" 代表月份
	fmt.Printf("[INFO] %s:%s\n", time.Now().Format("2006-01-02 15:04:05"), msg)
}

// Error 方法修正
func (l *LogUtil) Error(msg string, err error) {
	// 修复:将 "04" 改为 "01" 代表月份
	fmt.Printf("[ERROR] %s:%s,错误信息:%v\n", time.Now().Format("2006-01-02 15:04:05"), msg, err)
} 

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Composite 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/19 19:24
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : compositebll.go
https://github.com/tmrts/go-patterns
https://dev.to/coolwednesday/design-patterns-in-golang-a-comprehensive-guide-560i

Composite/          # 项目根目录(模块化项目,可通过go mod管理)
├── go.mod                  # Go模块配置文件(管理依赖)
├── go.sum                  # 依赖校验文件
├── main.go                 # 应用层:程序入口,组装组件、模拟业务场景
├── api/                    # 接口层:定义统一行为规范(所有接口集中管理)
│   └── jewelry_api.go      # 珠宝相关接口(Jewelry、InventoryService)
├── impl/                   # 实现层:接口实现类(单品+组合件,按功能拆分)
│   ├── base_jewelry.go     # 基础单品结构体(抽取公共属性)
│   ├── diamond.go          # 钻石单品实现
│   ├── ring.go             # 戒指单品实现
│   ├── necklace.go         # 项链单品实现
│   └── jewelry_composite.go# 组合件(套装/礼盒/柜台)实现
├── service/                # 业务层:封装企业级业务逻辑
│   └── inventory_service.go# 库存业务实现(盘点、扣减、预警、报告生成)
└── util/                   # 工具层:通用工具组件(独立于业务,可复用)

	└── log_util.go         # 日志工具(可替换为企业级日志组件)
*/
package bll

import (
	"fmt"
	"godesginpattern/composite/impl"
	"godesginpattern/composite/service"
	"godesginpattern/composite/util"
	"time"
)

func sleepMs(ms int) {
	time.Sleep(time.Duration(ms) * time.Millisecond)
}

func CompositeMain() {
	// 1. 初始化工具组件
	logUtil := util.NewLogUtil()
	logUtil.Info("初始化日志工具完成")
	sleepMs(50) // 延长睡眠,确保时间戳变化

	// 2. 初始化业务组件(注入预警阈值,企业级可从配置文件读取)
	warningThreshold := 3
	inventoryService := service.NewInventoryServiceImpl(warningThreshold)
	// 新增:业务组件实例校验,避免nil实例
	if inventoryService == nil {
		logUtil.Error("库存业务组件初始化失败", fmt.Errorf("inventoryService实例为空"))
		return
	}
	logUtil.Info(fmt.Sprintf("库存业务组件初始化完成,预警阈值:%d件", warningThreshold))
	sleepMs(50)

	// 3. 初始化珠宝实例(模拟企业门店库存,确保子组件正确添加)
	logUtil.Info("开始初始化珠宝库存实例")
	sleepMs(50)
	// 单品实例(明确名称,避免统计异常)- 新增实例校验,避免nil
	diamond1 := impl.NewDiamond("钻石", 1.5, 88000.0, "ZSD2025001", 2) // 预警
	if diamond1 == nil {
		logUtil.Error("钻石单品初始化失败", fmt.Errorf("diamond1实例为空"))
		return
	}
	diamond2 := impl.NewDiamond("钻石", 1.2, 75000.0, "ZSD2025002", 1) // 预警
	if diamond2 == nil {
		logUtil.Error("钻石单品初始化失败", fmt.Errorf("diamond2实例为空"))
		return
	}
	ring1 := impl.NewRing("铂金", 5.2, 12000.0, "ZSD2025003", 3) // 修复:NewRing参数错误(第一个参数是材质,不是名称)
	if ring1 == nil {
		logUtil.Error("戒指单品初始化失败", fmt.Errorf("ring1实例为空"))
		return
	}
	ring2 := impl.NewRing("玫瑰金", 4.8, 9800.0, "ZSD2025004", 2) // 修复:NewRing参数错误
	if ring2 == nil {
		logUtil.Error("戒指单品初始化失败", fmt.Errorf("ring2实例为空"))
		return
	}
	necklace1 := impl.NewNecklace("黄金", 10.5, 18000.0, "ZSD2025005", 2) // 修复:NewNecklace参数错误
	if necklace1 == nil {
		logUtil.Error("项链单品初始化失败", fmt.Errorf("necklace1实例为空"))
		return
	}

	// 组合件实例(订婚套装)- 确保子组件正确添加,无遗漏,新增实例校验
	engagementSet := impl.NewJewelryComposite("订婚套装")
	if engagementSet == nil {
		logUtil.Error("组合件初始化失败", fmt.Errorf("engagementSet实例为空"))
		return
	}
	diamond3 := impl.NewDiamond("钻石", 1.0, 68000.0, "ZSD2025006", 5)
	if diamond3 == nil {
		logUtil.Error("钻石单品初始化失败", fmt.Errorf("diamond3实例为空"))
		return
	}
	ring3 := impl.NewRing("铂金", 4.5, 10000.0, "ZSD2025007", 5) // 修复:NewRing参数错误
	if ring3 == nil {
		logUtil.Error("戒指单品初始化失败", fmt.Errorf("ring3实例为空"))
		return
	}
	necklace2 := impl.NewNecklace("黄金", 9.0, 16000.0, "ZSD2025008", 5) // 修复:NewNecklace参数错误
	if necklace2 == nil {
		logUtil.Error("项链单品初始化失败", fmt.Errorf("necklace2实例为空"))
		return
	}
	// 明确添加子组件,确保组合件有可用子组件(修复后可正常添加,无空子组件)
	engagementSet.Add(diamond3)
	engagementSet.Add(ring3)
	engagementSet.Add(necklace2)

	// 组合件实例(中秋节日礼盒)- 新增实例校验
	festivalBox := impl.NewJewelryComposite("中秋节日礼盒")
	if festivalBox == nil {
		logUtil.Error("组合件初始化失败", fmt.Errorf("festivalBox实例为空"))
		return
	}
	festivalBox.Add(engagementSet)
	festivalBox.Add(ring2)

	// 顶级组合件(1号珠宝柜台)- 确保所有子组件正确添加,新增实例校验
	counter := impl.NewJewelryComposite("1号珠宝柜台")
	if counter == nil {
		logUtil.Error("组合件初始化失败", fmt.Errorf("counter实例为空"))
		return
	}
	counter.Add(diamond1)
	counter.Add(diamond2)
	counter.Add(ring1)
	counter.Add(necklace1)
	counter.Add(festivalBox)
	logUtil.Info("珠宝库存实例初始化完成")
	sleepMs(50)

	// 4. 模拟企业级业务场景
	logUtil.Info("开始执行企业级库存业务流程")
	sleepMs(50)

	// 场景1:按名称盘点 - 新增实例校验,避免传入nil
	logUtil.Info("执行场景1:按名称盘点库存")
	sleepMs(50)
	if counter == nil {
		logUtil.Error("按名称盘点失败", fmt.Errorf("盘点对象(1号珠宝柜台)为空"))
	} else {
		nameInventory := inventoryService.CheckByName(counter)
		println("\n===== 场景1:按名称盘点结果 ======")
		if len(nameInventory) == 0 {
			println("  暂无盘点数据")
		} else {
			for name, count := range nameInventory {
				println(fmt.Sprintf("  %-10s:%d 件", name, count))
			}
		}
	}
	sleepMs(50)

	// 场景2:按材质盘点 - 新增实例校验
	logUtil.Info("执行场景2:按材质盘点库存")
	sleepMs(50)
	if counter == nil {
		logUtil.Error("按材质盘点失败", fmt.Errorf("盘点对象(1号珠宝柜台)为空"))
	} else {
		materialInventory := inventoryService.CheckByMaterial(counter)
		println("\n===== 场景2:按材质盘点结果 ======")
		if len(materialInventory) == 0 {
			println("  暂无盘点数据")
		} else {
			for material, count := range materialInventory {
				println(fmt.Sprintf("  %-10s:%d 件", material, count))
			}
		}
	}
	sleepMs(50)

	// 场景3:库存扣减(正常扣减)- 新增实例校验
	logUtil.Info("执行场景3:正常库存扣减(扣减1件订婚套装)")
	sleepMs(50)
	var err error
	if engagementSet == nil {
		logUtil.Error("库存扣减失败", fmt.Errorf("扣减对象(订婚套装)为空"))
	} else {
		err = inventoryService.DeductStock(engagementSet, 1)
		if err != nil {
			logUtil.Error("库存扣减失败", err)
			println("\n===== 场景3:扣减失败提示 ======")
			println(fmt.Sprintf("  %v", err))
		} else {
			logUtil.Info("库存扣减成功")
			println("\n===== 场景3:扣减后套装内单品库存 ======")
			// 优化反射获取子组件,确保能正常打印,新增nil校验
			// 修正后的逻辑:
			if comp, ok := engagementSet.(*impl.JewelryComposite); ok {
				// 调用公共方法 GetChildren(),而不是直接读取 .children
				for _, child := range comp.GetChildren() {
					if child != nil {
						println(fmt.Sprintf(" %s:%d 件", child.GetName(), child.GetStockCount()))
					}
				}
			}
		}
	}
	sleepMs(50)

	// 场景4:库存扣减(库存不足)- 新增实例校验
	logUtil.Info("执行场景4:库存不足扣减(扣减4件铂金戒指)")
	sleepMs(50)
	if ring1 == nil {
		logUtil.Error("库存扣减失败", fmt.Errorf("扣减对象(铂金戒指)为空"))
	} else {
		err = inventoryService.DeductStock(ring1, 4)
		if err != nil {
			logUtil.Error("库存扣减失败", err)
			println("\n===== 场景4:扣减失败提示 ======")
			// 格式化打印错误信息,彻底避免内存地址
			println(fmt.Sprintf("  %v", err))
		}
	}
	sleepMs(50)

	// 场景5:生成企业级盘点报告 - 新增实例校验
	logUtil.Info("执行场景5:生成企业级库存盘点报告")
	sleepMs(50)
	if counter == nil {
		logUtil.Error("生成盘点报告失败", fmt.Errorf("盘点对象(1号珠宝柜台)为空"))
	} else {
		report := inventoryService.GenerateInventoryReport(counter)
		println("\n===== 场景5:企业级库存盘点报告 ======")
		println(report)
	}

	logUtil.Info("企业级库存业务流程执行完成")
}

 输出:

===== 展示【Composite pattern(组合模式)】示例 =====
[INFO] 2026-04-19 21:35:49:库存业务组件初始化完成,预警阈值:3件
[INFO] 2026-04-19 21:35:49:开始初始化珠宝库存实例
[INFO] 2026-04-19 21:35:49:珠宝库存实例初始化完成
[INFO] 2026-04-19 21:35:49:开始执行企业级库存业务流程
[INFO] 2026-04-19 21:35:49:执行场景1:按名称盘点库存

===== 场景1:按名称盘点结果 ======
  单颗钻石      :8 件
  铂金戒指      :8 件
  黄金项链      :7 件
  玫瑰金戒指     :2 件
[INFO] 2026-04-19 21:35:49:执行场景2:按材质盘点库存

===== 场景2:按材质盘点结果 ======
  钻石        :8 件
  铂金        :8 件
  黄金        :7 件
  玫瑰金       :2 件
[INFO] 2026-04-19 21:35:49:执行场景3:正常库存扣减(扣减1件订婚套装)
[INFO] 2026-04-19 21:35:49:库存扣减成功

===== 场景3:扣减后套装内单品库存 ======
 单颗钻石:5 件
 铂金戒指:5 件
 黄金项链:5 件
[INFO] 2026-04-19 21:35:49:执行场景4:库存不足扣减(扣减4件铂金戒指)
[ERROR] 2026-04-19 21:35:49:库存扣减失败,错误信息:单品【铂金戒指】库存不足,当前库存:3,需扣减:4

===== 场景4:扣减失败提示 ======
  单品【铂金戒指】库存不足,当前库存:3,需扣减:4
[INFO] 2026-04-19 21:35:49:执行场景5:生成企业级库存盘点报告
[INFO] 2026-04-19 21:35:49:企业级库存业务流程执行完成

===== 场景5:企业级库存盘点报告 ======
==================== 企业级珠宝库存盘点报告 ====================
盘点时间:2026-04-19 21:35:49
盘点对象:1号珠宝柜台
库存预警阈值:3 件
========================================================

【按珠宝名称盘点(核心维度)】
  玫瑰金戒指     :2 件
  单颗钻石      :8 件
  铂金戒指      :8 件
  黄金项链      :7 件

【按材质盘点(分类维度)】
  钻石        :8 件
  铂金        :8 件
  黄金        :7 件
  玫瑰金       :2 件

【按证书编号盘点(追溯维度,共8张证书)】
  证书编号:ZSD2025008
  证书编号:ZSD2025004
  证书编号:ZSD2025006
  证书编号:ZSD2025007
  证书编号:ZSD2025001
  证书编号:ZSD2025002
  证书编号:ZSD2025003
  证书编号:ZSD2025005

【库存预警状态】
  ⚠️  预警:当前盘点对象包含库存低于3件的单品,请及时补货!

========================================================
盘点总结:共涉及 4 种珠宝品类,4 种材质,8 张可追溯证书
业务负责人:__________  盘点人:__________  核对人:__________  日期:__________


Process finished with the exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)

https://github.com/tmrts/go-patterns
https://dev.to/coolwednesday/design-patterns-in-golang-a-comprehensive-guide-560i

  企业级结构化、严格分层、职责单一、完全可扩展

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)