微网站 建设方案,网站制作公司在哪里找,教育机构网站,电子商务网站帮助中心该怎么更好地设计设计模式—创建型模式之原型模式
原型模式#xff08;Prototype Pattern#xff09;用于创建重复的对象#xff0c;同时又能保证性能。
本体给外部提供一个克隆体进行使用。
比如我们做一个SjdwzMybatis#xff0c;用来操作数据库#xff0c;从数据库里面查出很多记录Prototype Pattern用于创建重复的对象同时又能保证性能。
本体给外部提供一个克隆体进行使用。
比如我们做一个SjdwzMybatis用来操作数据库从数据库里面查出很多记录其中很多记录改变很少。每次查数据库把所有数据都封装一个对象然后返回。假设有很多线程来查如下记录
Student student new Student(张三,男)如果每次都创建对象封装并返回这样系统就会有很多student这样就会浪费内存。
Student类如下
public class Student {private String name;private Integer age;public Student() {System.out.println(创建了Student对象);}//省略getter() 、 setter() toString()
}
SjdwzMybatis如下
public class SjdwzMybatis {/*** 通过name获取Student*/public Student queryStudent(String name){return queryStudentFromDB(name);}/*** 演示从数据库查Student*/private Student queryStudentFromDB(String name) {//简单演示查询到了System.out.println(从数据库查询到了:name);Student student new Student();student.setName(name);student.setAge(16);return student;}
}测试类
public class ProtoTypeTest {public static void main(String[] args) {SjdwzMybatis sjdwzMybatis new SjdwzMybatis();Student stu1 sjdwzMybatis.queryStudent(zhangsan);Student stu2 sjdwzMybatis.queryStudent(zhangsan);Student stu3 sjdwzMybatis.queryStudent(zhangsan);Student stu4 sjdwzMybatis.queryStudent(zhangsan);}
}这样会有大量具有相同属性的student被外部创建同时查库次数过多。
我们是否能设计一个缓存来保存查过的内容再查相同的记录时可以很快拿到原来的原型对象呢
那我们的SjdwzMybatis便变成了如下代码
public class SjdwzMybatis {//缓存private MapString,Student stuCache new HashMap();/*** 通过name获取Student*/public Student queryStudent(String name){if(stuCache.containsKey(name)){return stuCache.get(name);}else{return queryStudentFromDB(name);}}/*** 演示从数据库查Student*/private Student queryStudentFromDB(String name) {//简单演示查询到了System.out.println(从数据库查询到了:name);Student student new Student();student.setName(name);student.setAge(16);//存入内存stuCache.put(name,student);return student;}
}但是这是否会有问题呢 如果我们把stu1的属性改了那么stu2、stu3、stu4的属性也会被改变这会影响到我们缓存里的数据造成脏缓存数据同时我们查出来的内容并没有提交修改不能就把原数据给修改掉。
原型模式
我们把Student修改成如下代码这便是原型模式
//实现Cloneable接口这只是一个标记还需要重写clone()方法
public class Student implements Cloneable{private String name;private Integer age;//重写clone方法Overrideprotected Object clone() throws CloneNotSupportedException {Student student new Student();student.setName(this.name);student.setAge(this.age);return student;}
}然后SjdwzMybatis修改为如下代码
public class SjdwzMybatis {//缓存private MapString,Student stuCache new HashMap();/*** 通过name获取Student*/public Student queryStudent(String name) throws CloneNotSupportedException {if(stuCache.containsKey(name)){return (Student) stuCache.get(name).clone();}else{return queryStudentFromDB(name);}}/*** 演示从数据库查Student*/private Student queryStudentFromDB(String name) throws CloneNotSupportedException {//简单演示查询到了System.out.println(从数据库查询到了:name);Student student new Student();student.setName(name);student.setAge(16);//存入内存stuCache.put(name,(Student) student.clone());return student;}
}从数据库查出来放入缓存的对象与从缓存取出来的都是clone出来的。
可以看到我们对stu1修改并不会影响其他的数据了。