基于Composite Pattern(组合模式)的家谱树类图适配方案问询
嘿,这个问题挺有意思的——组合模式确实能完美适配家谱这种既有独立个体、又有群体单元的结构。我来一步步拆解怎么设计,保证贴合你的需求:
核心思路:把「个体」和「家庭单元」都抽象为组件
组合模式的核心就是让单个对象和组合对象拥有统一的接口,这样客户端可以无差别处理。对应家谱场景:
- 叶子节点:
Person(单个家庭成员) - 组合节点:
FamilyUnit(封装婚姻关系+亲子关系的家庭单元)
两者都实现同一个组件接口,这样你既可以单独操作某个人,也可以把整个家庭当作一个整体来处理。
1. 定义统一的组件接口
先定义一个FamilyMemberComponent接口,约定所有家庭成员/单元都要实现的核心行为:
from abc import ABC, abstractmethod from typing import List class FamilyMemberComponent(ABC): @abstractmethod def get_info(self) -> str: """返回成员/单元的描述信息""" pass @abstractmethod def get_all_members(self) -> List['FamilyMemberComponent']: """返回当前组件包含的所有成员(个体或子单元)""" pass
这个接口是组合模式的骨架,保证Person和FamilyUnit对外行为一致。
2. 实现叶子节点:Person类
Person代表单个个体,是组合模式里的叶子节点(没有子节点)。它需要存储个人信息,同时关联自己所属的家庭(出生家庭、婚姻家庭):
class Person(FamilyMemberComponent): def __init__(self, name: str): self.name = name self.birth_family = None # 记录出生的家庭 self.marriage_families: List['FamilyUnit'] = [] # 记录参与的婚姻家庭 def get_info(self) -> str: return f"个人:{self.name}" def get_all_members(self) -> List['FamilyMemberComponent']: # 叶子节点只返回自己 return [self] def join_marriage(self, family: 'FamilyUnit'): """加入一个婚姻家庭""" if family not in self.marriage_families: self.marriage_families.append(family) family.add_spouse(self)
3. 实现组合节点:FamilyUnit类
FamilyUnit是组合模式的核心,用来封装两类核心关系:
- 婚姻关系:用
spouses列表存储所有配偶(支持多配偶,符合你“无性别/数量约束”的要求) - 亲子关系:用
children列表存储所有子女
它实现组件接口,同时提供管理配偶、子女的方法:
class FamilyUnit(FamilyMemberComponent): def __init__(self): self.spouses: List[Person] = [] self.children: List[Person] = [] def get_info(self) -> str: spouse_names = ", ".join([p.name for p in self.spouses]) child_names = ", ".join([p.name for p in self.children]) return f"家庭(配偶:{spouse_names};子女:{child_names})" def get_all_members(self) -> List['FamilyMemberComponent']: # 组合节点返回所有配偶和子女 members = self.spouses.copy() members.extend(self.children) return members def add_spouse(self, spouse: Person): """添加配偶(自动维护双向关联)""" if spouse not in self.spouses: self.spouses.append(spouse) if self not in spouse.marriage_families: spouse.marriage_families.append(self) def add_child(self, child: Person): """添加子女(自动维护出生家庭关联)""" if child not in self.children: self.children.append(child) child.birth_family = self
4. 类图适配说明
用文本类图梳理下结构(你可以直接转成UML图):
+-------------------------+ | FamilyMemberComponent | +-------------------------+ | + get_info(): str | | + get_all_members(): List | +-------------------------+ ^ | +-------------------+ | | +-------------------+ +-------------------+ | Person | | FamilyUnit | +-------------------+ +-------------------+ | - name: str | | - spouses: List<Person> | | - birth_family: FamilyUnit | | - children: List<Person> | | - marriage_families: List<FamilyUnit> | | + add_spouse(Person): void | | + get_info(): str | | + add_child(Person): void | | + get_all_members(): List | | + get_info(): str | | + join_marriage(FamilyUnit): void | | + get_all_members(): List | +-------------------+ +-------------------+
5. 使用示例:构建你的家谱
现在你可以轻松构建家谱树了,比如:
if __name__ == "__main__": # 创建个体 grandpa = Person("张三") grandma = Person("李四") dad = Person("张五") mom = Person("王六") me = Person("张小七") aunt = Person("张八") # 祖辈家庭(张三+李四,子女张五、张八) grand_family = FamilyUnit() grandpa.join_marriage(grand_family) grandma.join_marriage(grand_family) grand_family.add_child(dad) grand_family.add_child(aunt) # 父母家庭(张五+王六,子女张小七) parent_family = FamilyUnit() dad.join_marriage(parent_family) mom.join_marriage(parent_family) parent_family.add_child(me) # 输出祖辈家庭的所有成员 print("祖辈家庭成员:") for member in grand_family.get_all_members(): print(f"- {member.get_info()}") # 输出我的出生家庭信息 print(f"\n{me.name}的出生家庭:{me.birth_family.get_info()}")
运行后会得到:
祖辈家庭成员: - 个人:张三 - 个人:李四 - 个人:张五 - 个人:张八 张小七的出生家庭:家庭(配偶:张五, 王六;子女:张小七)
设计亮点
- 完全贴合组合模式:单个
Person和组合FamilyUnit可以被客户端统一处理(比如遍历成员) - 满足你的需求:完美维护婚姻(
spouses)和亲子(children)关系,无性别/数量约束 - 双向关联:自动维护个体和家庭的关联(比如Person知道自己的出生家庭,Family知道自己的成员)
内容的提问来源于stack exchange,提问作者Mariox
相关产品推荐
相关产品推荐

