什么是享元模式

享元模式是一种共享对象的结构型模式。对象的某些状态或属性是不变的,比如要显示一个文档,文档上面多处引用了同一张图片,图片是一样的,只是所处位置不同而已。如果为每张图片都创建对象,那么将消耗很大内存。这个时候我们可以使用享元模式,所有位置引用的图片都是同一个对象,只需在显示时对图片的位置信息进行赋值即可。在Java中,String就使用了享元模式。

享元模式的结构

  • FlyWeight:抽象享元类
  • ConcreteFlyWeight:具体享元类
  • FlyWeightFactory:享元工厂类

一个享元模式实例

一个文本编辑器可以编辑带图片(Picture)的文档,为了节省内存,使用享元模式处理图片,这样对于同一张图片在文档中不同位置(Pos)所引用的都是同一个对象。

实例代码

Pos

public class Pos {
    private int x;
    private int y;

    public Pos(int x,int y){
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

Picture

public interface Picture {
   public void display(Pos pos);
}

ConcretePicture

public class ConcretePicture implements Picture {

    private String name;
    public ConcretePicture(String name){
        this.name = name;
    }

    @Override
    public void display(Pos pos) {
        System.out.println("name:" + name + ", x:" + pos.getX() + ", y:" + pos.getY());
    }
}

PictureFactory

public class PictureFactory {

    private Map<String,Picture> pictureMap = null;

    private static PictureFactory ourInstance = new PictureFactory();

    public static PictureFactory getInstance() {
        return ourInstance;
    }

    private PictureFactory() {
        pictureMap = new HashMap<String,Picture>();
    }

    public Picture getPicture(String key){
        if (pictureMap.containsKey(key)){
            return pictureMap.get(key);
        }else{
            Picture picture = new ConcretePicture(key);
            pictureMap.put(key,picture);
            return picture;
        }
    }
}

Clinet

public class Client {
    public static void main(String[] args){
        Picture picture1 = PictureFactory.getInstance().getPicture("bird");
        Picture picture2 = PictureFactory.getInstance().getPicture("bird");
        Picture picture3 = PictureFactory.getInstance().getPicture("bird");
        Picture picture4 = PictureFactory.getInstance().getPicture("bird");

        picture1.display(new Pos(1,1));
        picture2.display(new Pos(1,3));
        picture3.display(new Pos(2,1));
        picture4.display(new Pos(3,2));
    }
}

(完)