了解设计模式 之 创建模式(三) -- 原型模式

本文通过一个配钥匙的例子详细介绍了原型模式的概念及其在Java中的实现方式,对比了浅克隆与深度克隆的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
3. 原型模式(Prototype Pattern)
原型模式,顾名思义,就是有一个原型,可以根据这个原型来创建其他的对象,当要创建一些列相似的对象时,使用原型来克隆总比直接创建一个新的对象要来的直接。

还是举个例子吧,比如说一个配钥匙的过程,不过使用一个非常笨的方法。

首先是一个钥匙的类:

Java代码 复制代码  收藏代码
  1. public class Key {   
  2.     // 使用一个整形变量来代表钥匙的形状吧   
  3.     private int shape = 0;   
  4.   
  5.     public int getShape() {   
  6.         return shape;   
  7.     }   
  8.   
  9.     public void setShape(int shape) {   
  10.         this.shape = shape;   
  11.     }   
  12. }  
public class Key {
	// 使用一个整形变量来代表钥匙的形状吧
	private int shape = 0;

	public int getShape() {
		return shape;
	}

	public void setShape(int shape) {
		this.shape = shape;
	}
}


其次是一个配钥匙的机器:

Java代码 复制代码  收藏代码
  1. public class KeyCopier {   
  2.     public Key copy(Key key){   
  3.         Key newKey = new Key();   
  4.         newKey.setShape(key.getShape());   
  5.         return newKey;   
  6.     }   
  7. }  
public class KeyCopier {
	public Key copy(Key key){
		Key newKey = new Key();
		newKey.setShape(key.getShape());
		return newKey;
	}
}


最后是测试的客户端:

Java代码 复制代码  收藏代码
  1. public class Client {   
  2.   
  3.     public static void main(String[] args) {   
  4.         Key key = new Key();   
  5.         key.setShape(1);   
  6.            
  7.         KeyCopier copier = new KeyCopier();   
  8.         Key newKey = copier.copy(key);   
  9.     }   
  10.   
  11. }  
public class Client {

	public static void main(String[] args) {
		Key key = new Key();
		key.setShape(1);
		
		KeyCopier copier = new KeyCopier();
		Key newKey = copier.copy(key);
	}

}


上边的三个类模拟了一个配钥匙的过程,对一个Key进行了复制,但是,严格的说,上边的实现挺麻烦的,并且没有什么通用性,每次都要了解要被复制的对象的内部结构,其实就是把老对象和新对象间的状态复制过程封装了一下。java有很好的实现方式,就是java本身提供的#clone()方法。

比如上边的这个配钥匙的例子,用#clone()方法的实现如下。在这里,我修改了钥匙这个类中表示形状的成员,把它独立出来作为一个类Shape。

Java代码 复制代码  收藏代码
  1. public class Shape {   
  2.     private int state = 0;   
  3.   
  4.     public Shape(int state) {   
  5.         this.state = state;   
  6.     }   
  7.   
  8.     public int getState() {   
  9.         return state;   
  10.     }   
  11.   
  12.     public void setState(int state) {   
  13.         this.state = state;   
  14.     }   
  15.   
  16. }  
public class Shape {
	private int state = 0;

	public Shape(int state) {
		this.state = state;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

}


然后是Key

Java代码 复制代码  收藏代码
  1. public class Key implements Cloneable {   
  2.     // 使用一个整形变量来代表钥匙的形状吧   
  3.     private Shape shape = null;   
  4.        
  5.     public Key(Shape shape){   
  6.         this.shape = shape;   
  7.     }   
  8.   
  9.     public Shape getShape() {   
  10.         return shape;   
  11.     }   
  12.   
  13.     public void setShape(Shape shape) {   
  14.         this.shape = shape;   
  15.     }   
  16.   
  17.     public Object clone() {   
  18.         Key obj = null;   
  19.         try {   
  20.             obj = (Key) super.clone();   
  21.         } catch (CloneNotSupportedException e) {   
  22.         }   
  23.   
  24.         return obj;   
  25.     }   
  26.   
  27. }  
public class Key implements Cloneable {
	// 使用一个整形变量来代表钥匙的形状吧
	private Shape shape = null;
	
	public Key(Shape shape){
		this.shape = shape;
	}

	public Shape getShape() {
		return shape;
	}

	public void setShape(Shape shape) {
		this.shape = shape;
	}

	public Object clone() {
		Key obj = null;
		try {
			obj = (Key) super.clone();
		} catch (CloneNotSupportedException e) {
		}

		return obj;
	}

}


最后是客户端:

Java代码 复制代码  收藏代码
  1. public class Client {   
  2.   
  3.     public static void main(String[] args) {   
  4.         Shape shape = new Shape(1);   
  5.   
  6.         Key key = new Key(shape);   
  7.   
  8.         // 克隆了钥匙   
  9.         Key newKey = (Key) key.clone();   
  10.   
  11.         System.out.println(newKey.getShape().getState());   
  12.     }   
  13.   
  14. }  
public class Client {

	public static void main(String[] args) {
		Shape shape = new Shape(1);

		Key key = new Key(shape);

		// 克隆了钥匙
		Key newKey = (Key) key.clone();

		System.out.println(newKey.getShape().getState());
	}

}


执行Client之后,控制台会显示出 "1",说明同之前的那个Key的状态时相同的。

不过我们还可以做下面的一个实验,把Client做一些修改:

Java代码 复制代码  收藏代码
  1. public class Client {   
  2.   
  3.     public static void main(String[] args) {   
  4.         Shape shape = new Shape(1);   
  5.   
  6.         Key key = new Key(shape);   
  7.   
  8.         // 克隆了钥匙   
  9.         Key newKey = (Key) key.clone();   
  10.            
  11.         Shape newShape = newKey.getShape();   
  12.            
  13.         newShape.setState(0);   
  14.   
  15.         System.out.println(key.getShape().getState());   
  16.     }   
  17.   
  18. }  
public class Client {

	public static void main(String[] args) {
		Shape shape = new Shape(1);

		Key key = new Key(shape);

		// 克隆了钥匙
		Key newKey = (Key) key.clone();
		
		Shape newShape = newKey.getShape();
		
		newShape.setState(0);

		System.out.println(key.getShape().getState());
	}

}


程序会在控制台打印  "0";

修改了克隆后的新的钥匙的State,不过原来的钥匙的State也发生了变化。也就是说前后两个钥匙的状态发生了联系,这个与原型模式是相违背的。

上述的那个Clone()方法在java中叫"影子克隆",对所有状态进行的克隆,叫做"深度克隆"。我们来继续改写上边的例子。

Java代码 复制代码  收藏代码
  1. public class Shape implements Cloneable {   
  2.     private int state = 0;   
  3.   
  4.     public Shape(int state) {   
  5.         this.state = state;   
  6.     }   
  7.   
  8.     public int getState() {   
  9.         return state;   
  10.     }   
  11.   
  12.     public void setState(int state) {   
  13.         this.state = state;   
  14.     }   
  15.   
  16.     //实现Clone()方法   
  17.     public Object clone() {   
  18.         Shape obj = null;   
  19.         try {   
  20.             obj = (Shape) super.clone();   
  21.         } catch (CloneNotSupportedException e) {   
  22.         }   
  23.   
  24.         return obj;   
  25.     }   
  26. }   
  27.   
  28. public class Key implements Cloneable {   
  29.     // 使用一个整形变量来代表钥匙的形状吧   
  30.     private Shape shape = null;   
  31.   
  32.     public Key(Shape shape) {   
  33.         this.shape = shape;   
  34.     }   
  35.   
  36.     public Shape getShape() {   
  37.         return shape;   
  38.     }   
  39.   
  40.     public void setShape(Shape shape) {   
  41.         this.shape = shape;   
  42.     }   
  43.   
  44.     public Object clone() {   
  45.         Key obj = null;   
  46.         try {   
  47.             obj = (Key) super.clone();   
  48.         } catch (CloneNotSupportedException e) {   
  49.         }   
  50.            
  51.         // 加入了Shape的Clone   
  52.         obj.setShape((Shape) shape.clone());   
  53.         return obj;   
  54.     }   
  55. }   
  56.   
  57. public class Client {   
  58.   
  59.     public static void main(String[] args) {   
  60.         Shape shape = new Shape(1);   
  61.   
  62.         Key key = new Key(shape);   
  63.   
  64.         // 克隆了钥匙   
  65.         Key newKey = (Key) key.clone();   
  66.            
  67.         Shape newShape = newKey.getShape();   
  68.            
  69.         newShape.setState(0);   
  70.   
  71.         System.out.println(key.getShape().getState());   
  72.     }   
  73.   
  74. }  
public class Shape implements Cloneable {
	private int state = 0;

	public Shape(int state) {
		this.state = state;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	//实现Clone()方法
	public Object clone() {
		Shape obj = null;
		try {
			obj = (Shape) super.clone();
		} catch (CloneNotSupportedException e) {
		}

		return obj;
	}
}

public class Key implements Cloneable {
	// 使用一个整形变量来代表钥匙的形状吧
	private Shape shape = null;

	public Key(Shape shape) {
		this.shape = shape;
	}

	public Shape getShape() {
		return shape;
	}

	public void setShape(Shape shape) {
		this.shape = shape;
	}

	public Object clone() {
		Key obj = null;
		try {
			obj = (Key) super.clone();
		} catch (CloneNotSupportedException e) {
		}
		
		// 加入了Shape的Clone
		obj.setShape((Shape) shape.clone());
		return obj;
	}
}

public class Client {

	public static void main(String[] args) {
		Shape shape = new Shape(1);

		Key key = new Key(shape);

		// 克隆了钥匙
		Key newKey = (Key) key.clone();
		
		Shape newShape = newKey.getShape();
		
		newShape.setState(0);

		System.out.println(key.getShape().getState());
	}

}


这次的结果就是"1"了。

最后,给出原型模式的类图:


  • 大小: 16.5 KB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值