java设计模式--原型模式

Posted yimengyizhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java设计模式--原型模式相关的知识,希望对你有一定的参考价值。

 

  原型模式:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。通俗来说就是克隆一个对象,而且不用知道创建对象的细节,然后对这个对象进行自定义操作。首先,我们先看一下下面的这个例子。

//公司类
public
class Company private String level; private Long workYears; public String getLevel() return level; public void setLevel(String level) this.level = level; public Long getWorkYears() return workYears; public void setWorkYears(Long workYears) this.workYears = workYears; //实现Cloneable接口的People类(原型实例) public class People implements Cloneable private String name; private Long age; private String gender; //公司属性,没有实现Cloneable接口 private Company company; public String getName() return name; public People() //在初始People类的同时创建company实例 this.company = new Company(); public void setName(String name) this.name = name; public Long getAge() return age; public void setAge(Long age) this.age = age; public String getGender() return gender; public void setGender(String gender) this.gender = gender; public Company getCompany() return company; public void setCompany(String level,Long workYears) //给company的属性赋值 this.company.setLevel(level); this.company.setWorkYears(workYears); //Clone()方法,clone people类 public Object Clone() Object clone = null; try clone = super.clone(); catch (CloneNotSupportedException e) e.printStackTrace(); return (People) clone; public void show() System.out.println("name:" + name + ",age:" + age + ",gender" + gender); System.out.println("name:" + name + ",level:" + company.getLevel() + ",workYears:" + company.getWorkYears()); public class Test public static void main(String[] args)
     //原型实例对象 People people
= new People(); people.setName("zhangsan"); people.setAge(23L); people.setGender("man"); people.setCompany("A7",3L); //克隆对象1,修改age,gender属性 People clone1 = (People)people.Clone(); clone1.setAge(25L); clone1.setGender("woman"); //克隆对象2,修改age,company属性 People clone2 = (People)people.Clone(); clone2.setAge(26L); clone2.setCompany("A8",4L); people.show(); clone1.show(); clone2.show();

得到的结果为:

name:zhangsan,age:23,genderman
name:zhangsan,level:A8,workYears:4

name:zhangsan,age:25,genderwoman
name:zhangsan,level:A8,workYears:4

name:zhangsan,age:26,genderman
name:zhangsan,level:A8,workYears:4

  我们可以看到值类型的字段都会拷贝一份新的出来,对他们修改也不会对被克隆对象的值进行修改,但是如果字段是引用类型,则拷贝引用,但不复制引用的对象,这样的话如果我们对引用类型的字段company进行修改就会导致显示的永远是最后一次修改的值,因为拷贝出的三个引用指向一个对象,这就是浅拷贝。

 

  那么如果我们想把引用类型的字段也拷贝一份出来呢,那么我们就需要把引用类型也实现Cloneable接口,并重写Clone()方法,并且把引用类型的属性再拷贝一遍,代码如下:

public class Company implements Cloneable

    private String level;
    private Long workYears;

    public String getLevel() 
        return level;
    

    public void setLevel(String level) 
        this.level = level;
    

    public Long getWorkYears() 
        return workYears;
    

    public void setWorkYears(Long workYears) 
        this.workYears = workYears;
    

    //Clone()方法,clone company类
    public Object Clone() 
        Object clone = null;
        try 
            clone = super.clone();
         catch (CloneNotSupportedException e) 
            e.printStackTrace();
        
        return clone;
    


//实现Cloneable接口的People类
public class People implements Cloneable 
    private String name;
    private Long age;
    private String gender;
    private Company company;

    public String getName() 
        return name;
    

    public void setName(String name) 

        this.name = name;
    

    public People() 
        //在给People赋name的同时创建company实例
        this.company = new Company();
    

    public People(Company company) 
        this.company = (Company) company.Clone();
    

    public Long getAge() 
        return age;
    

    public void setAge(Long age) 
        this.age = age;
    

    public String getGender() 
        return gender;
    

    public void setGender(String gender) 
        this.gender = gender;
    

    public Company getCompany() 
        return company;
    

    public void setCompany(String level, Long workYears) 
        //给company的属性赋值
        this.company.setLevel(level);
        this.company.setWorkYears(workYears);
    

    //Clone()方法,clone people类
    public Object Clone() 
        Object object = null;
        try 
            object = super.clone();
        //把引用类型company再拷贝一遍 ((People)object).company
= (Company) this.company.Clone(); catch (CloneNotSupportedException exception) throw new RuntimeException(exception); return object; public void show() System.out.println("name:" + name + ",age:" + age + ",gender" + gender); System.out.println("name:" + name + ",level:" + company.getLevel() + ",workYears:" + company.getWorkYears());

结果为:

name:zhangsan,age:23,genderman
name:zhangsan,level:A7,workYears:3

name:zhangsan,age:25,genderwoman
name:zhangsan,level:A7,workYears:3

name:zhangsan,age:26,genderman
name:zhangsan,level:A8,workYears:4

  我们可以看到对复制出的对象中的引用对象company赋值时,并没有改变原型对象,因为引用对象的变量指向了新的克隆出的对象,这就是深拷贝。

总结:原型模式的优点就是可以快速创建对象,比直接new一个对象再进行赋值的操作性能要好,缺点就是每个类都得实现克隆方法,当有多层引用时,需要考虑是否会造成引用死循环。

以上是关于java设计模式--原型模式的主要内容,如果未能解决你的问题,请参考以下文章

Java设计模式-原型模式

java设计模式--原型模式

Java设计模式—— 原型模式

java设计模式——原型模式

Java 原型模式(克隆模式)

Java设计模式之原型模式