`
lixiongzhi_m
  • 浏览: 62156 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

监听器设计模式总结

阅读更多
         监听器模式设计总结

为何需要用到监听器设计模式?


        假设现在有这样一个情景:我们要在一个文本区域中显示一些我们指定的信息。这个信息假设是在一个线程中每隔三秒发布一个信息并显示在该文本区域,我们一般的做法会在,窗体界面类中实例化这样一个文本区域对象,然后再实例化一个信息产生对象(即前面所说的线程),在实例化这个信息产生对象的时候将该文本区域对象作为一个参数传到信息产生的类内部,并在信息产生代码语句后添加该文本区域对信息的处理。(此处为将信息添加到文本区域中)。说的可能有点模糊。请看以下代码,相信很好理解。

          先定义一个信心产生类(利用线程),和一个信息类,代码如下:


package 监听器设计模式;

import java.util.ArrayList;

import javax.swing.JTextArea;;

public class NetConnector extends Thread{
	private JTextArea textarea;

	public NetConnector(JTextArea textArea){
		this.textarea=textArea;
	}
	public void run(){
		//线程运行时模拟产生信息
		int t=0;
		while(true){
			try {
				sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
				}
			t++;
			Msg msg=new Msg();
			msg.setId(t);
			msg.setContent("第"+t+"条信息\n");
			textarea.append(msg.getContent());
		}
		
	
	}
		
}

class Msg{
	private int id; //消息id
	private String content;//消息内容
	public String toString(){//重写的toString方法
		return content;
	}	
	public int getId(){
		return id;
	}
	public void setId(int id){
		this.id=id;
	}
	public String getContent(){
		return content;
	}
	public void setContent(String content){
		this.content=content;
	}
}


在主界面的代码:
package 监听器设计模式;

import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class UI extends JFrame{
	public static void main(String[] args){
		UI ui=new UI();
		ui.show_Ui();
	}
	
	public void show_Ui(){
		this.setTitle("测试界面");
		this.setDefaultCloseOperation(3);
		this.setLayout(new FlowLayout());
		this.setLocationRelativeTo(null);
		this.setSize(400,300);
		JTextArea textarea=new JTextArea(10,20);
		JScrollPane jscollpane=new JScrollPane(textarea);
		NetConnector connector=new NetConnector(textarea);
		connector.start();
		
		this.add(jscollpane);
		this.setVisible(true);
	}
}


   那么这样在主界面的文本区域内就能3秒产生一条信息。

这样的设计有什么弊端呢?

          假设我们要在另外一个组件中也对这些信息做相应的处理,按照这种做法就必须在在实例化信息产生对象的时候在传入相应组件的参数,然后再信息产生代码后再添加相应组件对信息的处理,要是后面有更多的组件要处理这些相同的信息,那么我们就每次都要去修改信息产生的构造方法。并要去添加信息产生后相应组件处理信息的代码,这些都必须要去修改源代码,显然这样会使代码代码质量下降。那么我们该怎么去处理这样一个问题呢?下面的监听器模式能帮你解决。

            回想我们以前用过的监听器,比如鼠标监听器、键盘监听器等。拿鼠标监听器来讲。我们用一个自定义类去实现鼠标监听器,实现里面的方法,如鼠标按下的方法。这个过程它是怎么来处理的?当我们按下鼠标,这个就相当于一条信息的发送。那么这条信息要怎么处理呢?这个只要在鼠标Press的方法中实现即可。然后将这个实现了鼠标监听器的类对象添加给某个处理该信息的组件,如一个面板。要是你想在其他组件如一个窗体上,那么同样只要实现这个鼠标监听器的接口,在相应的处理方法中实现我们对信息的处理,在将实现了该鼠标监听器接口的对象添加给窗体。想想这个模式和我们上面涉及到的对同一些信息要多种组件来处理的是不是一样的?答案是是的,完全一样。这样的做法并不用像上面举到的例子一样要去修改来原来的代码,只要做相应的添加就行了。要是还不是很理解,请看如下监听器设计模式的步骤。(该处还是以上面多种组件来处理同一信息的情况)


           既然是对同一信息的处理。我们先定义这个一个接口,该接口中有一个信息处理的方法。

接口如下:

package 监听器设计模式;

public interface IMsgReciverListener {
	public void reciveMsg(Msg m);//监听器中必须实现的处理消息的方法
}





某一个组件要去处理这类信息那么它就必须去实现这个接口。并实现相应的信息的处理的方法。如上面所说的文本区域。



           那么实现了接口,就要实现了相应的方法。最后的工作只要去调用这个方法了。这个方法要在什么地方调用呢?最佳答案是在信息产生的类内部。这边就要考虑到这样一个问题,这个信息是要在多种组件下同时做处理的。那么该如何将这些能处理信息对像(即实现了接口的类的实例化对象)放置在一起呢?有这样一个想法,当我们实例化一个这样的对象时我们就动态地将这个对象添加到信息产生的类内部,并用一个队列保存,那么要去调用全部的这些对象的方法就迎刃而解了。只要遍历队列,取出所有的对象,并调用相应的信息处理方法即可。


           以下代码是对消息产生类的修改(实现监听器设计模式):


package 监听器设计模式;

import java.util.ArrayList;

import javax.swing.JTextArea;

public class NetConnector extends Thread{
	//内部保存消息监听器对象的队列
	private ArrayList<IMsgReciverListener> listeners=new ArrayList();
		public void run(){
		//线程运行时模拟产生信息
		int t=0;
		while(true){
			try {
				sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
				}
			t++;
			Msg msg=new Msg();
			msg.setId(t);
			msg.setContent("第"+t+"条信息\n");
                          //遍历队列调用相应信息处理方法
                          fireMsgRecive(msg);
						}
		
	
	}
	
	//给NetConnector对象中增加一个监听器的方法调用
	public void addListener(IMsgReciverListener listener){
		listeners.add(listener);
	}
	//将接收到的消息通知到队列中的所有监听器对象去处理
	private void fireMsgRecive(Msg m){
		for(int i=0;i<listeners.size();i++){
			listeners.get(i).reciveMsg(m);
		}
	}
	
}



还要定义实现了接口的文本区域类:
package 监听器设计模式;

import javax.swing.JTextArea;

public class MyTextArea extends JTextArea implements IMsgReciverListener{

	@Override
	public void reciveMsg(Msg m) {
		this.append(m.getContent());
	}

}


在主界面中代码修改如下:

package 监听器设计模式;

import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class UI extends JFrame{
	public static void main(String[] args){
		UI ui=new UI();
		ui.show_Ui();
	}
	
	public void show_Ui(){
		this.setTitle("测试界面");
		this.setDefaultCloseOperation(3);
		this.setLayout(new FlowLayout());
		this.setLocationRelativeTo(null);
		this.setSize(400,300);
		MyTextArea textarealistener=new MyTextArea(200,150);
		JScrollPane jscollpane=new JScrollPane(textarealistener);
		NetConnector connector=new NetConnector();
		connector.addListener(textarealistener);
		connector.start();
		
		this.add(jscollpane);
		this.setVisible(true);
	}
}



想看效果,可以运行下啊。

这样,要是我们想在另外一个组件比如一个按钮上让他显示最新产生的消息,我们只要自定义一个继承JButton的类并实现上述接口,在信息处理方法中做我们想要的信息处理方法就可以。代码如下:
package 监听器设计模式;

import javax.swing.JButton;

public class MyButton extends JButton implements IMsgReciverListener{

	@Override
	public void reciveMsg(Msg m) {
		this.setText(m.getContent());
	}

}


然后再主界面类中实例化我们实现了接口的按钮,这时这个按钮也是一个监听器对象(由于实现了接口),别忘了将该监听器添加给消息产生类中的队列。最后在把按钮添加到界面上即可。这个自己动手尝试下。


以下是我的一些看法:
            1.很多书上可能较多用监听术语来描述,类似事件源、事件处理着。上述对应于事件源的就是消息产生的类,要处理的信息就是这里产生的。那么我们实现了的事件处理方法就要在这里调用,(将消息传入)。事件处理者就是上述实现了事件处理接口的那些自定义类(当然继承了系统提供的组件类)。可以看出,用这样的方式,事件源和事件处理者是独立的。这样可以减少代码的耦合性。

            2.将所有要处理事件的类都实现了事件处理接口,这本身就是理所当然,由于它要对事件进行处理,必须实现,而后在调用的时候,不同组件却可以被当成同一类型的对象存在队列中,并遍历调用。也正是由于实现了同一接口,(可以理解为他们都是这个接口类的一个对象),不同组件对象可以当成同一类型对象也就显得顺理成章。

             3.大家可按自己的理解去理解监听器设计模式,而不用刻意按监听器术语去理解他,我昨天刚看hu总给的文档时,看前面写的那些也是一头晕,当然自己看了一遍后按自己的理解整理了一下思路,然后再去类比那些术语,这样感觉那些知识一下子浅显了了很多。
分享到:
评论

相关推荐

    AJAX_技术总结_设计模式

    **AJAX 技术总结与设计模式** AJAX(Asynchronous JavaScript and XML)是一种在无需刷新整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,提升了用户体验。...

    java中监听机制,以及观察者设计模式

    总结来说,Java中的监听机制和观察者设计模式都是为了提高程序的互动性和响应性。通过合理地使用它们,开发者能够创建出更加灵活、可维护的代码结构,使得系统能够更好地应对需求变化和扩展。在实际编程实践中,掌握...

    Spring 设计模式总结1

    Spring设计模式总结 在软件开发中,设计模式是解决常见问题的经验总结,它们为程序员提供了在特定场景下设计高效、可维护代码的蓝图。在Spring框架中,许多设计模式被广泛应用,以提升系统的灵活性和可扩展性。以下...

    基于 RBAC与监听器机制设计作业管理软件

    ### 基于RBAC与监听器机制设计作业管理软件 #### 一、项目背景与目标 本项目旨在设计一款适用于教育场景中的作业管理系统,利用角色基础的访问控制(Role-Based Access Control,简称RBAC)及监听器机制来实现安全...

    软件设计模式与体系结构课后习题代码(孙玉山).zip

    设计模式是一种在特定情境下,为了解决软件设计中反复出现的问题而总结出的最佳实践。这些模式是经过验证的解决方案,可以作为开发者之间的通用语言,使得团队能够更有效地沟通和合作。常见的设计模式包括: 1. ...

    经典设计模式总结

    ### 经典设计模式总结 #### 一、策略模式 **定义:** 策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。该模式让算法独立于使用它的客户而变化。 **背景:** 在一个动作冒险游戏中,...

    java设计模式 课件讲义

    设计模式并非具体的代码或库,而是经验丰富的开发者在长期实践中总结出的常见问题的通用解决方案。这些模式描述了在特定上下文中,如何在面向对象设计中重用已知的有效解决方案。 在Java中,设计模式分为三大类:...

    设计模式全套学习ppt

    ### 设计模式全套学习PPT知识点总结 #### 一、设计模式概述 设计模式是在软件设计过程中遇到的常见问题的解决方案。这些模式并不是具体的代码,而是一些指导思想,可以帮助开发者更好地解决特定类型的问题,提高...

    servlet监听器总结

    ### Servlet监听器总结 #### 一、Listener概念与作用 - **定义**:在Java Web开发中,Listener(监听器)是一种特殊的组件,主要用于监听容器内的特定事件,并根据这些事件的发生执行相应的处理逻辑。 - **功能**...

    01-02-07-各设计模式总结与对比1

    行为型设计模式,如解释器、模板方法、责任链、命令、迭代器、调解者、备忘录、观察者、状态、策略和访问者模式,主要处理对象之间的交互和行为。策略模式允许在运行时选择算法或策略,降低了代码的耦合度;而观察者...

    设计模式读书笔记

    总结来说,设计模式是软件设计的宝贵工具,它们提供了解决复杂问题的标准模板。状态机模式尤其适用于管理对象在不同状态下的行为变化,通过将状态和行为分离,使得代码更易于理解和扩展。理解并熟练应用这些设计模式...

    JAVA设计模式配套光盘

    Java设计模式是软件工程中的一种最佳实践,它们是解决常见编程问题的经验总结,旨在提高代码的可重用性、可维护性和可扩展性。在这个"JAVA设计模式配套光盘"中,我们可以期待找到一系列关于Java设计模式的资源,包括...

    设计模式学习知识点总结

    ### 设计模式学习知识点总结 #### 一、总则 设计模式的学习主要围绕面向对象的分析、设计与编程思想展开,旨在通过封装、继承、多态等机制来降低程序间的耦合度,使得程序结构更加灵活,易于维护与扩展。在实际...

    Java设计模式的教学PPT和源代码

    总结起来,这份"Java设计模式的教学PPT和源代码"资料是Java开发者学习和掌握设计模式的宝贵资源。通过理论学习与实践操作,可以系统地提升自己的软件设计水平,为日后的项目开发打下坚实的基础。无论是初学者还是有...

    Eclipse 向导设计模式

    ### Eclipse向导设计模式详解 #### 一、引言 在Eclipse开发环境中,向导是一种常见的用户交互机制,用于引导用户完成复杂任务的过程。Eclipse中的向导设计模式不仅提高了用户界面的友好性,还简化了开发人员的编码...

    Android源码设计模式解析与实战.pdf

    设计模式是一种在特定情况下解决软件设计问题的经验总结,它提供了一种通用的解决方案模板,可以帮助开发者更好地组织代码结构、降低模块间的耦合度并提高系统的灵活性。对于Android开发者而言,掌握常见的设计模式...

    23种设计模式总结(2020最新版).pdf

    设计模式是软件设计中的一种最佳实践,用于解决常见的设计问题并提供可重用的解决方案。在Java中,设计模式被广泛应用于构建可扩展且易于维护的系统。23种设计模式分为三大类:创建型模式、结构型模式和行为型模式。...

    HeadFirst设计模式.rar

    设计模式是面向对象编程中的一种最佳实践,是解决常见问题的经验总结,是软件开发中的通用解决方案。这本书通过丰富的图表、幽默的插图以及易于理解的例子,使得抽象的理论变得生动有趣。 首先,我们要提到的就是...

    ios三种设计模式

    在iOS应用开发中,设计模式是提升代码可读性、可维护性和可扩展性的重要工具。以下是关于三种主要设计模式——MVC(Model-View-Controller)、MVP(Model-View-Presenter)和MVVM(Model-View-ViewModel)的详细讲解...

Global site tag (gtag.js) - Google Analytics