
珠宝行业的典型场景: 叶子节点:单颗钻石、单条项链、单个戒指(不可拆分) 容器节点:订婚套装(戒指 + 项链 + 耳环)、节日礼盒(多件珠宝组合)、珠宝柜台(多个套装 / 单品) 结合珠宝实体属性(材质、重量、单价、证书编号)和业务流程(计算总价、生成销售清单、库存盘点)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:组合模式 Composite 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/7 15:14
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : JewelryComponent.py
from abc import ABC, abstractmethod
# ===================== 1 珠宝基础抽象类(Component)=====================
class JewelryComponent(ABC):
"""
统一叶子节点和容器节点的接口,定义珠宝核心属性和业务方法
"""
def __init__(self, name: str, material: str, cert_num: str = ""):
"""
:param name:
:param material:
:param cert_num:
"""
self.name = name
"""
珠宝名称(如:18K金钻戒、订婚套装)
"""
self.material = material
"""
材质(如:铂金、黄金、钻石)
"""
self.cert_num = cert_num
"""
证书编号(套装无单独证书,单品必填)
"""
@abstractmethod
def calculate_total_price(self) -> float:
"""
业务方法1:计算总价(核心)
:return:
"""
pass
@abstractmethod
def generate_sales_list(self, indent: str = "") -> str:
"""
业务方法2:生成销售清单
:param indent:
:return:
"""
pass
@abstractmethod
def inventory_check(self) -> int:
"""
业务方法3:库存盘点(统计数量)
:return:
"""
pass# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:组合模式 Composite 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/7 15:17
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : SingleJewelry.py
from CompositePattern.JewelryComponent import JewelryComponent
# =====================2 叶子节点:单个珠宝(Leaf)=====================
class SingleJewelry(JewelryComponent):
"""
不可拆分的单个珠宝,包含核心实体属性(重量、单价)
"""
def __init__(self, name: str, material: str, weight: float, unit_price: float, cert_num: str):
"""
:param name:
:param material:
:param weight:
:param unit_price:
:param cert_num:
"""
super().__init__(name, material, cert_num)
"""
调用父类 (超类)的一个方法。 super () 是用来解决多重继承问题的
"""
self.weight = weight
"""
重量(如:钻石0.5克拉、黄金5克)
"""
self.unit_price = unit_price
"""
单价(如:钻石8000元/克拉、黄金500元/克)
"""
def calculate_total_price(self) -> float:
"""
单个珠宝总价 = 重量 × 单价
:return:
"""
return round(self.weight * self.unit_price, 2)
def generate_sales_list(self, indent: str = "") -> str:
"""
生成单品销售清单(包含实体属性)
:param indent:
:return:
"""
return (
f"{indent}[单品] {self.name}\n"
f"{indent} - 材质:{self.material}\n"
f"{indent} - 重量:{self.weight}(单位)\n"
f"{indent} - 单价:{self.unit_price}元/单位\n"
f"{indent} - 证书编号:{self.cert_num}\n"
f"{indent} - 小计:{self.calculate_total_price()}元"
)
def inventory_check(self) -> int:
"""
单品库存数量为1
:return:
"""
return 1# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:组合模式 Composite 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/7 15:21
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : JewelryComposite.py
from CompositePattern.JewelryComponent import JewelryComponent
from typing import List
# ===================== 3 容器节点:珠宝组合(Composite)=====================
class JewelryComposite(JewelryComponent):
"""
可包含多个单品/子组合,如套装、礼盒
"""
def __init__(self, name: str, material: str = "组合装"):
"""
:param name:
:param material:
"""
super().__init__(name, material)
self.children: List[JewelryComponent] = [] # 子节点(单品/组合)
def add(self, jewelry: JewelryComponent) -> None:
"""
添加珠宝(单品/组合)
:param jewelry:
:return:
"""
self.children.append(jewelry)
def remove(self, jewelry: JewelryComponent) -> None:
"""
移除珠宝
:param jewelry:
:return:
"""
self.children.remove(jewelry)
def calculate_total_price(self) -> float:
"""
组合总价 = 所有子节点总价之和
:return:
"""
total = sum(child.calculate_total_price() for child in self.children)
return round(total, 2)
def generate_sales_list(self, indent: str = "") -> str:
"""
生成组合销售清单(递归遍历子节点)
:param indent:
:return:
"""
list_str = f"{indent}[组合] {self.name}\n{indent} - 包含:\n"
for child in self.children:
list_str += child.generate_sales_list(indent + " ") + "\n"
list_str += f"{indent} - 组合总价:{self.calculate_total_price()}元"
return list_str
def inventory_check(self) -> int:
"""
组合库存数量 = 所有子节点数量之和
:return:
"""
return sum(child.inventory_check() for child in self.children)# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:组合模式 Composite 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/7 15:24
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : CompositeBll.py
from CompositePattern.SingleJewelry import SingleJewelry
from CompositePattern.JewelryComposite import JewelryComposite
# =====================4 客户端业务流程测试 =====================
class CompositeBll(object):
"""
组合模式 Composite Pattern
"""
def demo(self):
"""
组合模式 Composite Pattern
:return:
"""
# 1. 创建单个珠宝(叶子节点)
diamond_ring = SingleJewelry(
name="18K金钻戒",
material="18K金+钻石",
weight=0.5, # 钻石0.5克拉
unit_price=8000, # 钻石8000元/克拉
cert_num="GIA20260307001"
)
gold_necklace = SingleJewelry(
name="足金项链",
material="足金",
weight=5.2, # 黄金5.2克
unit_price=500, # 黄金500元/克
cert_num="NGTC20260307002"
)
pearl_earrings = SingleJewelry(
name="珍珠耳环",
material="925银+珍珠",
weight=2.0, # 珍珠2.0克
unit_price=300, # 珍珠300元/克
cert_num="NGTC20260307003"
)
# 2. 创建珠宝组合(容器节点):订婚套装(戒指+项链+耳环)
engagement_set = JewelryComposite(name="订婚珠宝套装")
engagement_set.add(diamond_ring)
engagement_set.add(gold_necklace)
engagement_set.add(pearl_earrings)
# 3. 创建更高层级组合:节日礼盒(订婚套装+额外手链)
bracelet = SingleJewelry(
name="铂金手链",
material="铂金",
weight=8.0,
unit_price=450,
cert_num="NGTC20260307004"
)
festival_gift = JewelryComposite(name="春节珠宝礼盒")
festival_gift.add(engagement_set)
festival_gift.add(bracelet)
# ===================== 业务流程1:计算总价 =====================
print("=== 业务流程1:计算总价 ===")
print(f"单颗钻戒总价:{diamond_ring.calculate_total_price()}元")
print(f"订婚套装总价:{engagement_set.calculate_total_price()}元")
print(f"春节礼盒总价:{festival_gift.calculate_total_price()}元\n")
# ===================== 业务流程2:生成销售清单 =====================
print("=== 业务流程2:生成销售清单 ===")
print(festival_gift.generate_sales_list())
print()
# ===================== 业务流程3:库存盘点 =====================
print("=== 业务流程3:库存盘点 ===")
print(f"订婚套装库存数量:{engagement_set.inventory_check()}件")
print(f"春节礼盒库存数量:{festival_gift.inventory_check()}件")调用:
# 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 Controller.CheckPatterns
def select_design_pattern() -> tuple[int, Controller.CheckPatterns.DesignPattern | None]:
"""
返回 (序列号, 选中的枚举对象),退出则返回 (0, None)
:return:
"""
print("\n=== 方式3:用户选择展示 ===")
print("可选设计模式(输入0或q退出):")
for idx, pattern in enumerate(Controller.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(Controller.CheckPatterns.DesignPattern):
selected_pattern = list(Controller.CheckPatterns.DesignPattern)[choice - 1]
print(f"✅ 你选择了序号:{choice}(对应{selected_pattern._name_to_cn(selected_pattern.name)})")
return (choice, selected_pattern) # 返回(序列号, 枚举对象)
else:
print(f"❌ 输入无效!请输入1-{len(Controller.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.')输出:
