享元模式

来源:互联网 发布:pc安装mac系统 编辑:程序博客网 时间:2024/05/31 19:21

简介

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。


案例


坦克大战设计

每个坦克都是一个对象

以下两种可以是共享的 那么我么可以称他们为:内部状态

  1. 型号
  2. 颜色

另外一些则是不可共享的 我们称之为:外部状态

  1. 坐标

代码实现

享元设计模式一般包括以下的四块内容


  • FlyWeight 抽象享元类

这个通常是一个接口或者是一个抽象类,这个可以提供内部状态,设置外部状态。
我这边为了简洁,只写一个内部状态。

 public interface TankFlyWeight {    void setColor(String color);    String getColor();    void display(Coordinate coordinate);}


  • ConcreteFlyWeight具体享元类

具体享元类主要是为内部状态,也就是 共有的状态 提供一个存储的地方
    class ConcreateTank implements TankFlyWeight{    private String  model;    private String color;    public void setColor(String color) {        this.color = color;    }    public ConcreateTank(String color) {        super();        this.color = color;    }    public void display(Coordinate coordinate) {        System.out.println("坦克颜色:"+color);        System.out.println("坦克位置:"+coordinate.getX()+"=="+coordinate.getY());    }    public String getColor() {        // TODO Auto-generated method stub        return color;    }


  • UnsharedConcreateFlyWeight 非共享享元类

用于存储外部状态,也就是经常改变的状态

public class Coordinate {    private int x,y;    public Coordinate(int x, int y) {        super();        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;    }}


  • FlyWeightFactory 享元工厂类

创建并管理享元对象,一般是键值对的形式
import java.util.HashMap;import java.util.Map;public class TankFlyWeightFactory {    private static Map<String, TankFlyWeight> map = new HashMap<String, TankFlyWeight>();    public static TankFlyWeight getTank(String color) {            if (map.get(color)!=null) {                return map.get(color);            }            else {                TankFlyWeight tankFlyWeight = new ConcreateTank(color);                map.put(color, tankFlyWeight);                return  map.get(color);            }    }}


  • 最后 定义一个客户类进行测试

创建一个客户类,通过享元工厂进行生产取出
public class Client {    public static void main(String[] args) {        TankFlyWeight tank1 = TankFlyWeightFactory.getTank("黄色");        TankFlyWeight tank2 = TankFlyWeightFactory.getTank("黄色");        System.out.println(tank1);        System.out.println(tank2);        tank1.display(new Coordinate(10, 12));        tank2.display(new Coordinate(13,15));    }}
输出结果是 com.guxiang.flyweight.ConcreateTank@5d888759com.guxiang.flyweight.ConcreateTank@5d888759坦克颜色:黄色坦克位置:10==12坦克颜色:黄色坦克位置:13==15

我们可以看到,两个对象的 hashcode值是一样的,这证明它们其实是同一个对象,这样就避免了内存中存放过多的相似的对象,而导致内存不够用的情况下。


UML图实现如下
这里写图片描述

例子

  1. 享元模式在身边随处可见,最常用的要属 String类 string类中有一个常量池的概念,其内部也是一个享元设计模式实现的。
  2. 常见的还有 线程池 ThreadLocal
  3. 以及数据连接池
0 0