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

推荐订阅源

Martin Fowler
Martin Fowler
J
Java Code Geeks
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
腾讯CDC
D
DataBreaches.Net
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
V
V2EX
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
Jina AI
Jina AI
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
B
Blog
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium

博客园 - ®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: Flyweight Pattern
®Geovin Du D · 2026-04-20 · via 博客园 - ®Geovin Du Dream Park™

项目结构:

image

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

import (
	"fmt"
	"godesginpattern/flyweight/errors"
)

// JewelryCategoryFlyweight 享元接口(共享内部状态)
type JewelryCategoryFlyweight interface {
	CategoryID() string
	CategoryName() string
	Material() string
	Style() string
	BasePrice() float64
	BaseInfo() string
}

// jewelryCategory 实现
type jewelryCategory struct {
	categoryID   string
	categoryName string
	material     string
	style        string
	basePrice    float64
}

func (j *jewelryCategory) CategoryID() string   { return j.categoryID }
func (j *jewelryCategory) CategoryName() string { return j.categoryName }
func (j *jewelryCategory) Material() string     { return j.material }
func (j *jewelryCategory) Style() string        { return j.style }
func (j *jewelryCategory) BasePrice() float64   { return j.basePrice }

func (j *jewelryCategory) BaseInfo() string {
	return fmt.Sprintf("品类ID:%s | 名称:%s | 材质:%s | 款式:%s | 基础价:%.2f",
		j.categoryID, j.categoryName, j.material, j.style, j.basePrice)
}

// NewJewelryCategory 创建享元
func NewJewelryCategory(id, name, material, style string, basePrice float64) (JewelryCategoryFlyweight, error) {
	if id == "" {
		return nil, errors.ErrCategoryEmpty
	}
	return &jewelryCategory{
		categoryID:   id,
		categoryName: name,
		material:     material,
		style:        style,
		basePrice:    basePrice,
	}, nil
}


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

import (
	"fmt"
	"godesginpattern/flyweight/domain/flyweight"
)

type JewelryStatus string

const (
	StatusOnSale  JewelryStatus = "在售"
	StatusSoldOut JewelryStatus = "已售罄"
	StatusOffline JewelryStatus = "已下架"
)

// JewelryInventory 库存实体(外部状态)
type JewelryInventory struct {
	UniqueCode string
	StockNum   int
	OnlineTime string
	SalePrice  float64
	Status     JewelryStatus
	Category   flyweight.JewelryCategoryFlyweight
}

func (j *JewelryInventory) FullInfo() string {
	return fmt.Sprintf(
		"[%s] %s | 唯一码:%s | 库存:%d | 售价:%.2f | 状态:%s",
		j.Category.CategoryID(), j.Category.BaseInfo(),
		j.UniqueCode, j.StockNum, j.SalePrice, j.Status,
	)
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Flyweight 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/20 20:59
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : category_factory.go
*/
package factory

import (
	"context"
	"godesginpattern/flyweight/domain/flyweight"
	"log"
	"sync"
)

// FlyweightFactory 享元工厂接口
type FlyweightFactory interface {
	GetCategory(ctx context.Context, req NewCategoryReq) (flyweight.JewelryCategoryFlyweight, error)
	Count() int
}

type NewCategoryReq struct {
	CategoryID   string
	CategoryName string
	Material     string
	Style        string
	BasePrice    float64
}

// categoryFactory 实现
type categoryFactory struct {
	mu    sync.RWMutex
	cache map[string]flyweight.JewelryCategoryFlyweight
}

func NewCategoryFactory() FlyweightFactory {
	return &categoryFactory{
		cache: make(map[string]flyweight.JewelryCategoryFlyweight),
	}
}

func (f *categoryFactory) GetCategory(ctx context.Context, req NewCategoryReq) (flyweight.JewelryCategoryFlyweight, error) {
	f.mu.RLock()
	cate, ok := f.cache[req.CategoryID]
	f.mu.RUnlock()

	if ok {
		log.Printf("[工厂] 复用品类:%s", req.CategoryID)
		return cate, nil
	}

	f.mu.Lock()
	defer f.mu.Unlock()

	if cate, ok = f.cache[req.CategoryID]; ok {
		return cate, nil
	}

	newCate, err := flyweight.NewJewelryCategory(
		req.CategoryID, req.CategoryName, req.Material, req.Style, req.BasePrice,
	)
	if err != nil {
		return nil, err
	}

	f.cache[req.CategoryID] = newCate
	log.Printf("[工厂] 创建新品类:%s", req.CategoryID)
	return newCate, nil
}

func (f *categoryFactory) Count() int {
	f.mu.RLock()
	defer f.mu.RUnlock()
	return len(f.cache)
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Flyweight 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/20 20:59
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : inventory_service.go
*/
package service

import (
	"context"
	"godesginpattern/flyweight/domain/flyweight"
	"godesginpattern/flyweight/domain/inventory"
	"godesginpattern/flyweight/errors"
	"log"
)

// InventoryService 库存服务接口
type InventoryService interface {
	CreateInventory(ctx context.Context, req CreateInventoryReq) *inventory.JewelryInventory
	Query(ctx context.Context, inv *inventory.JewelryInventory) string
	SaleOut(ctx context.Context, inv *inventory.JewelryInventory, num int) error
}

type CreateInventoryReq struct {
	UniqueCode string
	OnlineTime string
	SalePrice  float64
	Category   flyweight.JewelryCategoryFlyweight
}

// inventoryService 实现
type inventoryService struct{}

func NewInventoryService() InventoryService {
	return &inventoryService{}
}

func (s *inventoryService) CreateInventory(ctx context.Context, req CreateInventoryReq) *inventory.JewelryInventory {
	return &inventory.JewelryInventory{
		UniqueCode: req.UniqueCode,
		StockNum:   1,
		OnlineTime: req.OnlineTime,
		SalePrice:  req.SalePrice,
		Status:     inventory.StatusOnSale,
		Category:   req.Category,
	}
}

func (s *inventoryService) Query(ctx context.Context, inv *inventory.JewelryInventory) string {
	return inv.FullInfo()
}

func (s *inventoryService) SaleOut(ctx context.Context, inv *inventory.JewelryInventory, num int) error {
	if inv.StockNum < num {
		return errors.ErrStockNotEnough
	}

	inv.StockNum -= num
	if inv.StockNum == 0 {
		inv.Status = inventory.StatusSoldOut
	}

	log.Printf("[销售] 出库成功:%s 剩余:%d", inv.UniqueCode, inv.StockNum)
	return nil
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Flyweight 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/20 20:59
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_api.go
*/
package api

import (
	"context"
	"fmt"
	"godesginpattern/flyweight/config"
	"godesginpattern/flyweight/domain/inventory"
	"godesginpattern/flyweight/infrastructure/factory"
	"godesginpattern/flyweight/service"
)

// JewelryAPI 对外接口层
type JewelryAPI struct {
	config  *config.AppConfig
	factory factory.FlyweightFactory
	service service.InventoryService
}

func NewJewelryAPI(
	cfg *config.AppConfig,
	f factory.FlyweightFactory,
	s service.InventoryService,
) *JewelryAPI {
	return &JewelryAPI{
		config:  cfg,
		factory: f,
		service: s,
	}
}

// BatchCreate 批量创建库存
func (api *JewelryAPI) BatchCreate(ctx context.Context, req factory.NewCategoryReq, count int) ([]*inventory.JewelryInventory, error) {
	cate, err := api.factory.GetCategory(ctx, req)
	if err != nil {
		return nil, err
	}

	var list []*inventory.JewelryInventory
	for i := 1; i <= count; i++ {
		inv := api.service.CreateInventory(ctx, service.CreateInventoryReq{
			UniqueCode: fmt.Sprintf("JM%06d", i),
			OnlineTime: "2025-01-10",
			SalePrice:  cate.BasePrice() - 300,
			Category:   cate,
		})
		list = append(list, inv)
	}
	return list, nil
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Flyweight 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/20 21:00
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config

type AppConfig struct {
	AppName string
	Version string
}

func NewDefaultConfig() *AppConfig {
	return &AppConfig{
		AppName: "jewelry-inventory-system",
		Version: "v1.0.0",
	}
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Flyweight 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/20 20:59
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : errors.go
*/
package errors

import "errors"

var (
	ErrStockNotEnough = errors.New("库存不足")
	ErrCategoryEmpty  = errors.New("品类ID不能为空")
)

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Flyweight 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/20 21:03
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : flyweightbll.go
flyweight/
├── go.mod                  # Go 模块
├── cmd/
│   └── main.go             # 项目启动入口
├── config/
│   └── config.go           # 应用配置
├── domain/
│   ├── flyweight/
│   │   └── jewelry_category.go  # 享元(共享内部状态)
│   └── inventory/
│       └── inventory.go    # 库存实体(外部状态)
├── infrastructure/
│   └── factory/
│       └── category_factory.go   # 享元工厂(缓存/复用)
├── service/
│   └── inventory_service.go      # 业务逻辑层
├── api/
│   └── jewelry_api.go            # 对外接口/流程编排
└── common/

	└── errors/
	    └── errors.go       # 全局统一错误
*/
package bll

import (
	"context"
	"godesginpattern/flyweight/api"
	"godesginpattern/flyweight/config"
	"godesginpattern/flyweight/infrastructure/factory"
	"godesginpattern/flyweight/service"
	"log"
)

func FlyweightMain() {
	ctx := context.Background()
	cfg := config.NewDefaultConfig()

	// 依赖注入
	f := factory.NewCategoryFactory()
	s := service.NewInventoryService()
	api := api.NewJewelryAPI(cfg, f, s)

	log.Println("=== 珠宝库存销售系统启动 ===")

	// 创建10000件钻戒
	diamond, _ := api.BatchCreate(ctx, factory.NewCategoryReq{
		CategoryID:   "C001",
		CategoryName: "钻戒",
		Material:     "18K金",
		Style:        "经典六爪",
		BasePrice:    5999,
	}, 10000)

	// 创建5000件黄金项链
	gold, _ := api.BatchCreate(ctx, factory.NewCategoryReq{
		CategoryID:   "C002",
		CategoryName: "黄金项链",
		Material:     "足金999",
		Style:        "简约锁骨链",
		BasePrice:    2999,
	}, 5000)

	log.Printf("总库存:%d", len(diamond)+len(gold))
	log.Printf("共享享元对象:%d", f.Count())

	// 查询 & 销售
	log.Println("\n=== 库存查询 ===")
	log.Println(s.Query(ctx, diamond[0]))

	log.Println("\n=== 销售出库 ===")
	_ = s.SaleOut(ctx, diamond[0], 1)
	log.Println(s.Query(ctx, diamond[0]))
}

输出:

image

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