首页 > 代码库 > 《大话设计模式》ruby版代码:原型模式
《大话设计模式》ruby版代码:原型模式
需求:
实现一个简历类,必须要有姓名,可以设置性别和年龄,可以设置工作经历。最终需要三个简历
初步实现:
# -*- encoding: utf-8 -*-#简历类class Resume attr_accessor :name, :sex, :age, :time_area, :company def initialize(name) @name = name end def set_personal_info(sex, age) @sex = sex @age = age end def set_work_experience(time_area, company) @time_area = time_area @company = company end def display puts "#{name} #{age} #{sex}" puts "工作经历 #{time_area} #{company}" endendresume1 = Resume.new(‘大鸟‘)resume1.set_personal_info(‘男‘, ‘29‘)resume1.set_work_experience(‘1998-2000‘, ‘xx公司‘)resume2 = Resume.new(‘大鸟‘)resume2.set_personal_info(‘男‘, ‘29‘)resume2.set_work_experience(‘2000-2002‘, ‘xx公司‘)resume3 = Resume.new(‘大鸟‘)resume3.set_personal_info(‘男‘, ‘29‘)resume3.set_work_experience(‘2002-2004‘, ‘xx公司‘)resume1.displayresume2.displayresume3.display
存在的问题:如果要20份,就需要实例化20次。如果改一个年龄,也要改20次,这样写很麻烦。
resume1 = Resume.new(‘大鸟‘)resume1.set_personal_info(‘男‘, ‘29‘)resume1.set_work_experience(‘1998-2000‘, ‘xx公司‘)resume2 = resume1resume2.set_personal_info(‘男‘, ‘29‘)resume2.set_work_experience(‘2000-2002‘, ‘xx公司‘)resume3 = resume1resume3.set_personal_info(‘男‘, ‘29‘)resume3.set_work_experience(‘2002-2004‘, ‘xx公司‘)resume1.displayresume2.displayresume3.display
对于最终一部分,简单将resume1赋值给resume2和resume3是不对的,因为这样仅仅是传引用,而没有传值,resume1、resume2和resume3指向的是同一个地址。
原型模式:从一个对象再创建另一个可定制的对象,而且不需要知道任何创建的细节。
# -*- encoding: utf-8 -*-#简历类class Resume attr_accessor :name, :sex, :age, :time_area, :company def initialize(name) @name = name end def set_personal_info(sex, age) @sex = sex @age = age end def set_work_experience(time_area, company) @time_area = time_area @company = company end def display puts "#{name} #{age} #{sex}" puts "工作经历 #{time_area} #{company}" end def self_clone self.clone endendresume1 = Resume.new(‘大鸟‘)resume1.set_personal_info(‘男‘, ‘29‘)resume1.set_work_experience(‘1998-2000‘, ‘xx公司‘)resume2 = resume1.self_cloneresume2.set_personal_info(‘男‘, ‘28‘)resume3 = resume1.self_cloneresume3.set_personal_info(‘男‘, ‘29‘)resume3.set_work_experience(‘2002-2004‘, ‘xx公司‘)resume1.displayresume2.displayresume3.display
Resume类中增加了self_clone方法,resume2和resume3来自resume1.self_clone,这样只需要实例化一次,修改值也比较方便。
存在一个问题,如果工作经验复杂一些,需要一个类来实现会怎么样
# -*- encoding: utf-8 -*-#简历类class Resume attr_accessor :name, :sex, :age, :work_experience def initialize(name) @name = name @work_experience = WorkExperience.new end def set_personal_info(sex, age) @sex = sex @age = age end def set_work_experience(time_area, company) @work_experience.time_area = time_area @work_experience.company = company end def display puts "#{name} #{age} #{sex}" puts "工作经历 #{@work_experience.time_area} #{@work_experience.company}" end def self_clone self.clone endendclass WorkExperience attr_accessor :time_area, :companyendresume1 = Resume.new(‘大鸟‘)resume1.set_personal_info(‘男‘, ‘29‘)resume1.set_work_experience(‘1998-2000‘, ‘xx公司‘)resume2 = resume1.self_cloneresume2.set_personal_info(‘男‘, ‘30‘)resume2.set_work_experience(‘2000-2002‘, ‘xx公司‘)resume3 =resume1.self_cloneresume3.set_personal_info(‘男‘, ‘31‘)resume3.set_work_experience(‘2002-2004‘, ‘xx公司‘)resume1.displayresume2.displayresume3.display#大鸟 29 男#工作经历 2002-2004 xx公司#大鸟 30 男#工作经历 2002-2004 xx公司#大鸟 31 男#工作经历 2002-2004 xx公司
可以看出三个简历的工作经历是相同的,因为对于对象,clone的只是对象的引用,三个resume用到的是同一个工作经历。
浅拷贝与深拷贝
浅拷贝:obj.clone
深拷贝:Marshal.load(Marshal.dump(obj)),Marshal.dump(obj)是把obj递归地写入字符串或文件,Marshal.load生成一个与原对象状态相同的对象。其实是曲线实现了深拷贝。
下面是手动进行的深拷贝。
# -*- encoding: utf-8 -*-#简历类class Resume attr_accessor :name, :sex, :age, :work_experience def initialize(name) @name = name @work_experience = WorkExperience.new end def set_personal_info(sex, age) @sex = sex @age = age end def set_work_experience(time_area, company) @work_experience.time_area = time_area @work_experience.company = company end def display puts "#{name} #{age} #{sex}" puts "工作经历 #{@work_experience.time_area} #{@work_experience.company}" end def self_clone obj = self.clone obj.work_experience = self.work_experience.self_clone return obj endendclass WorkExperience attr_accessor :time_area, :company def self_clone self.clone endendresume1 = Resume.new(‘大鸟‘)resume1.set_personal_info(‘男‘, ‘29‘)resume1.set_work_experience(‘1998-2000‘, ‘xx公司‘)resume2 = resume1.self_cloneresume2.set_personal_info(‘男‘, ‘30‘)resume2.set_work_experience(‘2000-2002‘, ‘xx公司‘)resume3 =resume1.self_cloneresume3.set_personal_info(‘男‘, ‘31‘)resume3.set_work_experience(‘2002-2004‘, ‘xx公司‘)resume1.displayresume2.displayresume3.display#大鸟 29 男#工作经历 1998-2000 xx公司#大鸟 30 男#工作经历 2000-2002 xx公司#大鸟 31 男#工作经历 2002-2004 xx公司
《大话设计模式》ruby版代码:原型模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。