zoukankan      html  css  js  c++  java
  • 设计模式(四):原型模式

    原型模式

    UML类图:

    说明:

      在Java中不需要ProtoType接口,Java自带克隆接口:Cloneable,只需ConcreteProtoType直接实现Cloneable接口,之后重写 clone()方法即可。

    优点:

      ①隐藏了新对象创建的细节,大大提高了性能,逃避了构造函数的约束。

      ②在运行期建立和删除原型。

    缺点:

      ①给类配备克隆方法,需要对类的功能进行整体考虑。对于全新的类不难,但对于已有的类不一定容易,如类中含有循环结构。

      ②必须实现Cloneable接口。

    适用范围:创建新对象成本较大,原对象的状态变化不大或占内存不大,就可以用原对象克隆。

     

    客户端:实例化原对象(new),调用此对象的clone()方法,即可得到克隆对象。 

     

      //创建原型

      Resume a = new Resume();

      a.setPersonInfo("大鸟","男","29");

      a.setWorkExperience("1998-2000","XX公司");

     

      // 克隆,并修改(不影响原型)

      Resume b = (Resume)a.clone();

      b.setPersonInfo("小菜","女","20");

      b.setWorkExperience("2008-2009","ZZ公司");

     

    一句话概括:克隆原对象

     

    Ps:重写clone()方法时,需要注意理解 “浅复制”和“深复制”

      类对象中可能包含两种属性:一种是基本类型变量,一种是引用类型变量。

        ①对于基本类型变量,复制后的新对象的此变量含有与原对象相同的值。

        ②对于引用类型变量,可分为“浅复制”和“深复制”:

          浅复制:复制后的新对象的引用类型变量仍然指向原对象

          深复制:复制后的新对象的引用类型变量指向了复制后的新对象,而不是原对象

          深复制要深入多少层的引用,要提前考虑,比较复杂,要防止出现循环引用的问题。

     

    附:原对象类,包含重写的clone()方法

    public class Resume implements Cloneable {
    
        private String name; 
        private String age;
        private WorkExperience work; //工作经历
    
        public Resume(){
            this.work = new WorkExperience();
        }
    
        //设置个人信息
        public void setPersonInfo(String name,String age){
            this.name = name;this.age = age;
        }
        //填充工作经历
        public void setWorkExperience(String workDate, String company){
            this.work.setWorkDate(workDate);  //工作时间
            this.work.setCompany(company);   //所在公司
        }
        //显示
        public void display(){
            System.out.println(this.name+","+this.sex+","+this.age);
            System.out.println(this.work.getWorkDate()+","+this.work.getCompany());
        }
    
    //私有构造函数,仅深复制clone()使用,用于克隆“工作经历”数据 private Resume(WorkExperience work){ this.work = work.clone();//当深复制引用时,克隆已有的WorkExperience对象(WorkExperience类中也重写了的clone()方法) } //深复制,为新WorkExperience引用类型变量开辟新空间 @Override public Object clone() { //完全新创建一个类对象 Resume r = new Resume(this.work); //调用私有构造函数,让“工作经历”克隆完成 r.name = this.name; r.age = this.age; return r; }
    //浅复制(新旧引用类型变量的地址会指向同一个) // @Override // public Resume clone(){ // Object object = null; // try { // object = super.clone(); // } catch (CloneNotSupportedException e) { // e.printStackTrace(); // } // return (Resume)object; // } }
    public class WorkExperience implements Cloneable {
        private String workDate;
        private String company;
    
        //getter、setter 略
    
        @Override
        public WorkExperience clone(){
            Object object = null;
            try {
                object = super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return (WorkExperience)object;
        }
    }
  • 相关阅读:
    [机器学习] k-近邻算法(knn)
    [博客] 博客园侧边栏公告设置访问人数及访客国家来源
    Ubuntu搭建hugo博客
    CodeForces
    Javaweb开发入门___1
    JDBC的学习
    Mysql的学习7___权限和数据库设计
    Mysql的学习6____事物,索引,备份,视图,触发器
    Mysql的学习5___Mysql常用函数,聚合函数,sql编程
    Mysql的学习3___数据的管理,主键 外键 以及增改删
  • 原文地址:https://www.cnblogs.com/shushengyou/p/9805451.html
Copyright © 2011-2022 走看看