【设计模式】6.原型模式

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

原型模式

1. 基础

python 复制代码
import copy

class Resume:
    def __init__(self, name):
        self.name = name
        self.sex = None
        self.age = None
        self.time_area = None
        self.company = None
    
    def set_personal_info(self, sex, age):
        """设置个人信息"""
        self.sex = sex
        self.age = age
    
    def set_work_experience(self, time_area, company):
        """设置工作经历"""
        self.time_area = time_area
        self.company = company
    
    def 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. 原型模式

python 复制代码
import copy

class Resume:
    def __init__(self, name):
        """初始化简历"""
        self.name = name
        self.sex = None
        self.age = None
        self.time_area = None
        self.company = None
    
    def set_personal_info(self, sex, age):
        """设置个人信息"""
        self.sex = sex
        self.age = age
    
    def set_work_experience(self, time_area, company):
        """设置工作经历"""
        self.time_area = time_area
        self.company = company
    
    def 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代码(保留原始逻辑问题)

python 复制代码
class WorkExperience:
    def __init__(self):
        self.work_date = ""
        self.company = ""
    
    @property
    def WorkDate(self):
        return self.work_date
    
    @WorkDate.setter
    def WorkDate(self, value):
        self.work_date = value
    
    @property
    def Company(self):
        return self.company
    
    @Company.setter
    def Company(self, value):
        self.company = value


class Resume:
    def __init__(self, name):
        self.name = name
        self.sex = ""
        self.age = ""
        self.work = WorkExperience()  # 实例化工作经历
    
    def SetPersonalInfo(self, sex, age):
        self.sex = sex
        self.age = age
    
    def SetWorkExperience(self, work_date, company):
        self.work.WorkDate = work_date
        self.work.Company = company
    
    def 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 copy

if __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()

说明

  1. 问题

    • 所有克隆对象共享同一个WorkExperience对象引用
  2. 输出结果会有问题

    复制代码
    大鸟 男 29
    工作经历: 1998-2003 ZZ企业
    大鸟 男 29
    工作经历: 1998-2003 ZZ企业
    大鸟 男 29
    工作经历: 1998-2003 ZZ企业
    • 所有简历显示的工作经历都是最后设置的"ZZ企业"

4. 深复制

python 复制代码
import copy

class WorkExperience:
    def __init__(self):
        self.work_date = ""
        self.company = ""
    
    @property
    def work_date(self):
        return self._work_date
    
    @work_date.setter
    def work_date(self, value):
        self._work_date = value
    
    @property
    def company(self):
        return self._company
    
    @company.setter
    def company(self, value):
        self._company = value


class Resume:
    def __init__(self, name):
        self.name = name
        self.sex = ""
        self.age = ""
        self.work_experience = WorkExperience()  # 组合一个工作经历对象
    
    def set_personal_info(self, sex, age):
        self.sex = sex
        self.age = age
    
    def set_work_experience(self, work_date, company):
        self.work_experience.work_date = work_date
        self.work_experience.company = company
    
    def 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()

关键点说明

  1. 解决方案

    • 使用copy.deepcopy()进行深复制,确保WorkExperience对象也被完整复制
    • 这样每个简历对象都有自己独立的工作经历对象
  2. 输出结果

    复制代码
    大鸟 男 29
    工作经历: 1998-2000 XX公司
    大鸟 男 29
    工作经历: 1998-2006 YY企业
    大鸟 男 29
    工作经历: 1998-2003 ZZ企业
相关推荐
pe7er3 小时前
nuxtjs+git submodule的微前端有没有搞头
前端·设计模式·前端框架
极光雨雨5 小时前
【设计模式】单例模式 饿汉式单例与懒汉式单例
单例模式·设计模式
贱贱的剑9 小时前
2.单例模式
单例模式·设计模式
Your易元12 小时前
设计模式-模板方法模式
java·设计模式·模板方法模式
暴走的海鸽14 小时前
存储库模式赋能 Django:让你的代码不那么业余,更具生命力
python·设计模式·django
小张在编程15 小时前
Java设计模式实战:备忘录模式与状态机模式的“状态管理”双雄
java·设计模式·备忘录模式
小小寂寞的城1 天前
JAVA观察者模式demo【设计模式系列】
java·观察者模式·设计模式
花好月圆春祺夏安1 天前
基于odoo17的设计模式详解---备忘模式
数据库·设计模式
DKPT1 天前
Java设计模式之行为型模式(责任链模式)介绍与说明
java·笔记·学习·观察者模式·设计模式
使一颗心免于哀伤2 天前
《设计模式之禅》笔记摘录 - 6.原型模式
笔记·设计模式