享元模式
享元模式也是为了减少对象的创建,进而减少内存的重复利用而被使用的,这个和之前我们学过的单例模式,还有原型模式有着近似的相同之处,
这里大致复习一下,
单例模式:系统内只存在一个对象,比如windows里面只会存在一个任务管理器,一样的道理。
原型模式:原型模式则是通过实现Cloneable接口,调用Object 的clone方法,生成一个相同的对象。
而享元模式,有一个关键词,那就是共享,这些对象创建好之后会被共享,比如我需要一个圆形,要是内存里面已经存在这个对象,直接将这个对象的引用回传给我直接使用即可。
这里需要灵魂画师来操作一波!
这里模拟一个常见的windows窗口程序,比如我们可以用JAVA的Swing组件来画出窗口,这里的需求是这样的,我需要在这个窗口内画出100个圆形,总不可能你一个对象一个对象的来创建把,并且把他们摆放在不同的位置,
这里就按照这个需求,我们来操作一波
代码理解
形状接口,用来定义画出的形状,这里我们只是画一个圆形为例
public interface Shape { //画出形状 void draw(); }
创建一个圆形对象实现形状接口,它可以画出圆形,有一些自己的属性,比如坐标,以及画出来的颜色
public class circle implements Shape { //x坐标 private int x; //y坐标 private int y; //圆的颜色 private String color; @Override public void draw() { System.out.println("画出圆形在x:"+x+"y:"+y+"颜色:"+color); } //get and set }
一个形状的工厂,用于创建出圆形这个形状,map是一个集合,用于储存创建出来的共享对象,当需要加载一个对象的时候,先去查找这个颜色的对象存在不,存在则直接返回,不存在则创建后返回,并且
保存创建的那个对象,以便于下次直接使用。
public class ShapeFactory { private static Map<String, circle> map = new HashMap<>(); public static Shape getShape(String color) { circle shape = map.get(color); //共享对象里面没有,则创建一个下次用 if (shape == null) { shape = new circle(); shape.setColor(color); map.put(color, shape); System.out.println("创建了一个新圆:color="+color); } return shape; } }
开始测试,创建20个对象,分别是数组里面颜色的圆形,有则从共享的对象内部返回,没有则创建返回,
private static String[] colors = new String[]{"red", "blue", "yellow", "black"}; public static void main(String[] args) { for (int i = 0; i < 20; i++) { int index = (int)Math.round(Math.random()*3); String color = colors[index]; circle temp = (circle) ShapeFactory.getShape(color); temp.draw(); } }
//结果 可以看出在创建好了需要的对象后,后面再次调用,直接返回即可。无需再次创建