原型模式--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;
}
相關文章
相關標籤/搜索