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中常见,希望对大家有所帮助!

    推荐阅读