編輯:關於Android編程
享元模式是結構型設計模式之一,是對對象池的一種實現。就像它的名字一樣,共享對象,避免重復的創建。我們常用的
String
就是使用了共享模式,所以String
類型的對象創建後就不可改變,如果當兩個String
對象所包含的內容相同時,JVM只創建一個String
對象對應這兩個不同的對象引用。
采用一個共享來避免大量擁有相同內容對象的開銷。使用享元模式可有效支持大量的細粒度對象。
(1)系統中存在大量的相似對象。
(2)細粒度的對象都具備較接近的外部狀態,而且內部狀態與環境不關,也就是說對象沒有特定身份。
(3)需要緩沖池的場景。
PS:內部狀態與外部狀態:在享元對象內部並且不會隨著環境改變而改變的共享部分,可以稱之為享元對象的內部狀態,反之隨著環境改變而改變的,不可共享的狀態稱之為外部狀態。
享元模式分為單純享元模式和復合享元模式,上圖是復合享元模式。
(1)Flyweight
:享元對象抽象基類或者接口。
(2)ConcreateFlyweight
:具體的享元對象,如果有內部狀態的話,必須負責為內部狀態提供存儲空間。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPqOoM6OpPGNvZGU+VW5zaGFyYWRDb25jcmVhdGVGbHl3ZWlnaHQ8L2NvZGU+o7q4tLrPz+3Uqr3HyavL+bT6se21xLbUz/PKx7K7v8nS1Lmyz+21xKOssqLH0r/J0tS31r3is8nOqrbguPa1pbS/z+3UqrbUz/O1xNfpus+ho7WltL/P7dSqxKPKvcO709C0y8/uo6zV4tKyysfBvdXf1Nq94bm5yc+1xMf4sfChozwvcD4NCjxwPqOoNKOpPGNvZGU+Rmx5d2VpZ2h0RmFjdG9peTwvY29kZT6jus/t1Kq5pLOno6y4utTwudzA7c/t1Kq21M/zs9i6zbS0vajP7dSqttTP86GjPC9wPg0KPHA+o6g1o6k8Y29kZT5DbGllbnQ8L2NvZGU+o7rOrLukttTL+dPQz+3UqrbUz/O1xNL908OjrLb4x9K7udDo0qq05rSittTTprXEzeLUzNe0zKyhozwvcD4NCjxoMiBpZD0="4簡單實現">4.簡單實現
情景:過年買火車票的時候,我們需要查詢車票的情況,那麼如果每次查詢車票時都創建一個結果,那麼必然會大量的創建出許多重復的對象,頻繁的去銷毀他們,使得GC任務繁重。那麼這時我們可以使用享元模式,將這些對象緩存起來,查詢時優先使用緩存,沒有緩存在重新創建。
首先是Ticket接口(Flyweight):
public interface Ticket {
public void showTicketInfo(String bunk);
}
TrainTicket具體實現類(ConcreateFlyweight):
//火車票
public class TrainTicket implements Ticket{
public String from; // 始發地
public String to; // 目的地
public String bunk; //鋪位
public int price; //價格
public TrainTicket(String from, String to) {
this.from = from;
this.to = to;
}
@Override
public void showTicketInfo(String bunk) {
price = new Random().nextInt(300);
System.out.println("購買 從 " + from + " 到 " + to + "的" + bunk + "火車票" + ", 價格:" + price);
}
}
TicketFactory 管理查詢火車票(FlyweightFactoiy):
public class TicketFactory {
static Map sTicketMap = new ConcurrentHashMap();
public static Ticket getTicket(String from ,String to){
String key = from + "-" + to;
if(sTicketMap.containsKey(key)){
System.out.println("使用緩存 ==> " + key);
return sTicketMap.get(key);
}else{
System.out.println("創建對象 ==> " + key);
Ticket ticket = new TrainTicket(from, to);
sTicketMap.put(key, ticket);
return ticket;
}
}
}
查詢:
final class Client {
public static void main(String[] args) {
Ticket ticket01 = TicketFactory.getTicket("北京", "青島");
ticket01.showTicketInfo("上鋪");
Ticket ticket02 = TicketFactory.getTicket("北京", "青島");
ticket02.showTicketInfo("下鋪");
Ticket ticket03 = TicketFactory.getTicket("北京", "西安");
ticket03.showTicketInfo("坐票");
}
}
結果
創建對象 ==> 北京-青島
購買 從 北京 到 青島的上鋪火車票, 價格:71
使用緩存 ==> 北京-青島
購買 從 北京 到 青島的下鋪火車票, 價格:32
創建對象 ==> 北京-西安
購買 從 北京 到 西安的坐票火車票, 價格:246
因為Android是事件驅動的,因此如果通過new創建
Message
就會創建大量的Message
對象,導致內存占用率高,頻繁GC等問題。那麼Message
就采用了享元模式。
Message
通過next
成員變量保有對下一個Message
的引用,最後一個可用Message
的next
則為空。從而構成了一個Message鏈表。Message Pool
就通過該鏈表的表頭管理著所有閒置的Message
,一個Message
在使用完後可以通過recycle()
方法進入Message Pool
,並在需要時通過obtain
靜態方法從Message Pool
獲取。Message
承擔了享元模式中3個元素的職責,即是Flyweight
抽象,又是ConcreateFlyweight
角色,同時又承擔了FlyweightFactoiy
管理對象池的職責。
所以使用Message推薦obtain(),不要去new了。
//1。使用new Message()
//Message mess = new Message();
//2。使用Message.obtain()
Message mess = Message.obtain();
mess.what = 1;
//Message mess = mHandler.obtainMessage(1); 與上兩行的代碼一樣,可以參考源碼查看
mHandler.sendMessage(mess);
(1)大大減少應用程序創建的對象,降低程序內存的占用,增強程序的性能。
(2)使用享元模式,可以讓享元對象可以在不同的環境中被共享。
(1)使得系統更加復雜。為了使對象可以共享,需要將一些狀態外部化,這使得程序的邏輯復雜化。
(2)享元模式將需、享元對象的狀態外部化,而讀取外部狀態使得運行時間稍微變長。
轉載請注明文章出處和作者! 出處:http://blog.csdn.net/xl19862005 大家多多支持偶家媳婦的網店:http://wen1991.tao
Android 自定義控件實現顯示文字的功能自定義控件—–逐個顯示文字ONE Goal ,ONE Passion !前言:今天要實現的效果時.讓我們的文字一個一個顯示出來
Android Toolbar:ToolBar是Android 5.0(API Level 21)之後用來取代ActionBar的ToolBar的優勢:Toolbar本身
(1)使用數據庫mysql,腳本語言如下: /* 用戶表*/ CREATE TABLE `usertbl` ( `id` int(11) NOT NULL AUTO_