`
丶西红柿丿炒蛋
  • 浏览: 5554 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

原型模式(Prototype)

 
阅读更多

原型模式(Prototype)

定义:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

 

工作原理:

通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。

 

理解:

原型模式,顾名思义,通过一个原型模板,依葫芦画瓢得到另一个新的对象。

即通过一个已经存在的对象,复制出更多的具有与此对象具有相同类型的新的对象。

Java中对象的复制可以通过克隆完成。所以我们需先对克隆有所了解。

 

Java中有基本数据类型和引用类型之分。基本数据类型存放的是数值本身,引用类型存放的是数据的引用(类似指针)。

1、浅复制

基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。String是class对象,所以为引用类型,但因为String是final的且加之JVM对String优化,因此修改了克隆对象的String类型值后,原型对象的String类型之不会发生改变。Object的clone()方法默认为浅复制。

public class ShallowClone {
	public static void main(String[] args) throws CloneNotSupportedException {
		Course course = new Course("语文");
		Student stuA = new Student();
		stuA.setAge(11);
		stuA.setName("张三");
		stuA.setCourse(course);
		System.out.println("修改值前:");
		System.out.println("stuA:"+ stuA.toString());
		Student stuB = stuA.clone();
		System.out.println("stuB:"+ stuB.toString());
		stuB.setAge(22);
		stuB.setName("李四");
		stuB.setCourseName("数学");
		System.out.println("\n\n修改值后:");
		System.out.println("stuA:"+ stuB.toString());
		System.out.println("stuB:"+ stuA.toString());
	}
}
class Student implements Cloneable{
	private int age;
	private String name;
	private Course course;
	@Override
	protected Student clone() throws CloneNotSupportedException {
		return (Student)super.clone();
	}
	@Override
	public String toString() {
		return "年龄:" + this.age + "\t姓名:" + this.getName() + "\t选修课程:"+ this.getCourse().getName();
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Course getCourse() {
		return course;
	}
	public void setCourse(Course course) {
		this.course = course;
	}
	public void setCourseName(String name) {
		this.course.setName(name);
	}
}
class Course{
	private String name;
	public Course(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

打印结果:

修改值前:
stuA:年龄:11	姓名:张三	选修课程:语文
stuB:年龄:11	姓名:张三	选修课程:语文


修改值后:
stuA:年龄:22	姓名:李四	选修课程:数学
stuB:年龄:11	姓名:张三	选修课程:数学

 对于引用类型,原型对象和克隆对象指向了相同的引用。所以修改引用类型的值后,原型对象和克隆对象都会随之改变。

2、深复制

深复制是完全拷贝,克隆对象与原型对象的引用类型的值都指向了不同的实例,因此修改克隆或原型的引用类型值也不会相互影响。上述实例只需要修改clone方法,即可改为深复制。

package prototype.deep;

public class DeepClone {
	public static void main(String[] args) throws CloneNotSupportedException {
		Course course = new Course("语文");
		Student stuA = new Student();
		stuA.setAge(11);
		stuA.setName("张三");
		stuA.setCourse(course);
		System.out.println("修改值前:");
		System.out.println("stuA:"+ stuA.toString());
		Student stuB = stuA.clone();
		System.out.println("stuB:"+ stuB.toString());
		stuB.setAge(22);
		stuB.setName("李四");
		stuB.setCourseName("数学");
		System.out.println("\n\n修改值后:");
		System.out.println("stuA:"+ stuB.toString());
		System.out.println("stuB:"+ stuA.toString());
	}
}
class Student implements Cloneable{
	private int age;
	private String name;
	private Course course;
	@Override
	protected Student clone() throws CloneNotSupportedException {
		Student stu = (Student)super.clone();
		Course cou = new Course(stu.getCourse().getName());
		stu.setCourse(cou);
		return stu;
	}
	@Override
	public String toString() {
		return "年龄:" + this.age + "\t姓名:" + this.getName() + "\t选修课程:"+ this.getCourse().getName();
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Course getCourse() {
		return course;
	}
	public void setCourse(Course course) {
		this.course = course;
	}
	public void setCourseName(String name) {
		this.course.setName(name);
	}
}
class Course{
	private String name;
	public Course(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

 打印:

修改值前:
stuA:年龄:11	姓名:张三	选修课程:语文
stuB:年龄:11	姓名:张三	选修课程:语文


修改值后:
stuA:年龄:22	姓名:李四	选修课程:数学
stuB:年龄:11	姓名:张三	选修课程:语文

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics