把努力当成一种习惯,而不是三分钟热度。坚持才是王道,每一个你羡慕的收获,都是别人努力用心拼来的。你可以抱怨,也可以无视,但记住,不努力,连输的资格都没有!
一、原型模式简介
原型模式属于设计模式中的创建型模式。原型模式使用较小的代价创建重复的对象,提供了一种创建对象的最佳方式。
原型模式通常使用克隆来创建对象,它解决的问题是有些对象的创建代价过大的问题,例如一个对象需要花费较大的代价查询数据库后创建,这种情况我们就可以缓存这个对象,下一次创建时直接返回它的克隆,需要时再更新数据库,以此来减少数据库的调用。
二、实现方式
代码实现共有三个类:
- Prototype: 原型
- PrototypeCache: 原型管理类
- Client: 客户端
Prototype: 原型
import java.io.Serializable;
import java.util.List;
/**
* 原型(通常情况下直接创建此类的对象代价很大)
*
* @author ZhengNC
* @date 2020/7/22 15:36
*/
public class Prototype implements Serializable {
private Integer id;
private String name;
private List<String> objs;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getObjs() {
return objs;
}
public void setObjs(List<String> objs) {
this.objs = objs;
}
@Override
public String toString() {
return "Prototype{" +
"id=" + id +
", name='" + name + '\'' +
", objs=" + objs +
'}';
}
}
PrototypeCache: 原型管理类
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 获取原型
* 设计成单例模式有利于节省系统资源,还可以更方便的管理原型
*
* @author ZhengNC
* @date 2020/7/22 15:44
*/
public class PrototypeCache {
private Map<Integer, Prototype> cache = new HashMap<>();
private PrototypeCache(){}
private static class SingletonHolder{
private static PrototypeCache INSTANCE = new PrototypeCache();
}
public static PrototypeCache getInstance(){
return SingletonHolder.INSTANCE;
}
/**
* 根据缓存中的原型获取一个对象
*
* @param id
* @return
*/
public Prototype getPrototype(Integer id){
Prototype p = cache.get(id);
try {
return clone(p);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 创建一些原型
*/
public void loadCache(){
Prototype p1 = new Prototype();
p1.setId(1);
p1.setName("p1");
List<String> list1 = new ArrayList<>();
list1.add("p1_1");
list1.add("p1_2");
list1.add("p1_3");
p1.setObjs(list1);
cache.put(p1.getId(), p1);
Prototype p2 = new Prototype();
p2.setId(2);
p2.setName("p2");
List<String> list2 = new ArrayList<>();
list2.add("p2_1");
list2.add("p2_2");
list2.add("p2_3");
p2.setObjs(list2);
cache.put(p2.getId(), p2);
}
/**
* 深克隆对象
*
* @param obj
* @param <T>
* @return
*/
private <T extends Serializable> T clone(T obj) {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
T t = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
bais = new ByteArrayInputStream(baos.toByteArray());
ois = new ObjectInputStream(bais);
t = (T)ois.readObject();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (oos != null) {
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bais != null) {
bais.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (ois != null) {
ois.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return t;
}
}
Client: 客户端
/**
* 使用原型的客户端
*
* @author ZhengNC
* @date 2020/7/22 15:52
*/
public class Client {
public static void main(String[] args) {
PrototypeCache cache = PrototypeCache.getInstance();
//创建一些原型对象
cache.loadCache();
//根据原型获取一个对象
Prototype p1 = cache.getPrototype(1);
System.out.println(p1);
//修改获取的对象
p1.setName("asd");
p1.getObjs().add("aaa");
System.out.println(p1);
//再次根据同一个原型获取对象
Prototype p1Again = cache.getPrototype(1);
System.out.println(p1Again);
}
}
运行结果
Prototype{id=1, name='p1', objs=[p1_1, p1_2, p1_3]}
Prototype{id=1, name='asd', objs=[p1_1, p1_2, p1_3, aaa]}
Prototype{id=1, name='p1', objs=[p1_1, p1_2, p1_3]}