本節我們使用享元模式來實現資源共享池。舉個例子,每年春節為了買到一張回家的火車票,大家都大費周章。為了解決這一問題,12306 **提供了自動查票的功能。如果開啟自動查票的功能,則系統會將我們填寫的資訊快取起來,然後定時查詢餘票資訊。
在買票的時候,我們肯定要查詢一下有沒有我們需要的車票。假設一張火車票包含出發站、目的站、**、座位類別等資訊。現在要求編寫查詢火車票的模擬**。
比如要求可以通過出發站、目的站來查詢火車票的相關資訊,那麼只需構建出火車票類物件,向使用者提供乙個查詢出發站、目的站的介面進行查詢即可。
首先建立 ticket 介面。
public inte***ce ticket {
void showinfo(string bunk);
然後建立 trainticket 類實現 ticket 介面。
public class trainticket implements ticket {
private string from;
private string to;
private int price;
public trainticket(string from, string to) {
this.from = from;
this.to = to;
@override
public void showinfo(string bunk) {
this.price = new random().nextint(500);
system.out.println(this.from + "->" + this.to + ":" + bunk + "**:" + price + "元");
接著建立 ticketfactory 類。
public class ticketfactory {
public static ticket queryticket(string from,string to){
return new trainticket(from,to);
最後編寫客戶端**如下:
public static void main(string args) {
ticket ticket = ticketfactory.queryticket("北京西","石家莊");
ticket.showinfo("硬座");
執行結果如下:
首次查詢,建立物件:北京西->石家莊
北京西->石家莊:硬座**:450元
由上面**可以知道,當客戶端進行查詢時,系統通過 ticketfactory 直接建立乙個火車票物件,但是這樣做的話,如果某個瞬間有大量使用者查詢同一張票的資訊時,系統就會建立出大量該火車票物件,記憶體壓力驟增。
其實更好的做法應該是快取該火車票物件,然後提供給其他查詢請求復用,這樣乙個物件就足以支撐數以千計的查詢請求,記憶體完全無壓力。使用享元模式就可以很好地解決這個問題。
下面我們繼續優化**,只需要在 ticketfactory 類中進行更改,增加快取機制。
public class ticketfactory {
private static map sticketpool = new concurrenthashmap();
public static ticket queryticket(string from, string to) {
string key = from + "->" + to;
if (ticketfactory.sticketpool.containskey(key)) {
system.out.println("使用快取:" + key);
return ticketfactory.sticketpool.get(key);
system.out.println("首次查詢,建立物件:" + key);
ticket ticket = new trainticket(from, to);
ticketfactory.sticketpool.put(key, ticket);
return ticket;
測試**如下:
public class test {
public static void main(string args) {
ticket ticket = ticketfactory.queryticket("北京西","石家莊");
ticket.showinfo("硬座");
ticket ticket2 = ticketfactory.queryticket("北京西","石家莊");
ticket.showinfo("軟座");
ticket ticket3 = ticketfactory.queryticket("北京西","石家莊");
ticket.showinfo("硬臥");
執行結果如下:
首次查詢,建立物件:北京西->石家莊
北京西->石家莊:硬座**:48元
使用快取:北京西->石家莊
北京西->石家莊:軟座**:98元
使用快取:北京西->石家莊
北京西->石家莊:硬臥**:118元
可以看到,除了第一次查詢建立物件,後續查詢相同車次票的資訊都使用快取物件,不需要建立物件。
其中,ticket 是抽象享元角色,trainticket 是具體享元角色,ticketfactory 是享元工廠。有些小夥伴一定會有疑惑了,這不就是註冊式單例模式嗎?雖然在結構上很像,但是享元模式的重點在結構上,而不是在建立物件上。後面結合享元模式在 jdk 原始碼中的應用,大家應該就能徹底明白了。
Python實現程序資源共享
程序是cpu最小的資源分配的單位。程序之間的資源是不能共享的。但是執行緒之間的資源可以是共享的。下面簡單的介紹兩種方法實現程序之間資源的共享。1 queue 方法 usr bin envpython coding utf 8 from multiprocessing import process,q...
23種設計模式之 12 享元模式(共享池)
練習原始碼 參考內容 簡說設計模式 享元模式 23種設計模式全解析 享元模式的主要目的是實現物件的共享,即共享池,當系統中物件多的時候可以減少記憶體的開銷,通常與工廠模式一起使用。flyweightfactory負責建立和管理享元單元,當乙個客戶端請求時,工廠需要檢查當前物件池中是否有符合條件的物件...
Java Java實現執行緒間的資源共享
實現runnable介面相比繼承thread類有如下好處 避免單繼承的侷限,乙個類可以同時實現多個介面 適合資源的共享.如下 public class mythread extends thread public static void main string args 執行效果 售票口二 買票 5...