享元模式

简介

享元模式(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@5d888759
com.guxiang.flyweight.ConcreateTank@5d888759
坦克颜色:黄色
坦克位置:10==12
坦克颜色:黄色
坦克位置:13==15

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


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

例子

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值