享元模式

簡介

享元模式(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. 以及數據連接池
發佈了43 篇原創文章 · 獲贊 91 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章