設計模式--享元模式FlyWeight(結構型)
1 定義:
1.1 定義:Use sharing to support large numbers of fine-grained objects efficiently.(使用共享物件可以有效地支援大量的細粒度的物件。)
細粒度物件:不可避免地使得物件數量多且性質相近,可將這些物件的資訊分為兩個部分:內部狀態(intrinsic)與外部狀態(extrinsic)。
內部狀態:物件可共享出來的資訊,儲存在享元物件的內部並且不會隨環境改變而改變。
外部狀態:物件得以依賴的一個標記:隨環境改變而改變、不可以共享的狀態,享元物件的外蘊狀態必須由由端儲存,並在享元物件被建立之後,在需要使用的時候再傳入到享元物件內部。
(理解舉例:享元模式在編輯器系統中大量使用。一個文編輯器往往會提供很多種字型,而通常的做法就是將每一個字母做成一個享元物件。享元物件的內蘊狀態就是這個字母,而字母在文字中的位置和字型風格等其他資訊則是外蘊狀態。比如,字母a可以出現在文字的很多地方,雖然這些字母a的位置和字型風格不同,但是所有這些地方使用的都是同一個字母物件。這樣一來,字母物件就可以在整個系統中共享。)
1.2 通用類圖:
Flyweight——抽象享元角色
一個產品的抽象類,同時定義出物件的外部狀態和內部狀態的介面或實現。
ConcreteFlyweight——具體享元角色
實現抽象角色定義的業務。該角色中需要注意的是內部狀態處理應該與環境無關,不應該出現一個操作改變了內部狀態,同時修改了外部狀態,這是不允許的。
UnsharedConcreteFlyweight——不可共享的享元角色
不存在外部狀態或者安全要求(如執行緒安全)不能夠使用共享技術的物件,該物件一般不會出現在享元工廠中。
FlyweightFactory——享元工廠
職責非常簡單,就是構造一個池容器,同時提供從池中獲得物件的方式。
1.3 通用程式碼:
錯誤舉例:
package _22_Flyweight;
public abstract class Flyweight {
private String intrinsic;
protected String extrinsic;
public Flyweight(String intrinsic) {
this.intrinsic = intrinsic;
}
public String getIntrinsic() {
return intrinsic;
}
public abstract void operate();
public String getExtrinsic() {
return extrinsic;
}
public void setExtrinisic(String extrinsic) {
this.extrinsic = extrinsic;
}
}
public class ConcreteFlyweight1 extends Flyweight {
public ConcreteFlyweight1(String intrinsic) {
super(intrinsic);
}
public void operate() {
}
}
public class ConcreteFlyweight2 extends Flyweight {
public ConcreteFlyweight2(String intrinsic) {
super(intrinsic);
}
public void operate() {
}
}
public class FlyweightFactory {
private static HashMap<String, Flyweight> pool = new HashMap<String, Flyweight>();
public static Flyweight getFlyweight1(String Intrinsic) {
// 需要返回的物件
Flyweight flyweight = pool.get(Intrinsic);
if (flyweight == null) {
flyweight = new ConcreteFlyweight1(Intrinsic);
pool.put(Intrinsic, flyweight);
}
return flyweight;
}
public static int getSize() {
return pool.size();
}
}
public class Client {
public static void main(String args[]) {
Flyweight fly1 = FlyweightFactory.getFlyweight1("1234567890");
fly1.setExtrinisic("Pos: line=10, col=20, color = RED");
System.out.println(fly1.getExtrinsic() + " " + fly1.getIntrinsic());
Flyweight fly2 = FlyweightFactory.getFlyweight1("1234567890");
fly2.setExtrinisic("Pos: line=20, col=20, color = BLUE");
System.out.println(fly2.getExtrinsic() + " " + fly2.getIntrinsic());
System.out.println("池中數量為:" + FlyweightFactory.getSize());
}
}
結果:
Pos: line=10, col=20, color = RED 1234567890
Pos: line=20, col=20, color = BLUE 1234567890
池中數量為:1
注意上述是一個誤用(錯例)。
享元模式只是想將物件細粒度化,將可共享部分快取起來,以複用。而上例中將物件的共享部分與非共享部分融合在一起是錯誤的,因為這樣則會導致整體的複用,在一個物件未被消費時,其會被另一次複用覆蓋。而這並非複用的本質。
下例正確:
package _22_Flyweight.right;
public abstract class Flyweight {
private String intrinsic;
public Flyweight(String intrinsic) {
this.intrinsic = intrinsic;
}
public String getIntrinsic() {
return intrinsic;
}
public abstract void operate();
}
public class ConcreteFlyweightContent extends Flyweight {
public ConcreteFlyweightContent(String intrinsic) {
super(intrinsic);
}
public void operate() {
}
}
public class FlyweightFactory {
private static HashMap<String, Flyweight> pool = new HashMap<String, Flyweight>();
public static Flyweight getFlyweight1(String Intrinsic) {
// 需要返回的物件
Flyweight flyweight = pool.get(Intrinsic);
if (flyweight == null) {
flyweight = new ConcreteFlyweightContent(Intrinsic);
pool.put(Intrinsic, flyweight);
}
return flyweight;
}
public static int getSize() {
return pool.size();
}
}
public class WPS {
Flyweight fly;
List<String> formats = new ArrayList<String>();
List<Flyweight> contents = new ArrayList<Flyweight>();
public void addLine(String format, Flyweight content) {
formats.add(format);
contents.add(content);
}
public void show() {
for (int i = 0; i < formats.size(); i++) {
System.out.print(formats.get(i) + "\t\t");
System.out.println(contents.get(i).getIntrinsic());
}
}
}
public class Client {
public static void main(String args[]) {
WPS mydoc = new WPS();
mydoc.addLine("Pos: line=1, col=20, color = RED",
FlyweightFactory.getFlyweight1("1234567890"));
mydoc.addLine("Pos: line=2, col=20, color = GREEN",
FlyweightFactory.getFlyweight1("1234567890"));
mydoc.addLine("Pos: line=3, col=20, color = BLUE",
FlyweightFactory.getFlyweight1("1234567890"));
mydoc.show();
System.out.println("池中數量為:" + FlyweightFactory.getSize());
}
}
2 優點
2.1 大大減少應用程式建立的物件,降低程式記憶體的佔用,增強程式的效能;
3 缺點
3.1 提高了系統的複雜性:需要分離出外部狀態和內部狀態;
4 應用場景
4.1 系統存在大量的相似物件;
4.2 細粒度的物件都具備較接近的外部狀態,而且內部狀態與環境無關,也就是說物件沒有特定身份;
4.3 需要緩衝池的場景。
5 注意事項
暫無
6 擴充套件
暫無
7 範例
暫無
轉自:http://blog.csdn.net/yuanlong_zheng/article/details/7584881相關文章
- 享元模式(Flyweight)模式
- Rust語言之GoF設計模式:Flyweight享元模式RustGo設計模式
- 【大道模式】享元模式-FlyWeight Pattern模式
- 設計模式(十六)----結構型模式之代理享元模式設計模式
- 無廢話設計模式(9)結構型模式--享元模式設計模式
- 設計模式-享元模式設計模式
- 設計模式----享元模式設計模式
- 設計模式之享元模式設計模式
- 軟體設計模式————(享元模式)設計模式
- 極簡設計模式-享元模式設計模式
- 設計模式系列13–享元模式設計模式
- iOS設計模式 (四)享元模式iOS設計模式
- Java學設計模式之享元模式Java設計模式
- Java設計模式之(十一)——享元模式Java設計模式
- C#設計模式(13)——享元模式C#設計模式
- C#設計模式之享元模式C#設計模式
- Java設計模式(13):享元模式(蠅量模式)Java設計模式
- 結構型設計模式設計模式
- 設計模式之代理模式(結構型)設計模式
- 設計模式【10】-- 順便看看享元模式設計模式
- 11.java設計模式之享元模式Java設計模式
- 設計模式 | 享元模式及典型應用設計模式
- Java設計模式之七 —– 享元模式和代理模式Java設計模式
- (Java)設計模式:結構型Java設計模式
- 軟體設計模式系列之十三——享元模式設計模式
- 設計模式之:享元模式FlyweightPattern的實現設計模式
- 《設計模式四》觀察、組合、享元模式設計模式
- 每天一個設計模式之享元模式設計模式
- 12.享元模式設計思想模式
- 聊一聊設計模式(三)-- 結構型設計模式設計模式
- 好程式設計師分享java設計模式之享元模式程式設計師Java設計模式
- 好程式設計師精講 java設計模式—享元模式程式設計師Java設計模式
- 《JavaScript設計模式與開發實踐》模式篇(9)—— 享元模式JavaScript設計模式
- Java進階篇設計模式之七 —– 享元模式和代理模式Java設計模式
- Java進階篇設計模式之七 ----- 享元模式和代理模式Java設計模式
- 享元模式模式
- 物件導向-設計模式-結構型物件設計模式
- 大話 PHP 設計模式--結構型PHP設計模式
- 【設計模式自習室】結構型:組合模式 Composite設計模式