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企業