zoukankan      html  css  js  c++  java
  • 大话设计模式之原型模式

    原型模式

      是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

      这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

    优点: 1、性能提高。 2、逃避构造函数的约束。

    缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。

    注意事项:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。

         浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。 

    具体实现

    原型类

    package com.chenpt.designModel.prototypeModel;
    
    import java.io.Serializable;
    
    /**
     * @Author: chenpengtao
     * @Description: 简历
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class Resume implements Cloneable,Serializable{
        private static final long serialVersionUID = 1L;
    
        private String name;
        private String sex;
        private String age;
    
        Resume(String name,String sex,String age){
            this.name=name;
            this.sex=sex;
            this.age=age;
        }
    
        /**
         * 设置个人信息
         * @param sex
         * @param age
         */
        public void setPersonInfo(String sex,String age){
            this.sex=sex;
            this.age=age;
        }
    
        //描述
        public void dispaly(){
            System.out.println("姓名:"+name+"	年龄:"+age+"	性别:"+sex);
        }
    
        public Object clone(){
            try {
                Resume resume = (Resume)super.clone();
                return resume;
            }catch (Exception e){
                return null;
            }
    
        }
    
    }
    

      客户端

    package com.chenpt.designModel.prototypeModel;
    
    /**
     * @Author: chenpengtao
     * @Description:
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class MainTest {
        public static void main(String[] args){
    
            Resume resume = new Resume("大鸟","男","25");
    
            Resume resume2 = (Resume)resume.clone();
            resume2.setPersonInfo("男","26");
    
            resume.dispaly();
            resume2.dispaly();
    
        }
    }
    //结果
    姓名:大鸟	年龄:25	性别:男
    姓名:大鸟	年龄:26	性别:男
    

     如上代码基本实现了一个原型模式示例:

    浅复制与深复制

      现在需求改了--我们需要新加入工作经历,那么修改上述代码

    新加入工作类

    package com.chenpt.designModel.prototypeModel;
    
    /**
     * @Author: chenpengtao
     * @Description: 工作经历
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class WorkExperience{
    
        private String workDate;
        private String company;
    
        public WorkExperience(String workDate,String company){
            this.workDate=workDate;
            this.company=company;
        }
    
        public WorkExperience(){}
    
        public String getWorkDate() {
            return workDate;
        }
    
        public void setWorkDate(String workDate) {
            this.workDate = workDate;
        }
    
        public String getCompany() {
            return company;
        }
    
        public void setCompany(String company) {
            this.company = company;
        }
        
    }
    

     在个人信息那边引入工作类

    package com.chenpt.designModel.prototypeModel;
    
    import java.io.Serializable;
    
    /**
     * @Author: chenpengtao
     * @Description: 简历
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class Resume implements Cloneable,Serializable{
        private static final long serialVersionUID = 1L;
    
        private String name;
        private String sex;
        private String age;
        private WorkExperience workExperience;
    
        Resume(String name,String sex,String age){
            this.name=name;
            this.sex=sex;
            this.age=age;
            this.workExperience=new WorkExperience();
        }
    
        /**
         * 设置个人信息
         * @param sex
         * @param age
         */
        public void setPersonInfo(String sex,String age){
            this.sex=sex;
            this.age=age;
        }
    
        /**
         * 设置工作经历
         * @param workDate
         * @param company
         */
        public void setWorkExperience(String workDate, String company){
            this.workExperience.setWorkDate(workDate);
            this.workExperience.setCompany(company);
        }
    
        //描述
        public void dispaly(){
            System.out.println("姓名:"+name+"	年龄:"+age+"	性别:"+sex);
            System.out.println("工作经历:"+workExperience.getWorkDate()+"	"+workExperience.getCompany());
        }
    
        public Object clone(){
            try {
                Resume resume = (Resume)super.clone();
                return resume;
            }catch (Exception e){
                return null;
            }
    
        }
    
    }
    

      客户端

    package com.chenpt.designModel.prototypeModel;
    
    /**
     * @Author: chenpengtao
     * @Description:
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class MainTest {
        public static void main(String[] args){
    
            Resume resume = new Resume("大鸟","男","25");
            resume.setWorkExperience("2015-2016","南京工作");
    
            Resume resume2 = (Resume)resume.clone();
            resume2.setPersonInfo("男","26");
            resume2.setWorkExperience("2016-2018","上海工作");
    
            resume.dispaly();
            resume2.dispaly();
    
        }
    }
    //执行结果
    姓名:大鸟	年龄:25	性别:男
    工作经历:2016-2018	上海工作
    姓名:大鸟	年龄:26	性别:男
    工作经历:2016-2018	上海工作
    

      咦!!!什么情况???怎么工作经历显示的是最后一次设置的值啊?

    不要慌  问题不大。这是由于浅表复制导致的结果,对于值类型 克隆没问题,但对于引用类型来说,就只是复制了引用,引用的对象还是原来对象的地址,所以才有上述结果,既然已经说到这了就介绍下浅复制和深复制的概念吧

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

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

    深复制演示示例

    修改工作经历实现克隆

    package com.chenpt.designModel.prototypeModel;
    
    /**
     * @Author: chenpengtao
     * @Description: 工作经历
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class WorkExperience implements Cloneable{
    
        private String workDate;
        private String company;
    
        public WorkExperience(String workDate,String company){
            this.workDate=workDate;
            this.company=company;
        }
    
        public WorkExperience(){}
    
        public String getWorkDate() {
            return workDate;
        }
    
        public void setWorkDate(String workDate) {
            this.workDate = workDate;
        }
    
        public String getCompany() {
            return company;
        }
    
        public void setCompany(String company) {
            this.company = company;
        }
    
    
        public Object clone(){
            try {
                return super.clone();
            }catch (Exception e){
                return null;
            }
    
        }
    
    }
    

     修改resume对象

    package com.chenpt.designModel.prototypeModel;
    
    import java.io.Serializable;
    
    /**
     * @Author: chenpengtao
     * @Description: 简历
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class Resume implements Cloneable,Serializable{
        private static final long serialVersionUID = 1L;
    
        private String name;
        private String sex;
        private String age;
        private WorkExperience workExperience;
    
        Resume(String name,String sex,String age){
            this.name=name;
            this.sex=sex;
            this.age=age;
            this.workExperience=new WorkExperience();
        }
    
        /**
         * 添加私有构造 克隆工作经历
         * @param workExperience
         */
        private Resume(WorkExperience workExperience){
            this.workExperience= (WorkExperience) workExperience.clone();
        }
    
        /**
         * 设置个人信息
         * @param sex
         * @param age
         */
        public void setPersonInfo(String sex,String age){
            this.sex=sex;
            this.age=age;
        }
    
        /**
         * 设置工作经历
         * @param workDate
         * @param company
         */
        public void setWorkExperience(String workDate, String company){
            this.workExperience.setWorkDate(workDate);
            this.workExperience.setCompany(company);
        }
    
        //描述
        public void dispaly(){
            System.out.println("姓名:"+name+"	年龄:"+age+"	性别:"+sex);
            System.out.println("工作经历:"+workExperience.getWorkDate()+"	"+workExperience.getCompany());
        }
    
        /**
         * 重写了克隆方法
         * @return
         */
        public Object clone(){
            try {
                Resume resume = new Resume(this.workExperience);//调用私有构造器实现工作经历克隆
                //给对象属性重新赋值--最终返回的是深复制的resume对象
                resume.name=this.name;
                resume.sex=this.sex;
                resume.age=this.age;
                return resume;
            }catch (Exception e){
                return null;
            }
    
        }
    
    }
    

      客户端

    package com.chenpt.designModel.prototypeModel;
    
    /**
     * @Author: chenpengtao
     * @Description:
     * @Date: created in 2018/8/1
     * @Modified By:
     */
    public class MainTest {
        public static void main(String[] args){
    
            Resume resume = new Resume("大鸟","男","25");
            resume.setWorkExperience("2015-2016","南京工作");
    
            Resume resume2 = (Resume)resume.clone();
            resume2.setPersonInfo("男","26");
            resume2.setWorkExperience("2016-2018","上海工作");
    
            resume.dispaly();
            resume2.dispaly();
    
        }
    }
    //执行结果
    姓名:大鸟	年龄:25	性别:男
    工作经历:2015-2016	南京工作
    姓名:大鸟	年龄:26	性别:男
    工作经历:2016-2018	上海工作
    

      

     

     

     

  • 相关阅读:
    django-rest-framework 注意事项
    Python virtualenv 使用总结篇
    python flask 基础入门
    python property
    python Numpy
    c语言学习的第四天2
    c语言学习第四天数据类型1
    学习c编程的第三天
    学习c编程的第二天
    HTTP首部及各状态码
  • 原文地址:https://www.cnblogs.com/chenpt/p/9523967.html
Copyright © 2011-2022 走看看