• Chapter 9 原型模式


    原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 简单的说就是clone一个对象实例。使得clone出来的copy和原有的对象一模一样。 插一个简单使用clone的例子,如果一个对象内部有可变对象实例的话,public API不应该直接返回该对象的引用,以防调用方的code改变该对象的内部状态。这个时候可以返回该对象的clone。 一般而言,我们要的clone应该是这样的。copy和原型的内容一样,但是又是彼此隔离的。即在clone之后,改变其中一个不影响另外一个。 

    原型模式分为浅复制和深复制,其中浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

    class User {
    	String name;
    	int age;
    }
    class Account implements Cloneable {
    	User user;
    	long balance;
    	@Override
    	public Object clone() throws CloneNotSupportedException {
    		return super.clone();
    	}
    }

    我们之所以要深copy,是因为默认的实现提供的浅copy不是隔离的,换言之,改变copy的东西,会影响到原型的内部。比如例子中,改变copy的user的name,影响了原型。特别注意的是string是一种拥有值类型特点的特殊引用类型。
    class User implements Cloneable {
    	String name;
    	int age;
    	@Override
    	public User clone() throws CloneNotSupportedException {
    		return (User) super.clone();
    	}
    }
    class Account implements Cloneable {
    	User user;
    	long balance;
    	@Override
    	public Account clone() throws CloneNotSupportedException {
    		Account account = null;
    		account = (Account) super.clone();
    		if (user != null) {
    			account.user = user.clone();
    		}
    		return account;
    	}
    }

    再来贴2个实例代码

    一、浅复制:

    package xiao;

     

    class WorkExp{

    private String workDate;

    private String company;

    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;

    }

    }

    class Resume implements Cloneable{

    private String name;

    private String sex;

    private String age;

    private WorkExp work;

    public Resume(String name){

    this.name = name;

    work = new WorkExp();

    }

    public void setPerInfo(String sex,String age){

    this.sex = sex;

    this.age = age;

    }

    public void setWorkExper(String timeArea,String company){

    work.setWorkDate(timeArea);

    work.setCompany(company);

    }

    public void display(){

    System.out.println(this.name+" "+this.sex+" "+this.age);

    System.out.println(work.getWorkDate()+" "+work.getCompany());

    }

    public Object clone() throws CloneNotSupportedException {

    return super.clone();

    }

    }

    public class Hello {

     

    public static void main(String[] args) throws Exception{

    Resume a = new Resume("big bird");

    a.setPerInfo("male", "20");

    a.setWorkExper("1998-2006", "IT company");

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

    b.setWorkExper("1998-2004", "YY company");

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

    c.setPerInfo("female", "22");

    c.setWorkExper("1998-2004", "ZZ company");

    a.display();

    b.display();

    c.display();

    }

    }

    输出:

    big bird male 20
    1998-2006 ZZ company
    big bird male 20
    1998-2004 ZZ company
    big bird female 22
    1998-2004 ZZ company

    二、深复制:

    
    

    package xiao;

    
    

    class WorkExp implements Cloneable{
    private String workDate;
    private String company;
    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 WorkExp clone() throws CloneNotSupportedException {
    return (WorkExp)super.clone();
    }
    }
    class Resume implements Cloneable{
    private String name;
    private String sex;
    private String age;
    private WorkExp work;
    public Resume(String name){
    this.name = name;
    work = new WorkExp();
    }
    public void setPerInfo(String sex,String age){
    this.sex = sex;
    this.age = age;
    }
    public void setWorkExper(String timeArea,String company){
    work.setWorkDate(timeArea);
    work.setCompany(company);
    }
    public void display(){
    System.out.println(this.name+" "+this.sex+" "+this.age);
    System.out.println(work.getWorkDate()+" "+work.getCompany());
    }
    public Resume clone() throws CloneNotSupportedException {
    Resume resume = null;
    resume = (Resume) super.clone();
    if(work != null){
    resume.work = work.clone();
    }
    return resume;
    }
    }
    public class Hello {

    
    

    public static void main(String[] args) throws Exception{
    Resume a = new Resume("big bird");
    a.setPerInfo("male", "20");
    a.setWorkExper("1998-2006", "IT company");
    Resume b = (Resume)a.clone();
    b.setWorkExper("1998-2004", "YY company");
    Resume c = (Resume)a.clone();
    c.setPerInfo("female", "22");
    c.setWorkExper("1998-2004", "ZZ company");
    a.display();
    b.display();
    c.display();
    }
    }

    输出:

    big bird male 20
    1998-2006 IT company
    big bird male 20
    1998-2004 YY company
    big bird female 22
    1998-2004 ZZ company

  • 相关阅读:
    VIM快捷键(转)
    VIM中文乱码
    vsftpd.conf 联机手册
    keepalived nginx 主备配置
    Keepalived 主备配置
    Linux centos7 安装 keepalived-2.0.6
    Linux centos开机执行JAR Shell脚本
    Nginx负载均衡案例
    Windows虚拟机安装Linux系统
    Linux centos7 redis安装教程
  • 原文地址:https://www.cnblogs.com/tuifeideyouran/p/3733905.html
Copyright © 2020-2023  润新知