Java设计模式之 原型模式

Java设计模式 - 原型模式

原型模式应用场景:

原型模式是指用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.适合原型模式的情景如下:程序需要从一个对象出发,得到i若干个和其状态相同,并可独立变化其状态的对象时;对象创建需要独立于它的构造方法和表示时,以原型对象为基础,克隆新的对象,并完善对象实例变量时.

源码下载地址:

https://github.com/godlikecheng/prototype_model

对于浅复制和深复制的概念:

原型模式的实现方式:

1.原型复制具体实现方法 - 利用构造函数方法 - 浅复制

package prototype_model;

public class Address {
	String pro; // 出生省
	String city; // 出生市
	String zip; // 出生地邮编

	public Address(String pro, String city, String zip) {
		this.pro = pro;
		this.city = city;
		this.zip = zip;
	}

	public String getPro() {
		return pro;
	}

	public void setPro(String pro) {
		this.pro = pro;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}
	
}
package prototype_model;


public class Student {
	
	String name;  // 姓名
	int age; // 年龄
	Address add;  // 籍贯信息
	
	Student(String na, int a, Address add) {
		this.name = na;
		this.age = a;
		this.add = add;
	}
	
	public Student(Student s) {
		name = s.getName();
		age = s.getAge();
		add = s.getAdd();
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Address getAdd() {
		return add;
	}

	public void setAdd(Address add) {
		this.add = add;
	}
	
}

测试类:

package prototype_model;
/**
 * 测试类 - 浅复制
 * @author 张宜成
 */
public class Test {
	public static void main(String[] args) {
		Address adr = new Address("liaoning", "dalian","116081");
		Student s = new Student("Zhang",20,adr);  // 建立学生对象s
		Student s2 = new Student(s);  // 以s为原型,建立复制对象s2
		
		System.out.println("s=" + s + "\ts2=" + s2);
		System.out.println("s.name=" + s.getName() + "\ts2.name=" + s2.getName());
		System.out.println("a.age=" + s.getAge() + "\ts2.age=" + s2.getAge());
		System.out.println("a.adr=" + s.getAdd() + "\ts2.adr=" + s2.getAdd());
		
	}
}

运行结果:

深复制

package prototype_model_02;

public class Address {
	String pro; // 出生省
	String city; // 出生市
	String zip; // 出生地邮编

	public Address(String pro, String city, String zip) {
		this.pro = pro;
		this.city = city;
		this.zip = zip;
	}

	// 深拷贝构造方法
	public Address(Address add) {
		pro = add.getPro();
		city = add.getCity();
		zip = add.getZip();
	}

	public String getPro() {
		return pro;
	}

	public void setPro(String pro) {
		this.pro = pro;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}
	
}
package prototype_model_02;


public class Student {
	
	String name;  // 姓名
	int age; // 年龄
	Address add;  // 籍贯信息
	
	Student(String na, int a, Address add) {
		this.name = na;
		this.age = a;
		this.add = add;
	}
	
	public Student(Student s) {
		name = s.getName();
		age = s.getAge();
//		add = s.getAdd();
		// 与浅复制的不同之处
		add = new Address(s.getAdd());
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Address getAdd() {
		return add;
	}

	public void setAdd(Address add) {
		this.add = add;
	}
	
}

测试类:

package prototype_model_02;


/**
 * 测试类 - 深复制
 * @author 张宜成
 */
public class Test {
	public static void main(String[] args) {
		Address adr = new Address("liaoning", "dalian","116081");
		Student s = new Student("Zhang",20,adr);  // 建立学生对象s
		Student s2 = new Student(s);  // 以s为原型,建立复制对象s2
		
		System.out.println("s=" + s + "\ts2=" + s2);
		System.out.println("s.name=" + s.getName() + "\ts2.name=" + s2.getName());
		System.out.println("a.age=" + s.getAge() + "\ts2.age=" + s2.getAge());
		System.out.println("a.adr=" + s.getAdd() + "\ts2.adr=" + s2.getAdd());
		
	}
}

测试结果:


2.利用Cloneable接口方法

浅复制

package prototype_model_03;

public class Address {
	String pro; // 出生省
	String city; // 出生市
	String zip; // 出生地邮编

	public Address(String pro, String city, String zip) {
		this.pro = pro;
		this.city = city;
		this.zip = zip;
	}

	public String getPro() {
		return pro;
	}

	public void setPro(String pro) {
		this.pro = pro;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}
	
}
package prototype_model_03;


public class Student implements Cloneable {
	
	String name;  // 姓名
	int age; // 年龄
	Address add;  // 籍贯信息
	
	Student(String na, int a, Address add) {
		this.name = na;
		this.age = a;
		this.add = add;
	}
	
	public Student(Student s) {
		name = s.getName();
		age = s.getAge();
		add = s.getAdd();
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Address getAdd() {
		return add;
	}

	public void setAdd(Address add) {
		this.add = add;
	}
	
	// 利用Cloneable接口方法
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	
}

测试类:

package prototype_model_03;
/**
 * 测试类 - 浅复制 - 利用Cloneable接口方法
 * @author 张宜成
 */
public class Test {
	public static void main(String[] args) throws CloneNotSupportedException {
		Address adr = new Address("liaoning", "dalian","116081");
		Student s = new Student("Zhang",20,adr);  // 建立学生对象s  原型对象
//		Student s2 = new Student(s);  // 以s为原型,建立复制对象s2
		Student s2 = (Student) s.clone();  //克隆对象
		
		System.out.println("s=" + s + "\ts2=" + s2);
		System.out.println("s.name=" + s.getName() + "\ts2.name=" + s2.getName());
		System.out.println("a.age=" + s.getAge() + "\ts2.age=" + s2.getAge());
		System.out.println("a.adr=" + s.getAdd() + "\ts2.adr=" + s2.getAdd());
		
	}
}

测试结果:

深复制

package prototype_model_04;

public class Address implements Cloneable {
	String pro; // 出生省
	String city; // 出生市
	String zip; // 出生地邮编

	public Address(String pro, String city, String zip) {
		this.pro = pro;
		this.city = city;
		this.zip = zip;
	}

	public String getPro() {
		return pro;
	}

	public void setPro(String pro) {
		this.pro = pro;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}
	
	// 深拷贝
	protected Object clone() throws CloneNotSupportedException {
		Address s = (Address)super.clone();
		return s;
	}
	
}
package prototype_model_04;


public class Student implements Cloneable {
	
	String name;  // 姓名
	int age; // 年龄
	Address add;  // 籍贯信息
	
	Student(String na, int a, Address add) {
		this.name = na;
		this.age = a;
		this.add = add;
	}
	
	public Student(Student s) {
		name = s.getName();
		age = s.getAge();
		add = s.getAdd();
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Address getAdd() {
		return add;
	}

	public void setAdd(Address add) {
		this.add = add;
	}
	
	// 利用Cloneable接口方法
	protected Object clone() throws CloneNotSupportedException {
		Student s = (Student)super.clone();
		s.setAdd((Address)add.clone());
		return s;
	}
	
}

 测试类:

package prototype_model_04;
/**
 * 测试类 - 深复制 - 利用Cloneable接口方法
 * @author 张宜成
 */
public class Test {
	public static void main(String[] args) throws CloneNotSupportedException {
		Address adr = new Address("liaoning", "dalian","116081");
		Student s = new Student("Zhang",20,adr);  // 建立学生对象s  原型对象
//		Student s2 = new Student(s);  // 以s为原型,建立复制对象s2
		Student s2 = (Student) s.clone();  //克隆对象
		
		System.out.println("s=" + s + "\ts2=" + s2);
		System.out.println("s.name=" + s.getName() + "\ts2.name=" + s2.getName());
		System.out.println("a.age=" + s.getAge() + "\ts2.age=" + s2.getAge());
		System.out.println("a.adr=" + s.getAdd() + "\ts2.adr=" + s2.getAdd());
		
	}
}

测试结果:


利用Serializable序列化接口方法

深复制

package prototype_model_05;

import java.io.Serializable;

// 实现Serializable接口
public class Address implements Serializable{
	String pro; // 出生省
	String city; // 出生市
	String zip; // 出生地邮编

	public Address(String pro, String city, String zip) {
		this.pro = pro;
		this.city = city;
		this.zip = zip;
	}

	public String getPro() {
		return pro;
	}

	public void setPro(String pro) {
		this.pro = pro;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}
	
}
package prototype_model_05;

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

// 实现Serializable, Cloneable接口
public class Student implements Cloneable,Serializable {
	
	String name;  // 姓名
	int age; // 年龄
	Address add;  // 籍贯信息
	
	Student(String na, int a, Address add) {
		this.name = na;
		this.age = a;
		this.add = add;
	}
	
	public Student(Student s) {
		name = s.getName();
		age = s.getAge();
		add = s.getAdd();
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Address getAdd() {
		return add;
	}

	public void setAdd(Address add) {
		this.add = add;
	}
	
	// 利用Serializable序列化接口方法
	protected Object clone() throws CloneNotSupportedException {
		Object obj = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			oos.writeObject(this);
			
			// 从流里读回来
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bis);
			obj = ois.readObject();
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
	
}

测试类:

package prototype_model_05;
/**
 * 测试类 - 深复制 - 利用Serializable接口方法
 * @author 张宜成
 */
public class Test {
	public static void main(String[] args) throws CloneNotSupportedException {
		Address adr = new Address("liaoning", "dalian","116081");
		Student s = new Student("Zhang",20,adr);  // 建立学生对象s  原型对象
//		Student s2 = new Student(s);  // 以s为原型,建立复制对象s2
		Student s2 = (Student) s.clone();  //克隆对象
		
		System.out.println("s=" + s + "\ts2=" + s2);
		System.out.println("s.name=" + s.getName() + "\ts2.name=" + s2.getName());
		System.out.println("a.age=" + s.getAge() + "\ts2.age=" + s2.getAge());
		System.out.println("a.adr=" + s.getAdd() + "\ts2.adr=" + s2.getAdd());
		
	}
}

测试结果:


应用案例:

原型管理器及其应用

package prototype_demo;

import java.util.Hashtable;

/**
 * 原型管理器及其应用 很明显,原型管理器是对原型的管理类,可以添加原型对象,也可以获得原型对象
 * @author 张宜成
 */
public class PrototypeManager {
	// 定义一个Hashtable,用于存储原型对象
	private Hashtable ht = new Hashtable();
	private static PrototypeManager pm = new PrototypeManager();

	// 首先通过addPrototype()添加各原型对象
	public void addPrototype(String key, Object obj) {
		ht.put(key, obj);
	}

	// 再通过getPropotype()获得所需原型对象即可.
	public Object getPrototype(String key) {
		return ht.get(key);
	}

	public static PrototypeManager getPrototypeManager() {
		return pm;
	}
}
package prototype_demo;

public class PubInfo implements Cloneable{  // 这里需要实现Cloneable接口
	String college; // 所在大学
	String city; // 所在城市
	String zip; // 邮编

	// 构造方法
	public PubInfo(String college, String city, String zip) {
		super();
		this.college = college;
		this.city = city;
		this.zip = zip;
	}

	public String getCollege() {
		return college;
	}

	public void setCollege(String college) {
		this.college = college;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}
	
	public String toString() {
		return "PubInfo [college=" + college + ", city=" + city + ", zip="
				+ zip + "]";
	}

	// 重写clone的方法 - 浅拷贝
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	

}
package prototype_demo;

/**
 * 学生类
 * 
 * @author 张宜成
 */
public class Student implements Cloneable { // 这里需要实现Cloneable的接口
	String name; // 学生姓名
	int age; // 年龄
	PubInfo info; // 公共信息

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public PubInfo getInfo() {
		return info;
	}

	public void setInfo(PubInfo info) {
		this.info = info;
	}
	
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", info=" + info
				+ "]";
	}

	// 重写clone的方法 - 浅拷贝
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

测试类:

要求:

现在要求创建m个辽宁师大学生对象,n个大连理工大学学生对象,对重复的公共信息仅输入一次即可, 那么它还如何实现嗯?具体思路如下:
(1) 创建辽宁师大学生原型对象s,要求对象中姓名name,年龄age为默认值,公共信息对象info设置为 "辽宁师范大学, 大连, 116081" 同理创建大连理工大学学生原型对象s2,将s s2添加到原型管理器对象中.

(2)从原型管理器获取辽宁师大学生原型对象t,循环m次,在循环体中创建t的克隆对象(对应每一位新创建的学生对象), 仅输入学生姓名,年龄即可.

(3)同理创建n个大连理工公大学学生对象.

package prototype_demo;

import java.util.Scanner;
import java.util.Vector;

/**
 * @author 张宜成
 */
public class Test {
	public static void main(String[] args) throws CloneNotSupportedException {
		int m = 3;
		int n = 3;
		PrototypeManager pm = PrototypeManager.getPrototypeManager();
		PubInfo p = new PubInfo("liaoshi", "dalian", "116081");
		Student s = new Student(); // 创建辽师学生原型对象
		s.setInfo(p);
		pm.addPrototype("liaoshi", s); // 加入原型管理器
		PubInfo p2 = new PubInfo("dagong", "dalian", "116023");
		Student s2 = new Student(); // 创建大连理工学生对象
		s2.setInfo(p2);
		pm.addPrototype("dagong", s2);

		Scanner sc = new Scanner(System.in);

		/*
		 * 辽师
		 */
		Vector<Student> vec = new Vector(); // 创建辽师学生集合
		Student t = (Student) pm.getPrototype("liaoshi"); // 获取原型对象
		for (int i = 0; i < m; i++) {
			Student st = (Student) t.clone(); // 通过浅复制创建新学生对象
			System.out.println("请输入要录入的辽大姓名:");
			st.setName(sc.nextLine()); // 输入并设置姓名
			System.out.println("请输入要录入的辽大年龄:");
			st.setAge(sc.nextInt()); // 输入并设置年龄
			vec.add(st);
		}

		Vector<Student> vec2 = new Vector();
		Student t2 = (Student) pm.getPrototype("dagong");
		for (int i = 0; i < n; i++) {
			Student st = (Student) t2.clone();
			System.out.println("请输入要录入的大工姓名:");
			st.setName(sc.nextLine());
			System.out.println("请输入要录入的大工年龄:");
			st.setName(sc.nextLine());
			vec2.add(st);
		}

	}
}

上一篇: Java设计模式之 工厂模式

下一篇: 待更新...

猜你喜欢

转载自blog.csdn.net/qq_40820862/article/details/82620472