場景:
- 內存屬於稀缺資源,不要隨便浪費。如果遊很多個完全相同或類似的對象,我們可以通過享元模式,節省內存。
核心
- 享元模式以共享的方式高效地支持大量細粒度對象的重用。
- 享元對象能做到共享的關鍵是區分了內部狀態和外部狀態。
- 內部狀態:可以共享,不會隨環境變化而變化
- 外部狀態:不可以共享,會隨環境變化而變化
圍棋軟件設計
- 每個棋子都是一個對象,有如下屬性
- 顏色
- 形狀
- 大小
- 位置
- 其中1,2,3這些是可以共享的,稱之爲:內部狀態
- 4 是不可以共享的,稱之爲外部狀態
享元模式實現:
- FlyweightFactory享元工廠類
- FlyWeight抽象享元類
- 通常是一個接口或者抽象類,聲明公共方法,這些方法可以向外界提供對象的內部狀態,設置外部狀態。
- ConcreteFlyWeight具體享元類
- UnsharedConcreteFlyWeight非共享享元類
享元模式實現的UML圖
享元模式在開發中使用的場景:
- 享元模式由於其共享的特性,可以在任何“池”中操作,比如:線程池、數據連接池。
- String類的設計也是享元模式
優點
- 極大的減少了內存中對象的數量
- 相同或相似對象內存中只有一份,極大的節約資源,提高系統性能
- 外部狀態相對獨立,不影響內部狀態。
優點
- 模式較爲複雜,使程序邏輯複雜化
- 爲了節省內存,共享了內部狀態,分離了外部狀態,而讀取外部狀態使運行時間變長。用時間換取了空間。
一種實現
package com.coderbean.flyweight;
/**
* 享元類
* Created by Chang on 15/10/2.
*/
public interface ChessFlyWeightt {
void setColor(String color);
String getColor();
void display(Coordinate c);
}
class ConcreteChess implements ChessFlyWeightt {
private String color;
public ConcreteChess(String color) {
this.color = color;
}
@Override
public void setColor(String color) {
this.color = color;
}
@Override
public String getColor() {
return this.color;
}
@Override
public void display(Coordinate c) {
System.out.println("棋子顏色"+ this.color);
System.out.println("棋子位置"+ c.getX()+"---"+c.getY());
}
}
package com.coderbean.flyweight;
import java.util.HashMap;
import java.util.Map;
/**
* 享元工廠類
* Created by Chang on 15/10/2.
*/
public class ChessFlyWeightFactory {
private static Map<String, ChessFlyWeightt> map = new HashMap<String,ChessFlyWeightt>();
public static ChessFlyWeightt getChess(String color) {
if(map.get(color) != null) {
return map.get(color);
}else{
ChessFlyWeightt cfw = new ConcreteChess(color);
map.put(color, cfw);
return cfw;
}
}
}
package com.coderbean.flyweight;
/**
* 外部狀態UnSharedConcreteFlyWeight
* Created by Chang on 15/10/2.
*/
public class Coordinate {
private int x,y;
public Coordinate(int y, int x) {
this.y = y;
this.x = x;
}
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;
}
}
package com.coderbean.flyweight;
/**
* Created by Chang on 15/10/2.
*/
public class Client {
public static void main(String[] args) {
ChessFlyWeightt chess1 = ChessFlyWeightFactory.getChess("Black");
ChessFlyWeightt chess2 = ChessFlyWeightFactory.getChess("Black");
System.out.println(chess1);
System.out.println(chess2);
System.out.println("增加外部狀態的處理=======");
chess1.display(new Coordinate(10,10));
chess2.display(new Coordinate(100,20));
}
}