zoukankan      html  css  js  c++  java
  • 《大话设计模式》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}"
        end
    
    end
    
    resume1 = 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.display
    resume2.display
    resume3.display

    存在的问题:如果要20份,就需要实例化20次。如果改一个年龄,也要改20次,这样写很麻烦。

    resume1 = Resume.new('大鸟')
    resume1.set_personal_info('', '29')
    resume1.set_work_experience('1998-2000', 'xx公司')
    
    resume2 = resume1
    resume2.set_personal_info('', '29')
    resume2.set_work_experience('2000-2002', 'xx公司')
    
    resume3 = resume1
    resume3.set_personal_info('', '29')
    resume3.set_work_experience('2002-2004', 'xx公司')
    
    resume1.display
    resume2.display
    resume3.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
        end
    
    end
    
    resume1 = Resume.new('大鸟')
    resume1.set_personal_info('', '29')
    resume1.set_work_experience('1998-2000', 'xx公司')
    
    resume2 = resume1.self_clone
    resume2.set_personal_info('', '28')
    
    resume3 = resume1.self_clone
    resume3.set_personal_info('', '29')
    resume3.set_work_experience('2002-2004', 'xx公司')
    
    resume1.display
    resume2.display
    resume3.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
        end
    
    end
    
    class WorkExperience
        attr_accessor :time_area, :company
    end
    
    resume1 = Resume.new('大鸟')
    resume1.set_personal_info('', '29')
    resume1.set_work_experience('1998-2000', 'xx公司')
    
    resume2 = resume1.self_clone
    resume2.set_personal_info('', '30')
    resume2.set_work_experience('2000-2002', 'xx公司')
    
    resume3 =resume1.self_clone
    resume3.set_personal_info('', '31')
    resume3.set_work_experience('2002-2004', 'xx公司')
    
    resume1.display
    resume2.display
    resume3.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
        end
    
    end
    
    class WorkExperience
        attr_accessor :time_area, :company
        def self_clone
            self.clone
        end
    end
    
    resume1 = Resume.new('大鸟')
    resume1.set_personal_info('', '29')
    resume1.set_work_experience('1998-2000', 'xx公司')
    
    resume2 = resume1.self_clone
    resume2.set_personal_info('', '30')
    resume2.set_work_experience('2000-2002', 'xx公司')
    
    resume3 =resume1.self_clone
    resume3.set_personal_info('', '31')
    resume3.set_work_experience('2002-2004', 'xx公司')
    
    resume1.display
    resume2.display
    resume3.display
    
    #大鸟 29 男
    #工作经历 1998-2000 xx公司
    #大鸟 30 男
    #工作经历 2000-2002 xx公司
    #大鸟 31 男
    #工作经历 2002-2004 xx公司
  • 相关阅读:
    神秘现象?多种情况比较
    [备忘]C++BUILDER的文件操作
    缘起
    [备忘]一个二维数组的冒泡排序
    无可救药地买入NDSL
    递归的实质
    [网游计划第九、十天]能力有限,做些小品
    大学有救
    struts2+convertion实现struts.xml的零配置
    BSD下的超级终端
  • 原文地址:https://www.cnblogs.com/fanxiaopeng/p/4209485.html
Copyright © 2011-2022 走看看