我认为补这一段是非常有必要的,所以呢就给大家补了一下,对于原型模式的理解,我们想象一下,如果和单例结合起来应用的话,
会怎么样呢,那这个问题,也有可能会被问到,如何破坏单例模式,那通过原型模式的克隆呢,也是一种方法,那现在我们来操作一下,
很简单
package com.learn.design.pattern.creational.singleton;
import java.io.Serializable;
/**
* 我们现在让这个类实现Cloneable接口
*
*
* @author Leon.Sun
*
*/
public class HungrySingleton implements Serializable,Cloneable{
private final static HungrySingleton hungrySingleton;
static{
hungrySingleton = new HungrySingleton();
}
private HungrySingleton(){
if(hungrySingleton != null){
throw new RuntimeException("单例构造器禁止反射调用");
}
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
private Object readResolve(){
return hungrySingleton;
}
/**
* 然后让他重写克隆方法
* 注意克隆方法重写之后
* 它是protected
* 这么一个权限
* 那里面的实现先不动
* 然后来到Test里边
*
*
*
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return getInstance();
}
}
package com.learn.design.pattern.creational.prototype.clone;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.learn.design.pattern.creational.singleton.HungrySingleton;
/**
*
* @author Leon.Sun
*
*/
public class Test {
public static void main(String[] args) throws CloneNotSupportedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// Date birthday = new Date(0L);
// Pig pig1 = new Pig("佩奇",birthday);
// Pig pig2 = (Pig) pig1.clone();
// System.out.println(pig1);
// System.out.println(pig2);
// pig1.getBirthday().setTime(666666666666L);
// System.out.println(pig1);
// System.out.println(pig2);
/**
* 我们就用最简单的单例
*
*
*/
HungrySingleton hungrySingleton = HungrySingleton.getInstance();
/**
* 我们直接还用反射
* 选择反射包下的
* hungrySingleton.getClass()获取他的class
* 然后获取getDeclaredMethod("clone")
*
*
*/
Method method = hungrySingleton.getClass().getDeclaredMethod("clone");
/**
* 然后我们来设置他的权限
* 我们把他的权限打开
*
*
*/
method.setAccessible(true);
/**
* 调用它的invoke
* method.invoke
* invoke哪个对象呢
* 就是hungrySingleton这个对象
* 参数没有
* 所以第二个参数就不加
* 这里出现了一个强转的报错
* 我们直接强转他
* 我们run一下
* 非常简单
* 结果已经出来了
* 我们看到这两个对象并不是同一个对象
* 那怎么解决呢
* 很简单
* 要么我们这个单例不去实现cloneable接口
* 或者如果实现了
* 直接调用getInstance()方法
* 我们再run一下
* 结果已经出来了
* 这两个类是同一个对象
* 所以呢学完原型模式的时候
* 我们再回想一下
* 单例模式
* 那这些也都是想通的
* 那如何防止克隆破坏呢
* 只要我们不实现cloneable接口的话
* 或者我们实现了他
* 然后呢重写
* 重写这个对象的实例
* 这样的话就不怕克隆破坏了
* 那么回来
* 希望通过这一段
* 可以再回想一下
* 对于破坏单例模式
* 会有哪些方案呢
* 另外就是设计模式和设计模式之间
* 他们之间并不是独立存在的
* 我们学习完这个课程之后
* 应该多思考
* 融会贯通
* 那在很多源码中
* 也不只单单使用一个设计模式
* 也会把很多设计模式结合在一块
* 那我们在实际解决业务的时候呢
* 也会碰到这样的业务场景
* 可能不仅仅使用一个设计模式
*
*
*
*/
HungrySingleton cloneHungrySingleton = (HungrySingleton) method.invoke(hungrySingleton);
System.out.println(hungrySingleton);
System.out.println(cloneHungrySingleton);
}
}