java设计模式之享元模式
内存溢出,司空见惯 书是好东西,我们当然要多读书,但是如果你想看的书没有怎么办,当然是去图书馆借咯,省钱嘛!好,看代码如何实现,类图如下:
看类图很简单的一个工厂模式嘛,是的!下面看代码实现:
书类:
public class Book {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}}
工厂类(相当于图书馆):
public class BookFactory {
public static Book getBook(){
return new Book();
}
}
场景类(相当于我们个人要去图书馆借书):
public class Client {
public static void main(String[] args) {
//从工厂中获得一个对象
SignInfo signInfo = SignInfoFactory.getSignInfo();
//进行其他业务处理
}
}
这么简单,但是简单为什么会出现问题呢?而且这样写也没有问题呀,很标准的工厂方法模式,应该不会有大问题,但是就是用了这个工厂模式,内存突然飙升到1.4GB,新的对象申请不到内存空间,于是出现OutOfMemory,其中Book类的对象就有400MB!
大家想想,如果一个人用当然没问题,但是如果是国家图书馆呢,成千上万的人同时借书,那这个getBook()方法得产生多少类!大家又说了,java不是能自动回收内存吗?大家不要依靠这个东西,毕竟优先级太低了,不一定什么时候回收。
好,现在我们来想办法解决这个问题,大家想想,上面的工厂制造书是不是直接new一个,相当于每个人来借书,你都买本新的借给人家,为什么不先查看图书馆内部有没有这本书,如果有,直接借给他就行,干嘛要买一本呢是不是?下面我们来修改一下这个糟糕的代码!
【java设计模式之享元模式】保留Book类不变
修改BookFactory类:
public class BookFactory {
public static HashMap bookList = new HashMap();
public static Book getBook(String bookName){
if(bookList.containsKey(bookName)){//如果有这本书,直接取出来借出去。
System.out.println("发现图书馆里有"+bookName+"----直接借出去");
return bookList.get(bookName);
}else{
System.out.println("发现图书馆里没有"+bookName+"----买一本,借出去");
Book book =new Book();
book.setName(bookName);
bookList.put(bookName, book);
return book;
}
}
@Deprecated
public static Book getBook(){
return new Book();
}
}
场景类:
public class Client {
public static void main(String[] args) {
for(int i=0;
i<5;
i++){
BookFactory.getBook("书本"+i);
}
BookFactory.getBook("书本3");
}
}
输出如下:
发现图书馆里没有书本0----买一本,借出去
发现图书馆里没有书本1----买一本,借出去
发现图书馆里没有书本2----买一本,借出去
发现图书馆里没有书本3----买一本,借出去
发现图书馆里没有书本4----买一本,借出去
发现图书馆里有书本3----直接借出去
通过这样的改造后,我们想想内存中有多少个Book对象?是不是少多了,优化了非常多,系统运行得非常稳定,CPU占用率也下降了
读者需要注意一点的是@Deprecated注解,不要有删除投产中代码的念头,如果方法或类确实不再使用了,增加该注解,表示该方法或类已经过时,尽 量不要再使用了,我们应该保持历史原貌,同时也有助于版本向下兼容,特别是在产品级研发中。
结尾 这就是享元模式,在java中常见,希望对大家有所帮助!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用
- Java基础-高级特性-枚举实现状态机