设计模式 原型模式

原型模式(Prototype)

  • 用于创建重复的对象,同时又能保证性能。
  • 本体给外部提供一个克隆体进行使用
    在这里插入图片描述

原型模式的代码实现

  • Student类,实现Cloneable接口,表明该类允许被克隆
/**
 * 当前类的实例,允许被克隆
 */
@Data
public class Student  implements Cloneable{

    private String name;
    private Integer age;
    private ClassInfo classInfo;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

    /**
     * 重新创建一个学生,赋予克隆体所有属性
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        Student student = new Student();
        student.setName(name);
        student.setAge(age);
        student.setClassInfo(classInfo);
        return student;
    }

}
  • 模拟从数据库中查询数据,然后克隆该数据,以防止某个用户修改对其他用户可见
public class SchoolMybatis {

    //缓存student.序列化和反序列化-深克隆
    private Map<String,Student> studentCache = new HashMap<>();

    /**
     * 从数据库查数据
     * @return
     */
    public Student getStudent(String studentName) throws Exception {
        Student student = null;
        //缓存中没有
        if(!studentCache.containsKey(studentName)){
            //查询数据库
            student = getStudentFromDb(studentName);
        }else {
            //从缓存中直接拿,脏缓存问题
            //原型已经拿到,但是不能直接给。(本人)
            student = studentCache.get(studentName);
            System.out.println("从缓存中拿到的是:"+student);
            //从这个对象快速得到一个克隆体(克隆人)==原型模式
            student = (Student) student.clone();
        }

        return student;
    }


    private Student getStudentFromDb(String studentName) throws Exception{
        System.out.println("从数据库查到:"+studentName);
        Student student = new Student();
        student.setName(studentName);
        student.setAge(18);
        ClassInfo classInfo = new ClassInfo(1,"数学");
        student.setClassInfo(classInfo);
        //给缓存中放一个clone
        studentCache.put(student.getName(), (Student) student.clone());
        return student;
    }

}
  • 测试原型模式
  //得到的是克隆体
        Student zhangsan = mybatis.getStudent("zhangsan");
        System.out.println("1==>"+zhangsan);
        zhangsan.setName("lisi");
        System.out.println("zhangsan自己改了:"+zhangsan);
        //得到的是克隆体
        Student zhangsan2 = mybatis.getStudent("zhangsan");
        System.out.println("2-->"+zhangsan2);
        //得到的是克隆体
        Student zhangsan3 = mybatis.getStudent("zhangsan");
        System.out.println("3-->"+zhangsan3);
        //得到的是克隆体
        Student zhangsan4 = mybatis.getStudent("zhangsan");
        System.out.println("4-->"+zhangsan4);
        System.out.println(zhangsan == zhangsan3);
  • 测试结果
从数据库查到:zhangsan
1==>Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))
zhangsan自己改了:Student(name=lisi, age=18, classInfo=ClassInfo(className=数学, id=1))

从缓存中拿到的是:Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))
2-->Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))

从缓存中拿到的是:Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))
3-->Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))

从缓存中拿到的是:Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))
4-->Student(name=zhangsan, age=18, classInfo=ClassInfo(className=数学, id=1))

什么场景下使用原型模式

  • 资源优化
  • 性能和安全要求
  • 一个对象多个修改者的场景
  • 一个多项需要提供给其他对象访问,而且各个调用者都需要对其值修改,此种情况下,可以考虑使用原型模式拷贝多个对象供调用者进行使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值