软件发布| 专题库| 优优资讯| 苹果专区| 安卓专区| 软件下载| 首页
优优资讯 电脑教程 安卓教程 安卓攻略 苹果教程 苹果攻略 新闻资讯

学习Android设计模式--Prototype原型模式

时间:2015-07-22 来源:本站整理 我要评论

  一、什么是原型模式
 
  Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。
 
  结合Android学设计模式--原型模式(Prototype)
 
  二、原型模式的特点
 
  由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。
 
  目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
 
  根据对象克隆深度层次的不同,有浅度克隆深度克隆
 
  三、原型模式应用场景
 
  - 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗;
 
  通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
 
  一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
 
  在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。
 
  希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互不影响)。
 
  隐藏克隆操作的细节。很多时候,对对象本身的克隆需要涉及到类本身的数据细节。
 
  如,有一个Person类
 
  public class Person {
  private String name;
  private String gender;
  private int age;
  public String getName() {
  return name;
  }
  public void setName(String name) {
  this.name = name;
  }
  public String getGender() {
  return gender;
  }
  public void setGender(String gender) {
  this.gender = gender;
  }
  public int getAge() {
  return age;
  }
  public void setAge(int age) {
  this.age = age;
  }
  }
 
  创建一个Person对象
 
  Person person1 = new Person();
  person1.setName("Jack");
  person1.setGender("男");
  person1.setAge(18);
 
  当下次想再次创建一个person对象时,
 
  Person person2 = new Person();
  person2.setName("John");
  person2.setGender("男");
  person2.setAge(18);
 
  person1与person2对象只有name不同,其他都相同,这个时候我们就可以使用原型模式,一般我们会提供一个clone方法,克隆不同于引用.
 
  我们在Person类中添加clone方法,返回一个克隆的person对象
 
  public Person clone() {
  try {
  Person person  = (Person)super.clone();
  return  person;
  } catch (CloneNotSupportedException e) {
  e.printStackTrace();
  return null;
  }
  }
 
  注意Person类要实现Cloneable接口
 
  public static void main(String[] args) {
  Person person1 = new Person();
  person1.setName("Jack");
  person1.setGender("男");
  person1.setAge(18);
  Person person2 = person1.clone();
  System.out.println("person1---name:"+person1.getName());
  person2.setName("John");
  System.out.println("person1---name:"+person1.getName());
  System.out.println("person1---name:"+person2.getName());
  }
 
  输出结果为:
 
  person1—name:Jack
  person1—name:Jack
  person2—name:John
 
  现在我们给Person添加hobbies字段
 
  private List<String> hobbies;
  public static void main(String[] args) {
  ArrayList<String> hobbies = new ArrayList<>();
  hobbies.add("音乐");
  hobbies.add("跑步");
  Person person1 = new Person();
  person1.setName("Jack");
  person1.setGender("男");
  person1.setAge(18);
  person1.setHobbies(hobbies);
  Person person2 = person1.clone();
  System.out.println("person2---hobbies:"+person2.getHobbies().toString());
  System.out.println("person1---hobbies:"+person1.getHobbies().toString());
  hobbies.add("打球");
  System.out.println("person2---hobbies:"+person2.getHobbies().toString());
  System.out.println("person1---hobbies:"+person1.getHobbies().toString());
  }
 
  输入结果
 
  person2---hobbies:[音乐, 跑步]
  person1---hobbies:[音乐, 跑步]
  person2---hobbies:[音乐, 跑步, 打球]
  person1---hobbies:[音乐, 跑步, 打球]
 
  我们修改了person1的hobbies字段,person2的也跟着该变了,这就是浅度克隆
 
  什么是深度克隆呢?
 
  修改clone方法
 
  public Person clone(){
  try {
  Person person  = (Person)super.clone();
  ArrayList<String> newHobby = new ArrayList<String>();
  for(String hobby : this.getHobbies()) {
  newHobby.add(hobby);
  }
  person.setHobbies(newHobby);
  return person;
  } catch (CloneNotSupportedException e) {
  e.printStackTrace();
  return null;
  }
  }
 
  再次运行
 
  person2---hobbies:[音乐, 跑步]
  person1---hobbies:[音乐, 跑步]
  person2---hobbies:[音乐, 跑步]
  person1---hobbies:[音乐, 跑步, 打球]
  Android中的SparseArray类使用了原型模式,SparseArray类用来代替HashMap
  public class SparseArray<E> implements Cloneable {
  ...
  }
 
  clone方法,
 
  @Override
  @SuppressWarnings("unchecked")
  public SparseArray<E> clone() {
  SparseArray<E> clone = null;
  try {
  clone = (SparseArray<E>) super.clone();
  clone.mKeys = mKeys.clone(); //同时需要深度克隆
  clone.mValues = mValues.clone();//同时需要深度克隆
  } catch (CloneNotSupportedException cnse) {
  /* ignore */
  }
  return clone;
  }
 
  结合上面的应用场景理解一下SparseArray类为什么使用原型模式。


 

用户评论

(已有0条评论)
表情
注:您的评论需要经过审核才能显示哦,请文明发言!
还没有评论,快来抢沙发吧!
快速检索
0-9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z