`
SurpriseLee
  • 浏览: 7545 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

监听器模式(生产消费模型)

 
阅读更多
    鲁迅有言:世上本没有路,只是走的人多了,也就成了路。不知道是历史的巧合,还是鲁迅的未卜先知。他的昔日之言,竟会在N年后,发出不一样的生命活力。
    在软件设计中,设计模式就是如同此理。它是经验的传承,,并不成体系,它是被前任发现,经过总结形成了一套某一类问题的一般性解决方案,而不是被设计出来的定性规则,它不像算法那样可以照搬照用。
    设计模式关注的终点在于通过经验提取的“准则或指导方案”在设计中的应用,因此,在不同层面考虑问题的时候就形成了不同问题域上的模式。模式的目标是吧共同的问题中不变部分和变化部分分离出来。不变的部分就构成了模式。因此,模式是一个经验提取的“准则”,并且在一次一次的时间中得到验证。不同的层次有不同的模式,小到语言的实现,大到架构。在不同的成面上,模式提供不同层面的指导。
    软件系统设计的目标是:高内聚,低耦合;
    所谓耦合,即不同的模块拼装到一起,产生相互依赖的关系。
    所谓高耦合,即不同模块之间连接点很多,造成错综复杂的连接关系,修改程序时牵一发则动全身。
    所谓低耦合,即模块层次化,我觉得理想的效果是,每一层的模块只与它上一层和下一层的模块进行耦合,同层之间的模块是没有交互的。
    通过一个聊天室项目,在具体分析监听器模式:
    在一般的设计中,我们会通过将文本域传给通信模块,在通信模块中把消息显示到文本域上。这样做,固然能实现聊天室的基本功能。但是,如果要对界面进行改动的话,需要改动通信模块,修改起来就会很蛋疼。
     而通过监听器模式,能实现通信模块与监听器部分代码的有效分离了,从而达到降低维护难度的目的。
     对一个按钮来说,事件源是按钮,监听器是动作监听器。
     对一个聊天室来说,事件源是通信模块,监听器须自己实现。
     监听器模式实现步骤:
     1. 定义一个时间监听器接口;
    
package 监听器模式;

/**
 * 消息监听器接口
 * @author SurpriseLee
 *
 */
public interface IMsgReceiveListener {
	public void receiveMsg(Message msg);
	
}

     2. 编写消息事件监听器的实现类;
    
package 监听器模式;

import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;

/**
 * 自定义监听器实现Listener接口
 * @author SurpriseLee
 *
 */
public class NetTree extends JTree implements IMsgReceiveListener {


	// 将消息包装成树上的一个节点对象,加载到树上
	public void receiveMsg(Message msg) 
	{
		// 取得这个树上的根节点
		DefaultMutableTreeNode root = (DefaultMutableTreeNode)this.getModel().getRoot();
		// 将消息包装成新建的节点
		DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(msg);
		root.add(newNode);
		// 刷新界面,将新节点显示在树上
		SwingUtilities.updateComponentTreeUI(this);
	}
	

}

     3. 注册消息监听器;
    
package 监听器模式;

import java.awt.List;
import java.util.ArrayList;

/**
 * @author SurpriseLee
 *
 */
public class NetConnector extends Thread {
	
	// 监听器队列
	private ArrayList<IMsgReceiveListener> listeners = new ArrayList<IMsgReceiveListener>();
	
	public void run()
	{
		int id = 0;
		while(true)
		{
			try 
			{
				Thread.sleep(3000);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			id++;
			Message msg = new Message();
			msg.setId(id);
			msg.setContent("第" + id + "条消息");
			
			// 分发
			fireMsgReceive(msg);
			System.out.println("第" + id + "条消息");
		}
		
	}
	
	// 注册监听器方法
	public void addListener(IMsgReceiveListener listener)
	{
		listeners.add(listener);
		
	}
	
	// 分发消息给所有监听器方法
	private void fireMsgReceive(Message msg)
	{
		for(int i = 0; i < listeners.size(); i++)
		{
			listeners.get(i).receiveMsg(msg);		
		}
		
	}
	

}


       4. 测试主界面代码;
      
package 监听器模式;

import java.awt.List;
import java.util.ArrayList;

/**
 * @author SurpriseLee
 *
 */
public class NetConnector extends Thread {
	
	// 监听器队列
	private ArrayList<IMsgReceiveListener> listeners = new ArrayList<IMsgReceiveListener>();
	
	public void run()
	{
		int id = 0;
		while(true)
		{
			try 
			{
				Thread.sleep(3000);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			id++;
			Message msg = new Message();
			msg.setId(id);
			msg.setContent("第" + id + "条消息");
			
			// 分发
			fireMsgReceive(msg);
			System.out.println("第" + id + "条消息");
		}
		
	}
	
	// 注册监听器方法
	public void addListener(IMsgReceiveListener listener)
	{
		listeners.add(listener);
		
	}
	
	// 分发消息给所有监听器方法
	private void fireMsgReceive(Message msg)
	{
		for(int i = 0; i < listeners.size(); i++)
		{
			listeners.get(i).receiveMsg(msg);		
		}
		
	}
	

}

        5. Message类定义代码;
       
package 监听器模式;

/**
 * Message
 * @author SurpriseLee
 *
 */
public class Message {

	private int id;   // 消息id
	private String content;
	
	public void setId(int id)
	{
		this.id = id;
	}
	
	public void setContent(String content)
	{
		this.content = content;
	}
}

     个人感悟
     监听器模式并不是不涉及到参数的传递,而是选择去传递那些某些属性不变的参数,或则说是传递那些传出模块不需要再次使用的参数。就像是工厂生产的产品,出厂后基本就不会再返厂再加工,工厂只需要关注怎样生产更适合消费者的产品就好,不用去告诉消费者产品的具体生产流程,只要将成型的产品发送给消费者,那么工厂作为生产者身份的任务就已经完成。而消费者只需要关注怎样去消费产品就好,不用去在意更不参与产品的设计生产过程。生产者与消费者这种生产与消费的有效分离,大大提高的软件系统维护的容易性。






分享到:
评论

相关推荐

    基于生产者消费者完整测试程序.rar

    生产者消费者模型是多线程编程中的经典设计模式,它描述了一种数据共享机制,通过缓冲区作为中间媒介,使得生产者线程可以将数据生产出来并存储,而消费者线程则负责从缓冲区取出并消费这些数据。这一模式在实现并发...

    生产者消费者 C#做的

    - 为了确保资源的有效管理,生产者和消费者应监听取消信号,并在完成任务后关闭Channel的读写器。这可以通过`CancellationToken`和`Dispose`方法实现。 8. ** 示例代码**: - 以下是一个简单的使用`Channel`实现...

    kafka生产和消费示例

    Spring MVC则是一个用于构建Web应用程序的轻量级框架,它提供了模型-视图-控制器(MVC)架构模式的实现。 首先,我们需要了解Kafka的基本概念。在Kafka中,生产者是负责发布消息到主题(Topic)的组件,而消费者则...

    activemq实战项目,同ssh框架整合(生产者+消费者)

    消费者可能是一个监听器,当接收到消息时触发特定的处理逻辑。 4. **特性与解决方案** - **消息重试**:在ActiveMQ中,可以通过配置消息的重试策略来处理发送失败的情况,如设置重试间隔和最大重试次数。 - **...

    spring 整合 activemq 生产者和消费者 案例源码

    对于消费者,可以创建一个`MessageListenerContainer`,该容器监听指定目的地的消息,并调用预定义的监听器方法来处理消息。 6. **编写业务逻辑**:在生产者的业务代码中,使用`JmsTemplate`发送消息。对于消费者,...

    RocketMQ生产者和消费者Java代码示例.zip

    消费者会根据设置的监听器自动拉取消息,当消息到达时,`consumeMessage`方法会被调用。在这个例子中,我们简单地打印出接收到的消息内容。 5. **注意事项** - 生产者和消费者在使用前都需要调用`start()`方法...

    ActiveMQ的队列模式

    消费者可以设置监听器,当有新消息到达时,监听器会被触发,执行相应的处理逻辑。 6. **持久化和事务**:ActiveMQ支持消息的持久化,即使服务器重启,未被消费的消息也不会丢失。同时,还可以结合JMS事务,确保消息...

    RabbitMQ工作模型及与Java 编程1

    基本步骤包括配置RabbitMQ连接,创建消息模板(`RabbitTemplate`),定义消息队列,以及设置生产者和消费者的监听器。 RabbitMQ的工作模式主要有五种:Direct、Fanout、Topic、Header和RPC。这些模式决定了消息如何...

    C#23种设计模式_示例源代码及PDF

    解释器模式: 给定一个语言后,解释器模式可以定义出其文法的一种表示,并同时提供一 解释器模式 个解释器。 客户端可以使用这个解释器来解释这个语言中的句子。 解释器模式将描述怎样 在 有了一个简单的文法后, ...

    ActiveMQ的队列queue模式(事务、应答、转发模式、阻塞消息)

    在ActiveMQ中,队列是一种点对点的消息传递模型,每个消息只能被一个消费者接收并处理。这种模式确保了消息的有序性和幂等性,适合处理有顺序要求或者需要独占处理的任务。 ### 2. 事务(Transactions) 在...

    Apache ActiveMQ学习笔记【原创:mq的方式有两种:点到点和发布/订阅】

    在这个模型中,生产者发送消息到队列,消费者从队列中取出并消费消息。每条消息只能被一个消费者接收。一旦消息被成功处理,就会从队列中移除该消息。这意味着,即使有多个消费者订阅了同一个队列,每个消息也只会被...

    java操作activeMQ(java项目代码及jar包可运行,队列和订阅模式)

    - 使用`createSubscriber()`方法创建订阅者,可以通过`MessageListener`监听器实时接收消息。 - 主题适合一对多的广播场景,如新闻推送或交易通知。 3. **Java API使用**: - `ConnectionFactory`:创建与...

    kafka-consumer:每个线程模式一个消费者卡夫卡消费者演示

    而`@KafkaListener`是Spring Kafka提供的一个注解,它可以简化消费者的配置,并允许我们以声明式的方式定义监听器方法,使得消费者操作更加直观。 **3. ConcurrentMessageListenerContainer** `...

    实用J2EE设计模式编程指南

    - **观察者模式**:J2EE中的事件驱动模型就应用了观察者模式,例如JSF(JavaServer Faces)中的组件和监听器。 **3. EJB设计模式** - **会话bean和消息驱动bean**:会话bean用于客户端交互,而消息驱动bean用于处理...

    kafka 18道面试题和答案.docx

    这里 `192.168.43.49:9092` 是 `server.properties` 文件中配置的监听器地址,每个新行即代表一条消息。 消费者接收消息的命令: - `bin/kafka-console-consumer.sh --zookeeper localhost:2181 -topic Hello-...

    rabbitmqdemo.zip

    在RabbitMQ中,生产者和消费者通过通道(Channel)与服务器交互,交换器(Exchange)负责根据预设规则将消息路由到队列,队列(Queue)是消息的临时存储区,而绑定(Binding)定义了交换器和队列之间的关系。...

    java多线程设计模式&amp;javaSocket&amp;java实用教程2.zip

    1. **生产者消费者模式**:在并发编程中,生产者负责生成数据,消费者负责消费数据。通过使用阻塞队列,可以确保生产者和消费者之间的同步,避免数据丢失或过度填充。 2. **单例模式**:确保一个类只有一个实例,并...

    springMVC-kafka消息分发

    它通过模型-视图-控制器(MVC)模式,将业务逻辑、数据呈现和用户交互分离开来,提高了代码的可维护性和可测试性。SpringMVC提供了丰富的注解支持,简化了Web应用的开发。 **Kafka简介** Apache Kafka是一种分布式...

Global site tag (gtag.js) - Google Analytics