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引用的拷贝是深拷贝