最新消息

java原型模式(prototype)

设计模式 金牌剑客 1270℃ 0评论

定义

原型模式是一种创建型模式,是通过拷贝这些原型创建对象。

类图

prototype

实现

原型模式可以通过覆写Object中的clone方法实现。在类声明时必须实现java.lang.Cloneable接口,虽然此接口不用实现任何方法,但是如果不实现此接口,会抛出异常:java.lang.CloneNotSupportedException。

深克隆与浅克隆

浅克隆:对于值型类型(包括基础类型,String类型)进行值复制,对于对象型类型进行引用复制,不复制引用的对象;

深克隆:对于值型类型进行值复制,对于对象型类型进行对象复制。

下面是浅克隆的例子:

ConcretePrototype.java

public class ConcretePrototype implements Cloneable{
	private String name;
	private ArrayList<String> phones;
	
	public ConcretePrototype(){
		this.phones = new ArrayList<>();
	}
	
	public String getName() {
		return name;
	}

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

	public ArrayList<String> getPhones() {
		return phones;
	}

	public void addPhone(String phone) {
		this.phones.add(phone);
	}

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

	@Override
	public ConcretePrototype clone() {
		try {
			return (ConcretePrototype) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}
}

Client.java

public class Client {
	public static void main(String[] args) {
		ConcretePrototype prototype = new ConcretePrototype();
		prototype.setName("prototype1");
		prototype.addPhone("13212345678");
		ConcretePrototype prototype2 = prototype.clone();
		prototype2.setName("prototype2");
		prototype2.addPhone("18512345678");
		System.out.println("拷贝前:");
		System.out.println(prototype);
		System.out.println("拷贝后:");
		System.out.println(prototype2);
	}
}

结果

拷贝前:
ConcretePrototype [name=prototype1, phones=[13212345678, 18512345678]]
拷贝后:
ConcretePrototype [name=prototype2, phones=[13212345678, 18512345678]]

在往prototype2中的phones添加元素时,prototype中的phones也是可以读到的,所以说明在克隆前后的phones引用指向同一个对象。

下面是深克隆的例子:

ConcretePrototype.java

public class ConcretePrototype implements Cloneable{
	private String name;
	private ArrayList<String> phones;
	
	public ConcretePrototype(){
		this.phones = new ArrayList<>();
	}
	
	public String getName() {
		return name;
	}

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

	public ArrayList<String> getPhones() {
		return phones;
	}

	public void addPhone(String phone) {
		this.phones.add(phone);
	}

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

	@Override
	public ConcretePrototype clone() {
		try {
			ConcretePrototype prototype = (ConcretePrototype) super.clone();
			prototype.phones = (ArrayList<String>)this.phones.clone();
			return prototype;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}
}

结果

拷贝前:
ConcretePrototype [name=prototype1, phones=[13212345678]]
拷贝后:
ConcretePrototype [name=prototype2, phones=[13212345678, 18512345678]]

在往prototype2中的phones添加元素时,prototype中的phones中的元素是不变的,所以说明在克隆前后的phones引用指向不同的对象。

转载请注明:QualInfo » java原型模式(prototype)

喜欢 (1)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址