原型模式--android开发模式

1、定义
java

用原型实例指定建立对象的种类,并经过拷贝这些原型建立新的对象。android

2、理解定义编程

举例说明:ide

一、定于一个模型函数

public class Person{    

 private String name;   
 private int age;    
 private double height;    
 private double weight;    
 public Person(){

    }    
 public String getName() {        return name;
    }    
 public void setName(String name) {        this.name = name;
    }    
 public int getAge() {        return age;
    }    
 public void setAge(int age) {        this.age = age;
    }    
 public double getHeight() {        return height;
    }    
 public void setHeight(double height) {        this.height = height;
    }    
 public double getWeight() {        return weight;
    }    
 public void setWeight(double weight) {        this.weight = weight;
    }

    @Override    
 public String toString() {        
 return "Person{" +                
 "name='" + name + '\'' +               
  ", age=" + age +                
  ", height=" + height +                
  ", weight=" + weight +                
  '}';
    }
}

要实现原型模式,只须要按照下面的几个步骤去实现便可。this

二、实现Cloneable接口spa

public class Person implements Cloneable{}

三、重写Object的clone方法code

     @Override
    public Object clone(){
        Person person=null;        
     try {
            person=(Person)super.clone();
            person.name=this.name;
            person.weight=this.weight;
            person.height=this.height;
            person.age=this.age;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }        return person;
    }

四、testorm

public class Main {    public static void main(String [] args){
        Person p=new Person();
        p.setAge(18);
        p.setName("张三");
        p.setHeight(178);
        p.setWeight(65);
        System.out.println(p);

        Person p1= (Person) p.clone();
        System.out.println(p1);

        p1.setName("李四");
        System.out.println(p);
        System.out.println(p1);
    }
}

五、结果显示对象

Person{name=’张三’, age=18, height=178.0, weight=65.0} 
Person{name=’张三’, age=18, height=178.0, weight=65.0} 
Person{name=’张三’, age=18, height=178.0, weight=65.0} 
Person{name=’李四’, age=18, height=178.0, weight=65.0}

3、应用场景

一、理解

        一个对象须要提供给其余对象访问,并且各个调用者可能都须要修改其值时,能够考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

二、思考

试想一下,两个不一样的人,除了姓名不同,其余三个属性都同样,用原型模式进行拷贝就会显得异常简单,这也是原型模式的应用场景之一。

三、应用

可是假设Person类里还有一个属性叫兴趣爱好,是一个List集合,就像这样子

private ArrayList<String> hobbies=new ArrayList<String>();    
    public ArrayList<String> getHobbies() {        
    return hobbies;
    }    

    public void setHobbies(ArrayList<String> hobbies) {        
    this.hobbies = hobbies;
    }

在进行拷贝的时候要格外注意,若是你直接按以前的代码那样拷贝

    @Override
    public Object clone(){
        Person person=null;        try {
            person=(Person)super.clone();
            person.name=this.name;
            person.weight=this.weight;
            person.height=this.height;
            person.age=this.age;
            person.hobbies=this.hobbies;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }        return person;
    }


test:

public class Main {
    public static void main(String [] args){
        Person p=new Person();
        p.setAge(18);
        p.setName("张三");
        p.setHeight(178);
        p.setWeight(65);
        ArrayList <String> hobbies=new ArrayList<String>();
        hobbies.add("篮球");
        hobbies.add("编程");
        hobbies.add("长跑");
        p.setHobbies(hobbies);
        System.out.println(p);

        Person p1= (Person) p.clone();
        System.out.println(p1);

        p1.setName("李四");
        p1.getHobbies().add("游泳");
        System.out.println(p);
        System.out.println(p1);
    }
}

结果:

Person{name=’张三’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑]} 
Person{name=’张三’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑]} 
Person{name=’张三’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑, 游泳]} 
Person{name=’李四’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑, 游泳]}

观察:

    你会发现原来的对象的hobby也发生了变换。

    其实致使这个问题的本质缘由是咱们只进行了浅拷贝,也就是只拷贝了引用,最终两个对象指向的引用是同一个,一个发生变化另外一个也会发生变换,显然解决方法就是使用深拷贝

     @Override
    public Object clone(){
        Person person=null;        try {
            person=(Person)super.clone();
            person.name=this.name;
            person.weight=this.weight;
            person.height=this.height;
            person.age=this.age;

            person.hobbies=(ArrayList<String>)this.hobbies.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }        return person;
    }

结果说明:

注意person.hobbies=(ArrayList)this.hobbies.clone();,再也不是直接引用而是进行了一份拷贝。再运行一下,就会发现原来的对象不会再发生变化了。

Person{name=’张三’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑]} 
Person{name=’张三’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑]} 
Person{name=’张三’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑]} 
Person{name=’李四’, age=18, height=178.0, weight=65.0, hobbies=[篮球, 编程, 长跑, 游泳]}

4、原型模式其余相关

一、经常使用写法

  • 在clone函数里调用构造函数,构造函数的入参是该类对象。

@Override
    public Object clone(){        return new Person(this);
    }

  • 在构造函数中完成拷贝逻辑

public Person(Person person){        
    this.name=person.name;       
    this.weight=person.weight;       
    this.height=person.height;        
    this.age=person.age;        
    this.hobbies= new ArrayList<String>(hobbies);
    }

二、android 源代码中的应用

    先看Bundle类,该类实现了Cloneable接口

    

public Object clone() {    
    return new Bundle(this);
} 
    public Bundle(Bundle b) {    super(b);

    mHasFds = b.mHasFds;
    mFdsKnown = b.mFdsKnown;
}
相关文章
相关标签/搜索