TMessageManager
es una clase fundamental en Delphi, parte de la unidad System.Messaging
, que actúa como un centro de notificaciones a nivel de aplicación. Permite la comunicación entre diferentes componentes de una aplicación mediante el envío y recepción de mensajes, promoviendo un diseño desacoplado y modular.
Este sistema es especialmente útil en aplicaciones complejas donde se requiere mantener una separación clara entre los distintos módulos, facilitando así el mantenimiento y la escalabilidad del software.
TMessageManager
utiliza el patrón singleton, lo que garantiza que exista una única instancia gestionando todos los mensajes dentro de la aplicación. Esto se accede comúnmente mediante TMessageManager.DefaultManager
.
Permite que múltiples componentes se suscriban a diferentes tipos de mensajes. Los suscriptores pueden recibir notificaciones específicas sin necesidad de conocer los detalles de los emisores.
A través del método SendMessage
, los componentes pueden enviar mensajes que serán recibidos por todos los suscriptores registrados para ese tipo de mensaje.
TMessage
Todos los mensajes deben derivar de la clase TMessage
. Esto permite una estructura común para todos los tipos de mensajes y facilita la gestión de diferentes tipos de datos.
En aplicaciones con múltiples formularios, TMessageManager
facilita la comunicación entre ellos sin necesidad de referencias directas, promoviendo un diseño más limpio y modular.
Permite que operaciones en segundo plano notifiquen a la interfaz de usuario sobre actualizaciones necesarias, evitando bloqueos y garantizando una experiencia de usuario fluida.
En aplicaciones modulares, TMessageManager
facilita la comunicación entre componentes independientes, mejorando la mantenibilidad y escalabilidad del sistema.
Para eventos que deben ser manejados por múltiples partes de la aplicación, como cambios en la configuración o eventos de autenticación, TMessageManager
es la herramienta ideal para enviar notificaciones globales.
uses
System.Messaging;
type
TMyMessage = class(TMessage)
private
FData: string;
public
constructor Create(const AData: string);
property Data: string read FData;
end;
constructor TMyMessage.Create(const AData: string);
begin
inherited Create;
FData := AData;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TMessageManager.DefaultManager.SubscribeToMessage(TMyMessage, HandleMyMessage);
end;
procedure TForm1.HandleMyMessage(const Sender: TObject; const M: TMessage);
var
MyMessage: TMyMessage;
begin
if M is TMyMessage then
begin
MyMessage := TMyMessage(M);
ShowMessage('Mensaje recibido: ' + MyMessage.Data);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TMessageManager.DefaultManager.SendMessage(Self, TMyMessage.Create('Hola, Mundo!'));
end;
En este ejemplo, se define un mensaje personalizado TMyMessage
que contiene un dato de tipo string
. El formulario se suscribe a este tipo de mensaje y define un manejador HandleMyMessage
que se ejecuta cuando se recibe el mensaje. Al hacer clic en un botón, se envía un mensaje de tipo TMyMessage
que es recibido y procesado por el formulario.
uses
System.Messaging, System.Threading;
type
TDataUpdatedMessage = class(TMessage);
procedure TForm1.Button1Click(Sender: TObject);
begin
TTask.Run(procedure
begin
// Simular una operación larga
Sleep(2000);
// Notificar que los datos han sido actualizados
TThread.Queue(nil, procedure
begin
TMessageManager.DefaultManager.SendMessage(Self, TDataUpdatedMessage.Create);
end);
end);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TMessageManager.DefaultManager.SubscribeToMessage(TDataUpdatedMessage, HandleDataUpdated);
end;
procedure TForm1.HandleDataUpdated(const Sender: TObject; const M: TMessage);
begin
ShowMessage('Los datos han sido actualizados');
end;
Este ejemplo simula una operación larga en un hilo secundario. Una vez que la operación ha finalizado, se envía un mensaje TDataUpdatedMessage
para notificar que los datos han sido actualizados. El formulario se suscribe a este mensaje y muestra una notificación cuando lo recibe.
type
TNotificationMessage = class(TMessage)
NotificationText: string;
constructor Create(const AText: string);
end;
constructor TNotificationMessage.Create(const AText: string);
begin
inherited Create;
NotificationText := AText;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Subscripciones para diferentes módulos de la aplicación
TMessageManager.DefaultManager.SubscribeToMessage(TNotificationMessage,
procedure(const Sender: TObject; const Msg: TMessage)
begin
Memo1.Lines.Add('Notificación: ' + TNotificationMessage(Msg).NotificationText);
end);
end;
procedure TForm1.SendNotification(const AText: string);
begin
// Enviar una notificación global
TMessageManager.DefaultManager.SendMessage(nil, TNotificationMessage.Create(AText));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SendNotification('Nuevo evento ocurrido.');
end;
En aplicaciones más complejas, este sistema de notificaciones permite que varios módulos se suscriban a diferentes tipos de eventos, manteniendo una comunicación eficiente y organizada.
Es crucial desuscribirse de los mensajes cuando ya no son necesarios para evitar fugas de memoria y referencias inválidas. Esto se debe hacer, por ejemplo, en el destructor de los formularios.
procedure TForm1.FormDestroy(Sender: TObject);
begin
TMessageManager.DefaultManager.Unsubscribe(TMyMessage, HandleMyMessage);
end;
El emisor del mensaje es responsable de liberar la instancia del mensaje después de enviarlo para evitar fugas de memoria.
procedure TForm1.Button1Click(Sender: TObject);
var
MyMessage: TMyMessage;
begin
MyMessage := TMyMessage.Create('¡Hola desde Button1!');
try
TMessageManager.DefaultManager.SendMessage(Self, MyMessage);
finally
MyMessage.Free;
end;
end;
Gracias a la comunicación desacoplada que proporciona TMessageManager
, se reduce la probabilidad de crear dependencias circulares entre componentes, lo cual facilita el mantenimiento y la escalabilidad del código.
Crear clases específicas para cada tipo de mensaje asegura que solo se incluya la información necesaria, mejorando la claridad y eficiencia del sistema de mensajería.
Método | Descripción |
---|---|
SubscribeToMessage |
Permite a un componente suscribirse a un tipo específico de mensaje. |
SendMessage |
Envía un mensaje a todos los suscriptores registrados para ese tipo de mensaje. |
Unsubscribe |
Cancela una suscripción previamente establecida. |
El uso de TMessageManager
en Delphi ofrece una solución robusta para la gestión de mensajes dentro de aplicaciones, promoviendo una comunicación eficiente y desacoplada entre componentes. Esta clase facilita la creación de aplicaciones modulares y escalables, mejorando tanto la mantenibilidad como la legibilidad del código. Al implementar las mejores prácticas y considerar cuidadosamente la gestión de suscripciones y memoria, los desarrolladores pueden aprovechar al máximo las capacidades de TMessageManager
para construir aplicaciones Delphi avanzadas y robustas.