设计模式之原始模型模式

如有转载,请申明:

转载至 http://blog.csdn.net/qq_35064774/article/details/52102397


1 什么是原始模型模式

 

原始模型模式属于对象的构建模式。通过给出一个原型对象来指明所要创建的对象的类型,然后复制这个原型对象的办法创建出更多同类型的对象。

 

通俗来说,就是通过存在的对象创建出n份相同的对象,也就是对象拷贝。而java对这模式有很好的支持,有克隆接口。

 

 

2 如何实现原始模型模式

 

对于对象拷贝来说,存在两种,一种是浅拷贝,一种是深拷贝。

两者唯一的区别其实也很简单。

深拷贝会把对象内部引用的对象也拷贝一份,而浅拷贝不会。

 

接下来我们写一个例子来测试这两种拷贝。

 

首先我们先设计一个接口,它继承Cloneable 接口,重写Object类的clone()方法。

 

package com.ittianyu.prototype;

public interface Prototype extends Cloneable {
	public Object clone() throws CloneNotSupportedException;
}


你可能问既然java支持clone,为什么还要这么麻烦特地定义一个接口。这里为了强制实现它的类必须重写clone方法。同时这种方式也可以在c++中使用。

 

然后我们定义两个实现了这个接口的类,分别是CarPersonCar实现的是浅拷贝,直接调用父类Objectclone方法作为实现。Person对象中含有Car对象,所以实现的是深拷贝,这里的深拷贝实现,我采用的是串行化的方式,这方式通用性强,缺点也很明显,就是必须实现Serializable

 

package com.ittianyu.prototype;

import java.io.Serializable;

public class Car implements Prototype, Serializable{
	private String name;
	
	public Car(String name) {
		super();
		this.name = name;
	}
	/**
	 * 直接调用Object的clone实现浅拷贝
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	
	@Override
	public String toString() {
		return "Car [name=" + name + "]";
	}
}


package com.ittianyu.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Person implements Prototype, Serializable {
	private String name;
	private Car car;
	
	public Person(String name, Car car) {
		super();
		this.name = name;
		this.car = car;
	}
	
	public Car getCar() {
		return car;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", car=" + car + "]";
	}

	/**
	 * 通过序列化实现深拷贝
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos;
		try {
			// write
			oos = new ObjectOutputStream(baos);
			oos.writeObject(this);
			
			// read
			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bais);
			return ois.readObject();
			
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
			throw new CloneNotSupportedException();
		}
	}
}


对于深拷贝,其实也很简单,就是把整个对象通过ObjectOutputStream 写到内存,然后通过ObjectInputStream读取出来。

把对象写入内存时,就是将整个对象深拷贝了一份,串行化的方式放到内存。

 

最后是测试类。


package com.ittianyu.prototype;

public class Test {
	public static void main(String[] args) {
		// 浅拷贝测试
		Car car = new Car("奔驰");
		System.out.println(car);
		try {
			System.out.println(car.clone());
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		
		// 深拷贝测试
		Person person = new Person("Mike", car);
		System.out.println(person);
		
		try {
			Person clonePerson = (Person) person.clone();
			System.out.println(clonePerson);
			
			System.out.println("clonePerson.getCar() == person.getCar() is "
			+ (clonePerson.getCar() == person.getCar()));
			
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
}




3 在什么情况下使用原始模型模式

 

引用《Java与模式》中的说明。

假设一个系统的产品类是动态加载的,而且产品类具有一定的等级结构。这个时候如果采取工厂模式的话,工厂类就不得不具有一个相应的等级结构。而产品类的等级结构一旦变化,工厂类的等级结构就不得不有一个相应的变化。这对于产品结构可能会有经常性变化的系统来说,采用工厂模式就有不方便之处。

这时如果采取原始模型模式,给每一个产品类配备一个克隆方法(大多数的时候只需给产品类等级结构的根类配备一个克隆方法),便可以避免使用工厂模式所带来的具有固定等级结构的工厂类。

 

 

4 原始模型模式的优点和缺点

 

优点:

 * 原始模型模式允许动态地增加或减少产品类。由于创建产品类实例的方法是产品类内部具有的,因此,增加新产品对整个结构没有影响。

 * 原始模型模式提供简化的创建结构。

 * 具有给一个应用软件动态加载新功能的能力。

 * 产品类不需要非得有任何事先确定的等级结构,因为原始模型模式适用于任何的等级结构。

 

缺点:

 * 要支持该模式的每个类都必须配备一个克隆方法。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值