¡Orden en la sala!
Siempre quise decir eso
Pues creo que no se termina de comprender, bien el asunto. Y todo se debe a los nombres tanto de las clases como de sus métodos. Vayamos al primer punto elemental a cuestionar:
¿Quién da a conocer los avisos? ¿Y quien los genera?
No es lo mismo gestionar, que generar
A como yo lo entiendo, TFactura y TAgenda son quienes GENERAN avisos (aunque creo que el término más adecuado sería PUBLICAR), los cuales son luego administrados por una sola clase TGestorAviso (por darle un nombre). TGestorAviso tiene por tanto la responsabilidad de ordenarlos, clasificarlos, etc. En pocas, hará con lo avisos lo que deba hacer. Al final, es ésta clase quien terminará mostrando los avisos al usuario.
Una manera de enfocar el tema es algo similar a como lo detalle roman. TAgenda, TFactura y demás clases interesadas se registran a este TGestor. TGestor recibirá de todas las entidades que se registren los avisos. Si no me equivoco en el término, creo que aquí podría ser útil las "clases amigas". Algo similar a como funciona TParam y TParams, y otras colleciones.
Todas las entidades que publiquen avisos debe heredar de una clase base, a falta de imaginación la llamo: TPublicadorAviso. TPublicadorAviso está diseñado para mantener una referencia del Gestor al que se asociará y contará con al menos tres métodos: Suscribirse(), PublicarAviso() y Desuscribrirse() (sería mejor Reigstrar, pero no encuentro su antónimo

)
Código:
+------------------------------------------+
| TPublicadorAviso |
+------------------------------------------+
| - FGestorAviso: TGestorAviso |
+------------------------------------------+
| + Suscribirse(GestorAviso: TGestorAviso) |
| + PublicarAviso(Aviso: TAviso) |
| + Desuscribirse |
+------------------------------------------+
De éste modo, unas posible (y simples) implementaciones de éstos métodos podría ser:
Código Delphi
[-]procedure TPublicadorAviso.Suscribirse(GestorAviso: TGestorAviso);
begin
if not assigned(FGestorAviso)
then begin
GestorAviso.Registrar(Self);
FGestorAviso := GestorAviso;
end;
end;
procedure TPublicadorAviso.PublicarAviso(Aviso: TAviso);
begin
FGestorAviso.AgregarPendientes(Aviso);
end;
procedure TPublicadorAviso.Desuscribirse;
begin
FGestorAviso.Eliminar(Self);
FGestorAviso := nil;
end;
Como se ve, se delegan algunas cosas a un TGestorAviso, que muy posiblemente sea un Singleton. Ahora TGestorAviso debe tener dos listas, una para llevar sus Publicadores y otra con los avisos. Ya podemos ir viendo algunos de sus métodos:
Código:
+-------------------------------------------+
| TGestorAviso |
+-------------------------------------------+
| - FPublicadores: TObjectList |
| - FAvisosPendientes: TObjectList |
+-------------------------------------------+
| + Registrar(Publicador: TPublicadorAviso) |
| + AgregarPendientes(Aviso: TAviso) |
| + Eliminar(Publicador: TPublicadorAviso |
| + MostrarAviso(Aviso) |
+-------------------------------------------+
Creo que no hace falta mucha imaginación y dar detalles de lo que sucede aquí,
Registrar() debería agregar en la lista de publicadores al PublicadorAviso, de forma similar, AgregarPendientes() agrega el aviso a su lista.
Un enfoque similar, habría que determinar cual es el más conveniente, es que el TGestorAviso no maneje la lista, sino que cada PublicadorAviso maneje la propia. En este caso, tal vez TGestorAviso disponga de métodos como ObtenerPendientes() y reciba como parámetro un TPublicadorAviso, y de este modo TPublicadorAviso le hace llegar o conocer sus avisos. Luego, el TGestor "recorre" el listado de estos avisos y actúa en razón a ellos. Ahora podría ser útil un PublicarLista.
Código:
+------------------------------------------+
| TPublicadorAviso |
+------------------------------------------+
| - FGestorAviso: TGestorAviso |
| - FListaPendientes: TObjectList |
+------------------------------------------+
| + Suscribirse(GestorAviso: TGestorAviso) |
| + PublicarAviso(Aviso: TAviso) |
| + PublicarLista |
| + Desuscribirse |
+------------------------------------------+
¿Se entiende? Espero que sí.
Saludos,