设计模式——原型模式
1原型模式的定义
原型模式:原型模式(Prototype Pattern)就是根据现有的实例生成新的实例的一种模式。在实际应用中可能对象的生成很复杂,可能对象中包含的对象太多,总之对象的生成比较复杂,此时就可以根据原型模式通过克隆的方式生成新的对象。
No BB,Show Code!
2原型模式的代码实现
2-1定义接口
定义一个继承了Cloneable的产品接口Product,在此接口中也定义了克隆生成新的对象的方法,代码如下:
package designPattern.test.prototype;
import java.io.Serializable;
/**
* 产品接口,继承于Cloneable
*/
public interface Product extends Cloneable, Serializable {
//使用方法
void use(String s);
//创建克隆对象方法
Product createClone();
}
2-2定义具体的产品
在本例中定义了3种具体的产品实现Product接口,分别为Bike、Car、Parking,代码如下:
Bike:
package designPattern.test.prototype;
/**
* 自行车对象
*/
public class Bike implements Product {
private String owner;
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Bike() {
}
public Bike(String owner) {
this.owner = owner;
}
@Override
public void use(String s) {
System.out.println("=====Bike====" + s);
}
//调用clone方法并返回
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (Exception e) {
e.printStackTrace();
}
return p;
}
public Object clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
Car:
package designPattern.test.prototype;
/**
* 汽车对象
*/
public class Car implements Product {
private String owner;
public Car() {
}
public Car(String owner) {
this.owner = owner;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
@Override
public void use(String s) {
System.out.println("=====Car====" + s);
}
//调用clone方法并返回
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (Exception e) {
e.printStackTrace();
}
return p;
}
public Object clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
Parking:
package designPattern.test.prototype;
import java.util.List;
import java.util.Map;
/**
* 停车场类
*/
public class Parking implements Product {
private String name;
private List<Bike> bikeList;
private List<Car> carList;
private Map<String, Object> map;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Bike> getBikeList() {
return bikeList;
}
public void setBikeList(List<Bike> bikeList) {
this.bikeList = bikeList;
}
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> carList) {
this.carList = carList;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
@Override
public void use(String s) {
System.out.println("-----Parking-----" + s);
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (Exception e) {
e.printStackTrace();
}
return p;
}
public Object clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
2-3定义管理类
定义一个管理类用于管理通过克隆方式生成新对象,代码如下:
package designPattern.test.prototype;
import java.util.HashMap;
import java.util.Map;
/**
* 管理类
*/
public class Manager {
private Map<String, Product> productMap = new HashMap();
//注册产品
public void register(String name, Product product) {
productMap.put(name, product);
}
//克隆出产品并返回
public Product create(String name) {
Product p = productMap.get(name);
return p.createClone();
}
}
3测试
测试代码如下:
package designPattern.test.prototype;
import com.google.common.collect.Lists;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 原型模式测试
*/
public class ProtoTypeTest {
@Test
public void testPrototype() {
Manager manager = new Manager();
Bike bike1 = new Bike("小明");
Bike bike2 = new Bike("小强");
Bike bike3 = new Bike("小红");
Car car1 = new Car("王总");
Car car2 = new Car("李总");
Car car3 = new Car("余总");
manager.register(bike1.getOwner(), bike1);
manager.register(bike2.getOwner(), bike1);
manager.register(bike3.getOwner(), bike1);
manager.register(car1.getOwner(), car1);
manager.register(car2.getOwner(), car2);
manager.register(car3.getOwner(), car3);
Bike bike1Clone = (Bike) manager.create(bike1.getOwner());
Parking parking = new Parking();
String name = "保安";
parking.setName(name);
parking.setBikeList(Lists.newArrayList(bike1, bike2, bike3));
parking.setCarList(Lists.newArrayList(car1, car2, car3));
Map<String, Object> map = new HashMap();
map.put("aa", "aa");
map.put("bb", 2);
map.put("cc", Lists.newArrayList(1.1, 2.2));
parking.setMap(map);
manager.register(parking.getName(), parking);
System.out.println(bike1 == bike1Clone);
Parking parkingClone = (Parking) manager.create("保安");
System.out.println(parking == parkingClone);
parking.getBikeList().add(bike1Clone);
System.out.println(parkingClone.getBikeList().size());
Parking parkingDeepClone = null;
try {
parkingDeepClone = (Parking) deepClone(parking);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(parking == parkingDeepClone);
parking.getBikeList().remove(bike2);
parking.getBikeList().remove(bike1);
System.out.println(parkingDeepClone.getBikeList().size());
}
/**
* 深度克隆方法:通过对象流的方式实现的深度克隆
*/
private Product deepClone(Product product) throws Exception {
//将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(product);
//从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (Product) oi.readObject();
}
}
打印结果:false
false
4
false
4
总结:使用原型模式需要注意的是如果没有重写clone方法的话,那么克隆就是浅克隆,即只是复制了复制了对象的引用并没有创建一个新的对象,在测试代码中通过原型模式克隆对象的方式克隆了parking得到parkingClone,但是修改parking对象的bikeList属性后,parkingClone的bikeList也变化了,可知浅克隆只是复制了引用,并没有创建新对象,而通过对象流的方式克隆则是深克隆,parkingDeepClone就是与parking完全是两个不同对象了!