[Python设计模式] 第9章 如何准备多份简历——原型模式

it2022-05-20  70

github地址:https://github.com/cheesezh/python_design_patterns

题目

设计一个简历类,必须有姓名,可以设置性别和年龄,即个人信息,可以设置曾就职公司和工作时间,即工作经历。

基础版本

class Resume(): def __init__(self, name): self.name = name # python默认成员变量公开 self.__sex = None # python默认成员变量公开,加__表示私有 self.__age = None # python默认成员变量公开,加__表示私有 self.__time_area = None # python默认成员变量公开,加__表示私有 self.__company = None # python默认成员变量公开,加__表示私有 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("{}\t{}\t{}".format(self.name, self.__sex, self.__age)) print("{}\t{}".format(self.__time_area, self.__company)) def main(): resume_a = Resume("鸣人") resume_a.set_personal_info("男", "29") resume_a.set_work_experience("2016-2018", "木叶公司") resume_b = Resume("鸣人") resume_b.set_personal_info("男", "29") resume_b.set_work_experience("2016-2018", "木叶公司") resume_c = Resume("鸣人") resume_c.set_personal_info("男", "29") resume_c.set_work_experience("2016-2018", "木叶公司") resume_a.display() resume_b.display() resume_c.display() main() 鸣人 男 29 2016-2018 木叶公司 鸣人 男 29 2016-2018 木叶公司 鸣人 男 29 2016-2018 木叶公司

点评

上述main函数中生成简历的方法,相当于手写简历,三份简历要三次实例化而且如果要更改某个字段,比如把时间从2016-2018改成2017-2018,那么同样修改三次

那如果这样写呢?

def main(): resume_a = Resume("鸣人") resume_a.set_personal_info("男", "29") resume_a.set_work_experience("2016-2018", "木叶公司") resume_b = resume_a resume_c = resume_a resume_a.display() resume_b.display() resume_c.display() main() 鸣人 男 29 2016-2018 木叶公司 鸣人 男 29 2016-2018 木叶公司 鸣人 男 29 2016-2018 木叶公司

点评

这里传递的是引用,而不是具体的值,相当于在简历b和简历c上没有实际内容,而是写着“详见简历a”可以使用clone的方法解决这个问题,即原型模式

原型模式

原型模式,即用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象[DP]。也就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

from abc import ABCMeta, abstractmethod from copy import copy class Prototype(): """ 抽象原型类 """ __metaclass__ = ABCMeta def __init__(self, id): self.id = id @abstractmethod def clone(self): pass class ConcretePrototypeOne(Prototype): """ 具体原型类 """ def __init__(self, id): super().__init__(id) def clone(self): return copy(self) # 1. 浅拷贝copy.copy() 或 深拷贝copy.deepcopy() 2. Python无需强制类型转换 def main(): prototype1 = ConcretePrototypeOne("1") prototype1_cloned = prototype1.clone() print(prototype1_cloned.id) main() 1

Python中的浅拷贝与深拷贝

Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块。

copy.copy(浅拷贝):只拷贝顶层对象,不会拷贝顶层对象的内部的对象成员变量;copy.deepcopy(深拷贝):拷贝对象及其子对象

按照基础版本的简历类定义,成员变量的类型都是基本数据类型(string),所以使用浅拷贝即可。那么什么时候用深拷贝呢?假如我们将工作经历定义为一个单独的类WorkExperience,那么简历类中就会有一个成员变量的类型是WorkExperience,如果这时候需要拷贝操作,就需要用深拷贝了。

深拷贝原型模式

from copy import deepcopy class WorkExperience(): def __init__(self, time_area="", company=""): self.time_area = time_area self.company = company class Resume(): def __init__(self, name): self.name = name # python默认成员变量公开 self.__sex = None # python默认成员变量公开,加__表示私有 self.__age = None # python默认成员变量公开,加__表示私有 self.__work_expereince = WorkExperience() # python默认成员变量公开,加__表示私有 def set_personal_info(self, sex, age): self.__sex = sex self.__age = age def set_work_experience(self, time_area, company): self.__work_expereince.time_area = time_area self.__work_expereince.company = company def display(self): print("{}\t{}\t{}".format(self.name, self.__sex, self.__age)) print("{}\t{}".format(self.__work_expereince.time_area, self.__work_expereince.company)) def deep_clone(self): """ 深拷贝方法 """ return deepcopy(self) def clone(self): """ 浅拷贝方法 """ return copy(self) def main(): resume_a = Resume("鸣人") resume_a.set_personal_info("男", "29") resume_a.set_work_experience("2016-2018", "木叶公司") resume_b = resume_a.clone() resume_b.set_work_experience("2018-2019", "王者学校") resume_c = resume_a.clone() resume_c.set_personal_info("男", "24") resume_c.set_work_experience("2019-2020", "问问公司") resume_a.display() resume_b.display() resume_c.display() def deep_main(): resume_a = Resume("鸣人") resume_a.set_personal_info("男", "29") resume_a.set_work_experience("2016-2018", "木叶公司") resume_b = resume_a.deep_clone() resume_b.set_work_experience("2018-2019", "王者学校") resume_c = resume_a.deep_clone() resume_c.set_personal_info("男", "24") resume_c.set_work_experience("2019-2020", "问问公司") resume_a.display() resume_b.display() resume_c.display() print("---浅拷贝, 工作经历都被修改成最后一次的值---") main() print("--------深拷贝, 工作经历为不同的值--------") deep_main() ---浅拷贝, 工作经历都被修改成最后一次的值--- 鸣人 男 29 2019-2020 问问公司 鸣人 男 29 2019-2020 问问公司 鸣人 男 24 2019-2020 问问公司 --------深拷贝, 工作经历为不同的值-------- 鸣人 男 29 2016-2018 木叶公司 鸣人 男 29 2018-2019 王者学校 鸣人 男 24 2019-2020 问问公司

转载于:https://www.cnblogs.com/CheeseZH/p/9398461.html

相关资源:数据结构—成绩单生成器

最新回复(0)