簡介
享元模式(Flyweight Pattern)主要用於減少創建對象的數量,以減少內存佔用和提高性能。這種類型的設計模式屬於結構型模式,它提供了減少對象數量從而改善應用所需的對象結構的方式。
案例
坦克大戰設計
每個坦克都是一個對象
以下兩種可以是共享的 那麼我麼可以稱他們爲:內部狀態
- 型號
- 顏色
另外一些則是不可共享的 我們稱之爲:外部狀態
- 座標
代碼實現
享元設計模式一般包括以下的四塊內容
- 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圖實現如下
例子
- 享元模式在身邊隨處可見,最常用的要屬 String類 string類中有一個常量池的概念,其內部也是一個享元設計模式實現的。
- 常見的還有 線程池 ThreadLocal
- 以及數據連接池