java设计模式之享元模式

内存溢出,司空见惯

书是好东西,我们当然要多读书,但是如果你想看的书没有怎么办,当然是去图书馆借咯,省钱嘛!好,看代码如何实现,类图如下:

java设计模式之享元模式_第1张图片

看类图很简单的一个工厂模式嘛,是的!下面看代码实现:

书类:

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一个,相当于每个人来借书,你都买本新的借给人家,为什么不先查看图书馆内部有没有这本书,如果有,直接借给他就行,干嘛要买一本呢是不是?下面我们来修改一下这个糟糕的代码!

保留Book类不变
修改BookFactory类:

public class BookFactory {
    public static HashMap<String,Book> bookList = new HashMap<String, Book>();
    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设计模式,内存溢出,享元模式)