原型模式

来源:互联网 发布:mysql 表空间查看 编辑:程序博客网 时间:2024/04/30 11:53

以孙悟空的72变为例子来说明下

 

/**
 * 克隆的原型
 * @author Administrator
 *
 */
public class Monkey implements Cloneable,Serializable{
 /**
  *
  */
 private static final long serialVersionUID = 1L;
 public int height;
 public int weight;
 public  GoldRingedStaff staff;
 
 //在序列化时会忽略该对象
// public  transient GoldRingedStaff staff;
 
 public Monkey(int height, int weight, GoldRingedStaff staff) {
  super();
  this.height = height;
  this.weight = weight;
  this.staff = staff;
 }
 
 //克隆方法,这里是浅克隆
 public Object shallowClone(){
  try {
   return (Monkey)super.clone();
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return null;
 }
 
 /**
  * 克隆方法,这里是深克隆,这样做的前提就是对象以及对象内部所有引用到的对象都是可序列化的,
  * 否则,就需要仔细考察那些不可序列化的对象可否设成transient,从而将之排除在复制过程之外。
  *
  * 有一些对象,比如线程(Thread)对象或Socket对象,是不能简单复制或共享的。
  * 不管是使用浅度克隆还是深度克隆,只要涉及这样的间接对象,就必须把间接对象设成transient而不予复制;
  * 或者由程序自行创建出相当的同种对象,权且当做复制件使用。
  */
 public Object deepClone() {
  
  //将对象写到流里
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  ObjectOutputStream oos;
  try {
   oos = new ObjectOutputStream(bos);
   oos.writeObject(this);
   
   //从流里读回对象
   ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
   ObjectInputStream ois = new ObjectInputStream(bis);
   return ois.readObject();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
  return null;
  
 }

 @Override
 public String toString() {
  return "Monkey [height=" + height + ", weight=" + weight + ", staff="
    + staff + "]";
 }
}

-------------------------------------------------------------------------------------------------------

/**
 * 金箍棒,原型对象里的一个内部对象
 * @author Administrator
 *
 */

 
public class GoldRingedStaff implements Serializable{
 /**
  *
  */
 private static final long serialVersionUID = 1L;
 public int height =1000;

 @Override
 public String toString() {
  return "GoldRingedStaff [height=" + height + "]";
 }
}

----------------------------------------------------------------------------------------------------

/**
 * 测试类:
 * * 原型模式的优点
  原型模式允许在运行时动态改变具体的实现类型。原型模式可以在运行期间,
由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,
但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。

       原型模式的缺点
  原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,
这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持序列化的间接对象,
或者引用含有循环结构的时候。
 * @author Administrator
 *
 */
public class Test {
 
 public static void main(String[] args) {
  Monkey monkey = new Monkey(100, 200, new GoldRingedStaff());
  
  shallowClone(monkey);
  System.out.println("-----------------------");
  deepClone(monkey);
 }
 
 
 //浅浅的克隆,继承自java.lang.Object类的clone()方法是浅克隆,浅克隆里面的对象是仍然持有原来的引用
 private static void shallowClone(Monkey monkey ){
  Monkey shallowMonkey  = (Monkey) monkey.shallowClone();
  System.out.println("原型对象:"+monkey);
  System.out.println("浅克隆shallowMonkey:"+shallowMonkey);
  
  System.out.println("原来的对象和浅克隆对象是否相等:"+(shallowMonkey==monkey));
  System.out.println("原来的对象的金箍棒可浅克隆对象的金箍棒是否相等:"+(shallowMonkey.staff==monkey.staff));
 }
 
 
 //
  private static void deepClone(Monkey monkey ){
   Monkey deepMonkey  = (Monkey) monkey.deepClone();
   System.out.println("原型对象:"+monkey);
   System.out.println("深克隆deepMonkey:"+deepMonkey);
   
   System.out.println("原来的对象和深克隆对象是否相等:"+(deepMonkey==monkey));
   System.out.println("原来的对象的金箍棒可深克隆对象的金箍棒是否相等:"+(deepMonkey.staff==monkey.staff));
  }
}

 

0 0
原创粉丝点击