Java原型设计模式(Prototype)

转载 2013年12月03日 21:43:11
1、定义
      原型模式(Prototype)就是通过复制一个已经存在的实例来返回新的实例,而不是新建实例,被复制的实例就是我们所称的原型对象,这个原型是可定制的。
2、原理
     有两部分组成,抽象原型和具体原型。意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

3、原型模式UML图


4、实现
      1>使用一个原型管理器;
      2>实现克隆操作(浅拷贝和深拷贝);

      3>初始化克隆对象。

5、示例程序

(1)利用Java中的clone方法深拷贝与浅拷贝

浅拷贝:

public class Professor {
	private String address;
	private double salary;

	public Professor(String address, double salary) {
		this.address = address;
		this.salary = salary;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	@Override
	public String toString() {
		return "Professor [address=" + address + ", salary=" + salary + "]";
	}
}
public class Student implements Cloneable {
	private String name;
	private int age;
	private Professor professor;

	public Student(String name, int age, Professor professor) {
		this.name = name;
		this.age = age;
		this.professor = professor;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", Professor="
				+ professor.toString() + "]";
	}

	@Override
	public Object clone() {
		Student student = null;
		try {
			// 在运行时,Object中的clone识别出你要复制的是哪一个对象,Object中的clone()
			// 然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
			student = (Student) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return student;
	}

	public static void main(String[] args) {
		Professor professor = new Professor("beijing", 12.0);
		Student s1 = new Student("zhangsan", 18, professor);
		Student s2 = (Student) s1.clone();
		System.out.println(s1);
		System.out.println(s2);
		System.out.println("**************************************");
		s2.name = "lisi";
		s2.age = 20;
		s2.professor.setAddress("shanghai");
		s2.professor.setSalary(230.0);
		System.out.println(s1);
		System.out.println(s2);
	}
}
Student [name=zhangsan, age=18, Professor=Professor [address=beijing, salary=12.0]]
Student [name=zhangsan, age=18, Professor=Professor [address=beijing, salary=12.0]]
**************************************
Student [name=zhangsan, age=18, Professor=Professor [address=shanghai, salary=230.0]]
Student [name=lisi, age=20, Professor=Professor [address=shanghai, salary=230.0]]
深拷贝:

public class Professor2 implements Cloneable {
	private String address;
	private double salary;

	public Professor2(String address, double salary) {
		this.address = address;
		this.salary = salary;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	@Override
	public String toString() {
		return "Professor2 [address=" + address + ", salary=" + salary + "]";
	}
	
	@Override
	public Object clone() {
		Professor2 o = null;
		try {
			o = (Professor2) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return o;
	}
}
public class Student2 implements Cloneable {
	private String name;
	private int age;
	private Professor2 professor;

	public Student2(String name, int age, Professor2 professor) {
		this.name = name;
		this.age = age;
		this.professor = professor;
	}

	@Override
	public String toString() {
		return "Student2 [name=" + name + ", age=" + age + ", Professor2="
				+ professor.toString() + "]";
	}

	@Override
	public Object clone() {
		Student2 o = null;
		try {
			// 在运行时,Object中的clone识别出你要复制的是哪一个对象,Object中的clone()
			// 然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
			o = (Student2) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		o.professor = (Professor2) professor.clone();
		return o;
	}

	public static void main(String[] args) {
		Professor2 professor = new Professor2("beijing", 12.0);
		Student2 s1 = new Student2("zhangsan", 18, professor);
		Student2 s2 = (Student2) s1.clone();
		System.out.println(s1);
		System.out.println(s2);
		System.out.println("**************************************");
		s2.name = "lisi";
		s2.age = 20;
		s2.professor.setAddress("shanghai");
		s2.professor.setSalary(230.0);
		System.out.println(s1);
		System.out.println(s2);
	}
}
Student2 [name=zhangsan, age=18, Professor2=Professor2 [address=beijing, salary=12.0]]
Student2 [name=zhangsan, age=18, Professor2=Professor2 [address=beijing, salary=12.0]]
**************************************
Student2 [name=zhangsan, age=18, Professor2=Professor2 [address=beijing, salary=12.0]]
Student2 [name=lisi, age=20, Professor2=Professor2 [address=shanghai, salary=230.0]]
模拟clone方法进行浅拷贝
public interface Prototype {
	public Prototype clone();

	public void setName(String name);

	public String getName();
}

public class ConcretePrototypeA implements Prototype {
	private String name;

	public ConcretePrototypeA() {
	}

	public ConcretePrototypeA(String name) {
		this.name = name;
	}

	@Override
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public Prototype clone() {
		ConcretePrototypeA prototype = new ConcretePrototypeA();
		prototype.setName(this.name);
		return prototype;
	}

	@Override
	public String toString() {
		return "ConcretePrototypeA [name=" + name + "]";
	}
}
public class TestPrototype {

	public static void main(String[] args) {
		ConcretePrototypeA prototypeA = new ConcretePrototypeA("jimmy");
		ConcretePrototypeA prototypeA2 = (ConcretePrototypeA) prototypeA
				.clone();
		System.out.println(prototypeA);
		System.out.println(prototypeA2);
	}
}
ConcretePrototypeA [name=jimmy]
ConcretePrototypeA [name=jimmy]

6、应用场景

      系统需要创建的对象是动态加载的,而且产品具有一定层次时,可以考虑使用原型模式。原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据。
     1>当要实例化的类是在运行时刻指定时,例如,通过动态装载;
     2>或者为了避免创建一个与产品类层次平行的工厂类层次时;
     3>或者当一个类的实例只能有几个不同状态组合中的一种时。
     4>建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
      比如有一个对象,在某一时刻该对象中已经包含了一些有效的值,此时可能会需要一个和该对象完全相同的新对象,并且此后对新对象的任何改动都不会影响到原来对象中的值,也就是说新对象与原来的对象是两个独立的对象,但新对象的初始值是由原来的对象确定的。
7、赋值创建对象
    1>java中赋值创建对象是可以实现对象的重用的,但是新对象和原对象是同一个引用;如果修改其中的一个对象的值,则另外的一个对象也会发生改变。
    2>使用clone方法会返回对象的一个拷贝,这样一来,如果修改一个对象的值,则另外的对象不会发生改变的。
8、拷贝分为"浅拷贝"和"深拷贝"
      浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
      深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制(那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象)。换言之,深复制把重复的对象所引用的对象都复制一遍,而这种对被引用到的对象的复制叫做间接复制。

iOS与java原型设计模式对比

iOS原型模式与Java原型模式 2014-10-17 牛其洪 iOS编程与大数据 什么是原型模式 什么时候用到原型模式 原型模式有那些优缺点 ...

JAVA设计模式之 原型模式【Prototype Pattern】

一、概述:      使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。简单的说就是对象的拷贝生成新的对象(对象的克隆),原型模式是一种对象创建型模式。 二、使用场景:     创...

java设计模式--原型模式(Prototype)

Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这...

java设计模式(6):原型模式(Prototype)

概述 在软件系统中,有时候面临的产品类是动态变化的,而且这个产品类具有一定的等级结构。这时如果用工厂模式,则与产品类等级结构平行的工厂方法类也要随着这种变化而变化,显然不大合适。那么如何封装这种...
  • lwj0310
  • lwj0310
  • 2014年04月25日 17:44
  • 2889

Java设计模式-----Prototype原型模式

源自:http://www.blogjava.net/flustar/archive/2007/12/02/prototype.html Prototype原型模式: 通过给出一个原型对象来指明所...

java设计模式5——原型模式(Prototype)

原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。本小结会通过对象的复制,进行讲解。在Java中...

Java设计模式——原型模式(Prototype Pattern)

什么是原型模式用于创建重复的对象的最佳方式,同时又能保证性能。 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代...

Java设计模式之-原型模式(prototype)

原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。本小结会通过对象的复制,进行讲解。在Java中...

java设计模式——原型模式(Prototype Pattern)

概述:        在使用原型模式时,我们需要首先创建一个原型对象,再通过复制这个原型对象来创建更多同类型的对象。 需要注意的是通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,通常对...

JAVA设计模式(05):创建型-原型模式(Prototype)

张纪中版《西游记》以出乎意料的造型和雷人的台词遭到广大观众朋友的热议,我们在此对该话题不作过多讨论。但无论是哪个版本的《西游记》,孙悟空都是其中的一号雄性主角,关于他(或它)拔毛变小猴的故事几乎人人皆...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java原型设计模式(Prototype)
举报原因:
原因补充:

(最多只允许输入30个字)