
基于珠宝品类、库存、销售等核心实体来实现享元模式,重点区分「可共享的珠宝基础属性」和「个性化的销售 / 库存属性」,并通过实际业务流程(如库存查询、销售出库)展示模式价值。
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:享元模式 Flyweight Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/3/5 22:38
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : FlyweightPattern.py
from dataclasses import dataclass
# -------------------------- 1. 享元核心类(珠宝基础信息,共享内部状态) --------------------------
@dataclass(frozen=True) # 冻结,确保内部状态不可变(享元对象必须不可变)
class JewelryBaseInfo:
"""
珠宝基础信息(享元对象)- 仅包含可共享的内部状态
"""
category: str
"""
类:戒指/项链/手链/耳钉
"""
material: str
"""
材质:足金999/铂金PT950/18K金/钻石
"""
style: str #
"""
款式:传承系列/小蛮腰/莫桑钻镶嵌/经典素圈
"""
craft: str = "基础抛光"
"""
基础工艺(默认值)
"""
def get_base_desc(self) -> str:
"""
返回基础信息描述(共享部分)
:return:
"""
return f"{self.material} {self.style} {self.category}(工艺:{self.craft})"# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:享元模式 Flyweight Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/3/5 22:43
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : JewelryFlyweightFactory.py
from typing import Dict, List
from FlyweightPattern.JewelryBaseInfo import JewelryBaseInfo
# -------------------------- 2. 享元工厂(管理珠宝基础信息,避免重复创建) --------------------------
class JewelryFlyweightFactory:
"""
珠宝基础信息工厂 - 核心是缓存和复用享元对象
"""
_flyweight_pool: Dict[tuple, JewelryBaseInfo] = {} # 缓存池,键为内部状态组合
@classmethod
def get_jewelry_base_info(cls, category: str, material: str, style: str,
craft: str = "基础抛光") -> JewelryBaseInfo:
"""
获取/创建珠宝基础信息对象(核心:先查缓存,再创建)
:param category:
:param material:
:param style:
:param craft:
:return:
"""
# 内部状态组合作为唯一键(保证相同状态的对象只创建一次)
key = (category, material, style, craft)
if key not in cls._flyweight_pool:
# 无缓存时创建新对象
cls._flyweight_pool[key] = JewelryBaseInfo(category, material, style, craft)
print(f"【工厂】创建新基础信息对象:{key}")
else:
print(f"【工厂】复用已有基础信息对象:{key}")
return cls._flyweight_pool[key]
@classmethod
def get_pool_size(cls) -> int:
"""
查看缓存池大小(验证共享效果)
:return:
"""
return len(cls._flyweight_pool)# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:享元模式 Flyweight Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/3/5 22:45
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : JewelryInventory.py
from FlyweightPattern.JewelryBaseInfo import JewelryBaseInfo
from dataclasses import dataclass
# -------------------------- 3. 业务实体(依赖享元对象,包含外部状态) --------------------------
@dataclass
class JewelryInventory:
"""
珠宝库存实体(外部状态 + 享元对象)
"""
base_info: JewelryBaseInfo
"""
引用享元对象(共享内部状态)
"""
weight: float
"""
克重(外部状态)
"""
size: float
"""
尺寸(戒指圈口/项链长度,外部状态)
"""
stock_location: str
"""
库存位置(外部状态)
"""
stock_quantity: int = 1
"""
库存数量(外部状态)
"""
def check_stock(self) -> str:
"""
查询库存信息
:return:
"""
return (
f"【库存查询】\n"
f" 基础信息:{self.base_info.get_base_desc()}\n"
f" 个性化信息:克重{self.weight}g | 尺寸{self.size}mm | 库存位置{self.stock_location} | 库存数量{self.stock_quantity}件"
)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:享元模式 Flyweight Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/3/5 22:47
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : SalesOrder.py
from FlyweightPattern.JewelryBaseInfo import JewelryBaseInfo
from dataclasses import dataclass
# -------------------------- 3. 业务实体(依赖享元对象,包含外部状态) --------------------------
@dataclass
class SalesOrder:
"""
销售订单实体(外部状态 + 享元对象)
"""
base_info: JewelryBaseInfo
"""
引用享元对象(共享内部状态)
"""
weight: float
"""
克重(外部状态)
"""
size: float
"""
尺寸(外部状态)
"""
order_no: str
"""
订单号(外部状态)
"""
customer_name: str
"""
客户姓名(外部状态)
"""
price: float
"""
成交价格(外部状态)
"""
def create_order(self) -> str:
"""
生成销售订单
:return:
"""
return (
f"【销售订单】\n"
f" 订单号:{self.order_no}\n"
f" 客户:{self.customer_name}\n"
f" 商品:{self.base_info.get_base_desc()}\n"
f" 规格:克重{self.weight}g | 尺寸{self.size}mm\n"
f" 成交金额:¥{self.price:.2f}"
)# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:享元模式 Flyweight Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/3/5 22:50
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : FlyweightBll.py
from FlyweightPattern.JewelryFlyweightFactory import JewelryFlyweightFactory
from FlyweightPattern.JewelryInventory import JewelryInventory
from FlyweightPattern.SalesOrder import SalesOrder
# -------------------------- 4. 客户端业务流程(模拟珠宝店实际操作) --------------------------
class FlyweightBll(object):
"""
"""
def demo(self):
"""
:return:
"""
# 1. 初始化享元工厂
factory = JewelryFlyweightFactory()
# 2. 场景1:添加多款「足金999 传承系列 戒指」到库存(仅外部状态不同,共享基础信息)
print("===== 库存操作 =====")
# 第1枚传承戒指(创建新享元对象)
base_ring1 = factory.get_jewelry_base_info("戒指", "足金999", "传承系列")
inventory_ring1 = JewelryInventory(base_ring1, 5.2, 18.0, "A区1层01柜", 5)
print(inventory_ring1.check_stock())
# 第2枚传承戒指(复用已有享元对象)
base_ring2 = factory.get_jewelry_base_info("戒指", "足金999", "传承系列")
inventory_ring2 = JewelryInventory(base_ring2, 5.5, 19.0, "A区1层01柜", 3)
print(inventory_ring2.check_stock())
# 3. 场景2:添加「铂金PT950 小蛮腰 项链」到库存
base_necklace1 = factory.get_jewelry_base_info("项链", "铂金PT950", "小蛮腰", "拉丝工艺")
inventory_necklace1 = JewelryInventory(base_necklace1, 8.8, 45.0, "B区2层05柜", 2)
print(inventory_necklace1.check_stock())
# 4. 场景3:销售珠宝(基于库存创建订单,复用享元对象)
print("\n===== 销售操作 =====")
# 销售1枚传承戒指
order1 = SalesOrder(
base_info=base_ring1,
weight=5.2,
size=18.0,
order_no="SO20260305001",
customer_name="张三",
price=5.2 * 600 # 假设金价600元/克
)
print(order1.create_order())
# 销售1条小蛮腰项链
order2 = SalesOrder(
base_info=base_necklace1,
weight=8.8,
size=45.0,
order_no="SO20260305002",
customer_name="李四",
price=8.8 * 400 # 假设铂金400元/克
)
print(order2.create_order())
# 5. 验证享元对象数量(仅2个:传承戒指、小蛮腰项链)
print(f"\n===== 享元池统计 =====")
print(f"当前缓存的珠宝基础信息对象数量:{factory.get_pool_size()}")调用:
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 设计模式 Design Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2023.1 python 3.11
# OS : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j
# Datetime : 2026/2/18 20:58
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : main.py
# explain : 学习
import bll.CheckPatterns
def select_design_pattern() -> tuple[int, bll.CheckPatterns.DesignPattern | None]:
"""
返回 (序列号, 选中的枚举对象),退出则返回 (0, None)
:return:
"""
print("\n=== 方式3:用户选择展示 ===")
print("可选设计模式(输入0或q退出):")
for idx, pattern in enumerate(bll.CheckPatterns.DesignPattern, 1):
print(f"{idx}. {pattern._name_to_cn(pattern.name)}({pattern.name})")
print("0. 退出")
while True:
user_input = input("\n请输入序号选择要展示的设计模式(输入0/q退出):").strip()
if user_input in ("0", "q", "Q"):
print("👋 退出选择流程")
return (0, None)
try:
choice = int(user_input)
if 1 <= choice <= len(bll.CheckPatterns.DesignPattern):
selected_pattern = list(bll.CheckPatterns.DesignPattern)[choice - 1]
print(f"✅ 你选择了序号:{choice}(对应{selected_pattern._name_to_cn(selected_pattern.name)})")
return (choice, selected_pattern) # 返回(序列号, 枚举对象)
else:
print(f"❌ 输入无效!请输入1-{len(bll.CheckPatterns.DesignPattern)}之间的数字,或0/q退出")
except ValueError:
print("❌ 输入无效!请输入数字序号,或0/q退出")
def ask_continue() -> bool:
"""
询问用户是否继续选择,返回True(继续)/False(退出)
"""
while True:
user_choice = input("\n是否继续选择其他设计模式?(y/n):").strip().lower()
if user_choice == "y":
return True
elif user_choice == "n":
print("👋 感谢使用,程序结束!")
return False
else:
print("❌ 输入无效!请输入 y(继续)或 n(退出)")
if __name__ == '__main__':
# 方式1:用户输入选择展示(交互版)
'''
print("\n=== 方式1:用户选择展示 ===")
print("可选设计模式:")
for idx, pattern in enumerate( bll.CheckPatterns.DesignPattern, 1):
print(f"{idx}. {pattern._name_to_cn(pattern.name)}({pattern.name})")
try:
choice = int(input("\n请输入序号选择要展示的设计模式:"))
selected_pattern = list( bll.CheckPatterns.DesignPattern)[choice - 1]
selected_pattern.show_example()
except (ValueError, IndexError):
print("❌ 输入无效,请输入正确的序号!")
'''
# 2
print("🎉 设计模式示例展示程序")
while True:
# 1. 选择设计模式
selected_num, selected_pattern = select_design_pattern()
# 2. 判断是否直接退出(输入0/q)
if selected_num == 0:
print("👋 程序结束!")
break
# 3. 执行选中的示例
selected_pattern.show_example()
print(f"\n📌 本次选择的序列号是:{selected_num}")
# 4. 询问是否继续
if not ask_continue():
break # 用户选择不继续,终止循环
print('hi,welcome geovindu.')输出:
