设计模式详解(二)原型模式

1. 概念

原型模式达到以原型实例创建副本实例的目的即可,并不需要知道其原始类,也就是说,原型模式可以用对象创建对象,而不是用类创建对象,以此达到效率的提升

2. 代码示例

场景:根据一辆BMW汽车模型再创建出多辆BMW

package designpattern;

class Wheel{//轮子类
	double price;//轮子价格

	public Wheel(double price) {
		super();
		this.price = price;
	}

	@Override
	public String toString() {
		return "Wheel [price=" + price + "]";
	}
	
	
}
class Car implements Cloneable{
	String name;//汽车名称
	Wheel wheel;//汽车轮子
	@Override
	protected Car clone() throws CloneNotSupportedException {
		
		return (Car) super.clone();
	}

	public Car(String name, Wheel wheel) {
		super();
		this.name = name;
		this.wheel = wheel;
	}

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

}
public class PrototypeDemo {
	static Car carProtoType=new Car("BMW",new Wheel(100));
	public static void main(String[] args) throws CloneNotSupportedException {
		Car[] cars=new Car[3];
		for(int i=0;i<3;i++)
		{
			cars[i]=carProtoType.clone();
			System.out.println(cars[i]);
		}
		System.out.println("-------------");
		cars[0].wheel.price=200;
		for(int i=0;i<3;i++)
		{
			System.out.println(cars[i]);
		}
		System.out.println(cars[0]==cars[1]);
		System.out.println(cars[0].wheel==cars[1].wheel);
	}
}

上面代码中在Car类中重写了Object类中的clone方法,通过该方法可以调用该方法的对象的一个副本,省去了由类而生的再造过程
在这里插入图片描述

从运行结果来看,的却得到了3个副本,但是存在一个问题,只要修改了其中一辆车的轮胎价格,其他车的轮胎价格也会改变

		System.out.println(cars[0]==cars[1]);//false
		System.out.println(cars[0].wheel==cars[1].wheel);//true

从这两条输出语句可以看出,3辆车的轮胎引用指向的是一个对象,这就是浅拷贝

浅拷贝:基本类型的值会被赋值,引用类型的值也只是拷贝了引用的副本,所以这些引用的副本指向的对象都是同一个

代码修改如下:

package designpattern;



class Wheel implements Cloneable{//轮子类
	double price;//轮子价格

	public Wheel(double price) {
		super();
		this.price = price;
	}

	@Override
	public String toString() {
		return "Wheel [price=" + price + "]";
	}

	@Override
	protected Wheel clone() throws CloneNotSupportedException {
		
		return (Wheel) super.clone();
	}
	
	
	
}
class Car implements Cloneable{
	String name;//汽车名称
	Wheel wheel;//汽车轮子
	@Override
	protected Car clone() throws CloneNotSupportedException {
		
		Car car=(Car) super.clone();
		car.wheel=this.wheel.clone();;
		return car;
	}

	public Car(String name, Wheel wheel) {
		super();
		this.name = name;
		this.wheel = wheel;
	}

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

}
public class PrototypeDemo {
	static Car carProtoType=new Car("BMW",new Wheel(100));
	public static void main(String[] args) throws CloneNotSupportedException {
		Car[] cars=new Car[3];
	
		
		for(int i=0;i<3;i++)
		{
			cars[i]=carProtoType.clone();
			System.out.println(cars[i]);
		}
		System.out.println("-------------");
		cars[0].wheel.price=200;
		for(int i=0;i<3;i++)
		{
			System.out.println(cars[i]);
		}
		System.out.println(cars[0]==cars[1]);
		System.out.println(cars[0].wheel==cars[1].wheel);
	}
}

在这里插入图片描述

修改之后对wheel引用的拷贝是深拷贝

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodePanda@GPF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值