【设计模式】6.原型模式
every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog
0. 前言
原型模式
1. 基础
import copyclass Resume:def __init__(self, name):self.name = nameself.sex = Noneself.age = Noneself.time_area = Noneself.company = Nonedef set_personal_info(self, sex, age):"""设置个人信息"""self.sex = sexself.age = agedef set_work_experience(self, time_area, company):"""设置工作经历"""self.time_area = time_areaself.company = companydef display(self):"""显示简历信息"""print(f"{self.name} {self.sex} {self.age}")print(f"工作经历: {self.time_area} {self.company}")# 客户端代码
if __name__ == "__main__":# 原始简历a = Resume("大鸟")a.set_personal_info("男", "29")a.set_work_experience("1998-2000", "XX公司")b = Resume("大鸟2")b.set_personal_info("男", "16")b.set_work_experience("1998-2010", "XX公司")# 显示所有简历a.display()b.display()
2. 原型模式
import copyclass Resume:def __init__(self, name):"""初始化简历"""self.name = nameself.sex = Noneself.age = Noneself.time_area = Noneself.company = Nonedef set_personal_info(self, sex, age):"""设置个人信息"""self.sex = sexself.age = agedef set_work_experience(self, time_area, company):"""设置工作经历"""self.time_area = time_areaself.company = companydef display(self):"""显示简历信息"""print(f"{self.name} {self.sex} {self.age}")print(f"工作经历: {self.time_area} {self.company}")def clone(self, deep=False):"""实现克隆方法(原型模式核心):param deep: 是否使用深拷贝,默认为浅拷贝:return: 克隆后的新对象"""return copy.deepcopy(self) if deep else copy.copy(self)if __name__ == "__main__":print("="*40)print("原型模式演示 - 简历复印")print("="*40)# 原始简历original = Resume("大鸟")original.set_personal_info("男", "29")original.set_work_experience("1998-2000", "XX公司")# 使用浅拷贝克隆简历shallow_copy = original.clone(deep=False)shallow_copy.set_work_experience("1998-2006", "YY企业")# 使用深拷贝克隆简历deep_copy = original.clone(deep=True)deep_copy.set_personal_info("男", "24")# 显示所有简历print("\n原始简历:")original.display()print("\n浅拷贝修改工作经历后的简历:")shallow_copy.display()print("\n深拷贝修改个人信息后的简历:")deep_copy.display()print("\n验证浅拷贝对原始对象的影响:")print("原始对象的工作经历未被修改:" if original.time_area == "1998-2000" else "警告: 浅拷贝影响了原始对象!")
3. 浅复制
直接转换为Python代码(保留原始逻辑问题)
class WorkExperience:def __init__(self):self.work_date = ""self.company = ""@propertydef WorkDate(self):return self.work_date@WorkDate.setterdef WorkDate(self, value):self.work_date = value@propertydef Company(self):return self.company@Company.setterdef Company(self, value):self.company = valueclass Resume:def __init__(self, name):self.name = nameself.sex = ""self.age = ""self.work = WorkExperience() # 实例化工作经历def SetPersonalInfo(self, sex, age):self.sex = sexself.age = agedef SetWorkExperience(self, work_date, company):self.work.WorkDate = work_dateself.work.Company = companydef Display(self):print(f"{self.name} {self.sex} {self.age}")print(f"工作经历: {self.work.WorkDate} {self.work.Company}")def Clone(self):# 使用浅复制,会导致工作经历对象被共享return copy.copy(self)# 客户端代码
import copyif __name__ == "__main__":a = Resume("大鸟")a.SetPersonalInfo("男", "29")a.SetWorkExperience("1998-2000", "XX公司")b = a.Clone()b.SetWorkExperience("1998-2006", "YY企业")c = a.Clone()c.SetWorkExperience("1998-2003", "ZZ企业")a.Display()b.Display()c.Display()
说明
-
问题:
- 所有克隆对象共享同一个
WorkExperience
对象引用
- 所有克隆对象共享同一个
-
输出结果会有问题:
大鸟 男 29 工作经历: 1998-2003 ZZ企业 大鸟 男 29 工作经历: 1998-2003 ZZ企业 大鸟 男 29 工作经历: 1998-2003 ZZ企业
- 所有简历显示的工作经历都是最后设置的"ZZ企业"
4. 深复制
import copyclass WorkExperience:def __init__(self):self.work_date = ""self.company = ""@propertydef work_date(self):return self._work_date@work_date.setterdef work_date(self, value):self._work_date = value@propertydef company(self):return self._company@company.setterdef company(self, value):self._company = valueclass Resume:def __init__(self, name):self.name = nameself.sex = ""self.age = ""self.work_experience = WorkExperience() # 组合一个工作经历对象def set_personal_info(self, sex, age):self.sex = sexself.age = agedef set_work_experience(self, work_date, company):self.work_experience.work_date = work_dateself.work_experience.company = companydef display(self):print(f"{self.name} {self.sex} {self.age}")print(f"工作经历: {self.work_experience.work_date} {self.work_experience.company}")def clone(self):# 使用深复制来解决共享引用问题return copy.deepcopy(self)# 客户端代码
if __name__ == "__main__":a = Resume("大鸟")a.set_personal_info("男", "29")a.set_work_experience("1998-2000", "XX公司")b = a.clone()b.set_work_experience("1998-2006", "YY企业")c = a.clone()c.set_work_experience("1998-2003", "ZZ企业")a.display()b.display()c.display()
关键点说明
-
解决方案:
- 使用
copy.deepcopy()
进行深复制,确保WorkExperience
对象也被完整复制 - 这样每个简历对象都有自己独立的工作经历对象
- 使用
-
输出结果:
大鸟 男 29 工作经历: 1998-2000 XX公司 大鸟 男 29 工作经历: 1998-2006 YY企业 大鸟 男 29 工作经历: 1998-2003 ZZ企业