大话设计模式:第9章 原型模式

第9章:原型模式

原型模式

原型模式(prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

在这里插入图片描述

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。

Prototype
在这里插入图片描述

ConcretePrototype1

在这里插入图片描述
客户端代码

在这里插入图片描述

这样可以直接克隆,而不用实例化ConcretePrototype1

对于.NET而言,不需要原型抽象类Prototype的定义,因为克隆为常用操作,所以.NETSystem命名空间中提供了ICloneable接口,其中唯一一个方法就是Clone(),只需要实现这个接口就可以完成原型模式了。

原型模式示例

任务:简历复制

在这里插入图片描述

from typing import Text
from copy import copy, deepcopy
# 简历类

class Resume(object):
    
    def __init__(self, name: Text) -> None:
        self.__name = name
        self.__age = None
        self.__sex = None
        self.__time_area = None
        self.__company = None
        
    def set_personal_info(self, sex: Text, age: int) -> None:
        """
        设置个人信息
        """
        self.__age = age
        self.__sex = sex
        
    def set_work_experience(self, time_area: Text, company: Text) -> None:
        """
        设置工作经历
        """
        self.__time_area = time_area
        self.__company = company
        
    def display(self) -> None:
        """
        显示
        """
        print(self.__name, self.__age, self.__sex)
        print("工作经历:", self.__time_area, self.__company)
        
# 客户端代码(直接赋值,即引用)

if __name__ == "__main__":
    
    resume_a = Resume("cai")
    resume_a.set_personal_info("male", 25)
    resume_a.set_work_experience("1990-2002", "xx")
    
    resume_b = resume_a
    resume_b.set_work_experience("1993-2012", "yy")
    
    resume_c = resume_a
    resume_c.set_work_experience("1949-2000", "zz")
    
    resume_a.display()
    resume_b.display()
    resume_c.display()

cai 25 male
工作经历: 1949-2000 zz
cai 25 male
工作经历: 1949-2000 zz
cai 25 male
工作经历: 1949-2000 zz
# 客户端代码(浅复制)

if __name__ == "__main__":
    
    resume_a = Resume("cai")
    resume_a.set_personal_info("male", 25)
    resume_a.set_work_experience("1990-2002", "xx")
    
    resume_b = copy(resume_a)
    resume_b.set_work_experience("1993-2012", "yy")
    
    resume_c = copy(resume_a)
    resume_c.set_work_experience("1949-2000", "zz")
    
    resume_a.display()
    resume_b.display()
    resume_c.display()

cai 25 male
工作经历: 1990-2002 xx
cai 25 male
工作经历: 1993-2012 yy
cai 25 male
工作经历: 1949-2000 zz

一般在初始化的信息不发生变化的情况下,克隆是最好的方法,不用重新初始化对象,而是动态地获得对象运行时的状态。这既隐藏了对象创建的细节,又能极大提高性能(如果构造函数极其耗时)

浅复制与深复制

MemberwiseClone()方法:如果字段是值类型的,则对该字段执行逐位复制;如果字段是引用类型,则复制引用但不复制引用的对象。因此,原始对象及其复本引用同一对象。

浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。

深复制:把要复制的对象所引用的对象都复制一遍,把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

浅复制与深复制示例

任务:简历复制

浅复制

在这里插入图片描述

from abc import ABC, abstractmethod
# 复制接口
class ICloneable(ABC):
    
    @abstractmethod
    def clone(self) -> object:
        pass
    
# 工作经历类

class WorkExperience(object):
    
    def __init__(self) -> None:
        self.__work_date = None
        self.__company = None
        
    @property
    def work_date(self) -> Text:
        return self.__work_date
    @work_date.setter
    def work_date(self, work_date: Text) -> None:
        self.__work_date = work_date
        
    @property
    def company(self) -> Text:
        return self.__company
    @company.setter
    def company(self, company: Text) -> None:
        self.__company = company
        
# 简历类

class Resume(ICloneable):
    
    def __init__(self, name: Text) -> None:
        self.__name = name
        self.__age = None
        self.__sex = None
        self.__work = WorkExperience()
        
    def set_personal_info(self, sex: Text, age: int) -> None:
        """
        设置个人信息
        """
        self.__age = age
        self.__sex = sex
        
    def set_work_experience(self, time_area: Text, company: Text) -> None:
        """
        设置工作经历
        """
        self.__work.work_date = time_area
        self.__work.company = company
        
    def clone(self) -> Resume:
        return copy(self)
        
    def display(self) -> None:
        """
        显示
        """
        print(self.__name, self.__age, self.__sex)
        print("工作经历:", self.__work.work_date, self.__work.company)
        
# 客户端代码(浅复制)

if __name__ == "__main__":
    
    resume_a = Resume("cai")
    resume_a.set_personal_info("male", 25)
    resume_a.set_work_experience("1990-2002", "xx")
    
    resume_b = resume_a.clone()
    resume_b.set_work_experience("1993-2012", "yy")
    
    resume_c = resume_a.clone()
    resume_c.set_work_experience("1949-2000", "zz")
    
    resume_a.display()
    resume_b.display()
    resume_c.display()

cai 25 male
工作经历: 1949-2000 zz
cai 25 male
工作经历: 1949-2000 zz
cai 25 male
工作经历: 1949-2000 zz

深复制

在这里插入图片描述

# 工作经历类

class WorkExperience(ICloneable):
    
    def __init__(self) -> None:
        self.__work_date = None
        self.__company = None
        
    def clone(self) -> object:
        return copy(self)
    
    @property
    def work_date(self) -> Text:
        return self.__work_date
    @work_date.setter
    def work_date(self, work_date: Text) -> None:
        self.__work_date = work_date
        
    @property
    def company(self) -> Text:
        return self.__company
    @company.setter
    def company(self, company: Text) -> None:
        self.__company = company
        
# 简历类

class Resume(ICloneable):
    
    def __init__(self, name: Text=None) -> None:
        self.__name = name
        self.__age = None
        self.__sex = None
        self.__work = WorkExperience()
        
    def set_personal_info(self, sex: Text, age: int) -> None:
        """
        设置个人信息
        """
        self.__age = age
        self.__sex = sex
        
    def set_work_experience(self, time_area: Text, company: Text) -> None:
        """
        设置工作经历
        """
        self.__work.work_date = time_area
        self.__work.company = company
        
    def clone(self) -> object:
        obj = Resume()
        obj.__work = self.__work.clone()
        obj.__name = self.__name
        obj.__age = self.__age
        obj.__sex = self.__sex
        return obj
        
    def display(self) -> None:
        """
        显示
        """
        print(self.__name, self.__age, self.__sex)
        print("工作经历:", self.__work.work_date, self.__work.company)
        
# 客户端代码(深复制)

if __name__ == "__main__":
    
    resume_a = Resume("cai")
    resume_a.set_personal_info("male", 25)
    resume_a.set_work_experience("1990-2002", "xx")
    
    resume_b = resume_a.clone()
    resume_b.set_work_experience("1993-2012", "yy")
    
    resume_c = resume_a.clone()
    resume_c.set_work_experience("1949-2000", "zz")
    
    resume_a.display()
    resume_b.display()
    resume_c.display()

cai 25 male
工作经历: 1990-2002 xx
cai 25 male
工作经历: 1993-2012 yy
cai 25 male
工作经历: 1949-2000 zz

猜你喜欢

转载自blog.csdn.net/zhaoyin214/article/details/105788051
今日推荐