亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

我對觀察者模式的理解

系統(tǒng) 2170 0

前言

???? 一直很少動手寫文檔,覺得自己只是一個新手,對很多技術(shù)點或者概念理解的不透徹,沒多少自信。二來,做程序遇到困難時,在論壇上找到的幾乎都是通篇的代碼,只能一行行解讀代碼,自己自圓其說。我不太喜歡這種模式,但是又不知道如何找到詳細的資料,天天百度,費力不討好。在圖書館找參考書,大多都是些基礎(chǔ)的東西,也沒什么幫助。

??? 昨天,老師布置了一些作業(yè),問我們應(yīng)不應(yīng)該強制?回來后我想了想,還是覺得不該強制,如果你愛JAVA,你自己會花時間在上面的。寫文檔倒是很有必要的。寫文檔,一來可以記錄你的學(xué)習(xí)歷程,二來可以暴露一些問題,如果你講不清楚一個問題,很有可能時因為你對該問題的理解不透徹。

??

?? 今天,我要敘述的內(nèi)容是觀察者模式,也稱發(fā)布/訂閱模式,監(jiān)聽器模式

??

觀察者模式是軟體設(shè)計模式的一種。在此種模式中,一個目標(biāo)物件(被觀察者)管理所有相依于它的觀察者物件,并且在它本身的狀態(tài)改變時主動發(fā)出通知。這通常透過呼叫各觀察者所提供的方法來實現(xiàn)。此種模式通常被用來實作事件處理系統(tǒng)。

?

???敘述該問題,通篇敘述不如通過實例來的易理解,不用實例,估計我也講不清楚

??

?? 例:給一個JFrame上的JTree添加節(jié)點,通過線程給JTree添加5個節(jié)點

?

1.直接調(diào)用模式

?????學(xué)習(xí)這么久,老師從沒有講過搭建模型,記得在寫五子棋游戲的時候,那時候?qū)懙氖怯魫灥暮?,每添加一個功能時,都要修改好幾個類。類與類的耦合非常高。????

??? 實現(xiàn)JFrame的JTree上添加節(jié)點:

??? 思路:用線程來模擬給JTree添加節(jié)點,在線程的構(gòu)造器中傳入JTree對象。

?????

    /**********************
 *此類為消息類,用來作為樹節(jié)點
 */
public class Msg {

	private String text;
	
	public Msg(String text){
		this.text = text;
	}
	
	//重寫toString方法,設(shè)置節(jié)點顯示內(nèi)容
	public String toString(){
		return this.text;
	}
}

  

?

? 線程類:

????

    public class TestThread extends  Thread{

	private JTree tree;
	
	public TestThread(JTree tree){
	    //傳入JTree對象   
		this.tree = tree ;
	}
	
	
	public void run(){
		
		DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
		
		for(int i=0;i<5;i++){
			
			Msg msg = new Msg("第"+(i+1)+"個節(jié)點");
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(msg);
			//添加節(jié)點
			root.add(node);
			//刷新樹
			javax.swing.SwingUtilities.updateComponentTreeUI(tree);
			//延時1S
			try{
				Thread.sleep(1000);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	
  

?測試界面類:

??

    	public static void main(String[] args){
		
		JFrame fr = new JFrame("Test_1");
		fr.setSize(300, 300);
		fr.setDefaultCloseOperation(3);
		fr.setLayout(new FlowLayout(FlowLayout.LEFT));
		
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("根節(jié)點");
		JTree tree = new JTree(root);
		fr.add(tree);
		
		new TestThread(tree).start();
		
		fr.setVisible(true);
		
	}
  

?

總結(jié)1 :軟件是應(yīng)用戶需要而編寫的,肯定會經(jīng)常修改。這種模式由于界面類和實現(xiàn)類之間的高耦合,要改界面類和實現(xiàn)

???????類都要改,?不利于程序的修改和擴展。

??????????怎樣才能避免這種牽一發(fā)動全身的問題呢?

?????????? 想想,如果將具體對象間的依賴關(guān)系轉(zhuǎn)化為接口實現(xiàn)的抽象關(guān)系會怎樣,就可將界面類和實現(xiàn)類分別封裝,使相互

?????? 獨立,各自修改互補影響。對于本例,在線程中添加一個監(jiān)聽器隊列,當(dāng)產(chǎn)生事件時通知隊列中的各監(jiān)聽器即可,這

??????? 需要有添加,移除,通知監(jiān)聽器的方法。

?

????????? 可將上面的代碼修改一下

觀察者模式

?????首先需要定義消息處理接口

    public interface InListener {

	public void actionPerformed(Msg msg);
	
}
  

???根據(jù)需要編寫實現(xiàn)類,本例中:

?? MyJTreeListener

??

    public class MyJTreeListener implements InListener{

	
	private JTree tree;
	private DefaultMutableTreeNode root;
	
	public MyJTreeListener(JTree tree){
		
		this.tree = tree;
		root = (DefaultMutableTreeNode) tree.getModel().getRoot();
		
	}
	
	
	public void actionPerformed(Msg msg) {
		
		DefaultMutableTreeNode node = new DefaultMutableTreeNode(msg);
	    root.add(node);
	    javax.swing.SwingUtilities.updateComponentTreeUI(tree);
	}

}

  

?線程類:

?

    public class TestThread extends  Thread{
    
	//監(jiān)聽器隊列
	private ArrayList<InListener> list ;
	
	public TestThread(){
	    //初始化監(jiān)聽器隊列
		list = new ArrayList();
	}
	
	
	public void run(){
		
			for(int i=0;i<5;i++){
				
				Msg msg = new Msg("第"+(i+1)+"條消息");
				//通知各監(jiān)聽器
				this.fireInListener(msg);
				
				//延時1S
				try{
					Thread.sleep(1000);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		
	}
	
	/***********************8
	 * 通知所有消息監(jiān)聽器
	 * @param msg:消息
	 */
	public void fireInListener(Msg msg){
		
		for(int i=0;i<list.size();i++){
			InListener listener = list.get(i);
			listener.actionPerformed(msg);
		}
	}
	
	/***************************
	 * 添加事件監(jiān)聽器
	 * @param l:要添加的監(jiān)聽器
	 * @return:添加結(jié)果
	 */
	public boolean addListener(InListener l){
		
		return list.add(l);
		
	}
	/****************************
	 * 移除事件監(jiān)聽器
	 * @param l:要移除的監(jiān)聽器
	 * @return:移除結(jié)果
	 */
	public boolean removeListener(InListener l){
		
		return list.remove(l);
	}
	
	
  

?測試:

??

    	public static void main(String[] args){
		
		JFrame fr = new JFrame("Test_2");
		fr.setSize(300, 300);
		fr.setDefaultCloseOperation(3);
		fr.setLayout(new FlowLayout(FlowLayout.LEFT));
		
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("根節(jié)點");
		JTree tree = new JTree(root);
		fr.add(tree);
		
		TestThread nt = new TestThread();
		//注冊監(jiān)聽器
		nt.addListener(new MyJTreeListener(tree));
		nt.start();
		
		
		fr.setVisible(true);
		
	}
  

? 總結(jié)2: 這樣,線程對象和具體的事件處理對象就可以相互獨立的修改??? 但實際上這是一種具體對抽象的關(guān)系,可以進一步將事件產(chǎn)生類(本例中為線程)進行抽象,變?yōu)槌橄髮Τ橄蟮年P(guān)系,畢竟現(xiàn)實中的事件產(chǎn)生可以有很多種情況,往往風(fēng)馬牛不相及。

?

??? 只需再定義一個事件產(chǎn)生接口即可:

??? InEventSource

???

    public interface InEventSource {

	public ArrayList<InListener> list = new ArrayList();
	
	public boolean addListener(InListener l);
	
	public boolean removeListener(InListener l);
	
	public void fireInListener(Msg msg);
	
	
}

  

?

線程類:

??

    public class TestThread extends  Thread implements InEventSource{

	
	public void run(){
		
			for(int j=0;j<5;j++){
				
				Msg msg = new Msg("第"+(j+1)+"條消息");
				
				this.fireInListener(msg);
				
				//延時1S
				try{
					Thread.sleep(1000);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		
	}
	
	
	public void fireInListener(Msg msg){
		
		for(int i=0;i<list.size();i++){
			InListener listener = list.get(i);
			listener.actionPerformed(msg);
		}
	}
	
	
	public boolean addListener(InListener l){
		
		return list.add(l);
		
	}
	
	public boolean removeListener(InListener l){
		
		return list.remove(l);
	}
	
  

?

測試不變

?

總結(jié)3: 觀察者模式所進行的工作就是解耦,就是將具體的對象之間的關(guān)系進行抽象,變?yōu)槌橄髮Τ橄蟮年P(guān)系,降低具體對象間的依賴性,從而實現(xiàn)良好的修改,擴充性。其實,就是讓我們懂得封裝的重要性,教我們?nèi)绾畏庋b。

?

?

什么時候應(yīng)該采用觀察者模式

???? 我覺得,當(dāng)一個對象改變時,同時要改變其他對象,而且不知道要改變多少其他對象時,應(yīng)該考慮采用觀察者模式。

?

?

由于我的水平有限,講的不是很清楚,如果有錯的,或是不好的地方,歡迎指出批評。

?

附上 《大話設(shè)計模式》下載鏈接 書中第14章有很生動的講解

http://dl.iplaysoft.com/files/742.html

我對觀察者模式的理解


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品久久久久久久久久久搜索 | 黄色成人在线网站 | 国产三级在线精品男人的天堂 | 经典国产乱子伦精品视频 | 国产精品免费久久久久影院小说 | 国产香蕉网 | 美美女高清毛片视频黄的一免费 | 97影院在线观看 | 亚洲香蕉在线视频 | 九九热播 | 国产一区二区三区影院 | 国产最新精品 | 国产色在线 | 国产精品久久久久久久y | 91精品国产色综合久久不卡蜜 | 日本毛片免费看 | www.色94色.com| 青青青爽视频在线观看入口 | 国产精品久热 | 久久中文视频 | 污视频在线看网站 | 亚洲日本欧美在线 | 亚洲九九 | 成人动漫久久 | 九九视频国产免 | 波多野结衣久久一区二区 | 日韩欧美一级大片 | 国产欧美日韩亚洲精品区2345 | 国产一级毛片国语版 | 国产精品久久亚洲不卡动漫 | 伊人久久免费视频 | 久久久久在线观看 | 麻豆一区二区三区在线观看 | 日韩一区二区久久久久久 | 日韩精品一区二区三区免费视频 | 免费在线不卡视频 | 久久精品99视频 | 波多野结衣免费免费视频一区 | 亚洲日本久久一区二区va | 欧美乱妇高清无乱码视频在线 | 国产日韩精品欧美一区色 |