Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-02-2009
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 20
Bauhaus1975 Va por buen camino
Discusión OOP: Un sistema de avisos, usado por varias clases

Hola, os comento este tema, al que ahora le estoy dando vueltas:

Se trata de incluir un sistema de avisos (visuales) en un programa. Hay ciertas entidades o clases en el proyecto que son suceptibles de generar avisos: Por ejemplo, la entidad 'factura' debe dar avisos de facturas pendientes, así como la clase 'agenda' genera avisos cuando hay una cita apuntada para el dia actual. Este tipo de funcionalidad seguro que a muchos ya se os ha presentado. Lo ideal sería mostrar información del aviso y un enlace al formulario dónde se puedan ver los datos de la entidad/objeto que ha generado dicho aviso.

En este post me gustaria conocer/discutir cómo organizariais el modelado de objetos. Yo lo organizaria de la siguiente manera, hablando desde el punto de vista de UML.

Cita:

[Class Gestion]. Cualquier clase que necesite publicar avisos en el sistema. Inclye la Interfaz 'Aviso' que ofrece información sobre el método 'obtenerAvisos' a implementar por las clases.
+function ObtenerAvisos:listaAvisos (implementación)

[Interfaz Aviso]. Define un método que obtiene la lista de avisos. La lista de avisos puede contener información sobre: Un título, la entidad que epresenta, una 'manera' de abrir un formulario para acceder a los datos etc.
+function ObtenerAvisos:listaAvisos (definición)

[Class Aviso]. Ofrece la funcionalidad para mostrar la lista de avisos pendientes, por ejemplo al entrar en el programa, o en un momento eterminado. Aquí también podemos definir un tipo de datos para la estructura 'itemAviso' o la 'listaAvisos' antes mencionada.
No sé si hay interfaces en delphi, (todavía no sé nada sobre ello). En Java si las he usado. Aquí es donde necesitaria vuestra ayuda, si este enfoque es adecuado, para ver cómo se implementaria de la mejor manera.

Bueno, no sé si os habré liado mucho. Espero vuestros comentarios.
Gracias por vuestra atención y un saludo.
Responder Con Cita
  #2  
Antiguo 13-02-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Hola Bauhaus1975,
He visto que me haz enviado un mensaje al correo.
Bueno, déjame decirte que si había visto el hilo y he estado organizando y reordenando en mi cabeza tus palabras y algo no me agrada mucho.

Por empezar debo comentarte que tengo mis reservas de que basarse en ejemplos en Java para exponerlos a Delphi sea una buena idea. Sobre todo debido a que en Java hay demasiado purismos y existen ciertas diferencias en como resolver las cosas respecto a Delphi.
Si bien tiendo a pensar en purismos, me parece que Java llega a un extremo exagerado y prefiero llegar a un purismo que me brinda Delphi.

Debido a esto, no me atrevo a decir que la forma de como lo estás organizando este bien, ni tampoco puedo asegurar de que esté mal.
Ten presente que cada persona puede ver al asunto de forma diferente, pero ello no implica que uno sea malo y otro sea bueno. En POO existe el gris... sino mira a aquel animal símbolo máximo de que en la naturaleza y en POO las cosas no son simples hechos concretos y una simple lógica binaria: el ornitorrinco.

Asi que de entrada no tomes a mis palabras como la verdad absoluta. Si tu sientes que tu modelo sirve, quedate con él. No les mucha vuelta al asunto.

Me gustarías que expusieras de otro modo tu modelo y que reordenaras tus ideas. Temo no interpretar apropiadamente tus palabras y me gustaría que seas un poco más gráfico/a. Disculpame pero no veo un punto de vista UML el asunto

Lo que más me nubla y cuesta interpretar es la diferencia entre la clase Gestion y la clase Aviso... ¿al final que hace cada una? ¿Que relación existe entre una y otra?

En Delphi existen las interfaces. Lee desde la página 801 de la Cara Oculta de Delphi 4 (puedes acceder a una copia del mismo en .pdf en el FTP del club), allí está expuesto el tema de las interfaces. Recomiendo además la lectura de la ayuda que ofrece Delphi al respecto.

Habría que ver hasta que punto es bueno tener esa interfaz. En Delphi, no es tan necesario estar definiendo interfaces. De vez en cuando añadirlas provoca más ruido... en principio bastaría con una clase que implemente los métodos necesarios.

Para asesorarte bien, necesitaría conocer mejor el negocio o contexto. Ver estas simples clases es la mitad del problema. Deberías saber que sin analizar en contexto no se puede tomar una decisión.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #3  
Antiguo 16-02-2009
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 20
Bauhaus1975 Va por buen camino
Gracias Delphius por responder. He leido atentamente las lecturas que me has recomendado y he estudiado tus consejos. También he visto que puedo usar interfaces si lo considerase oportuno. Paso ahora a profundizar un poco más en el tema:

Cita:
Empezado por Delphius Ver Mensaje
Hola Bauhaus1975,
Para asesorarte bien, necesitaría conocer mejor el negocio o contexto. Ver estas simples clases es la mitad del problema. Deberías saber que sin analizar en contexto no se puede tomar una decisión.
Exposición del contexto:
Pensemos un programa para gestionar Clientes, Facturas, Citas... que cuenta con entidades como 'Agenda', para apuntar hitos o citas y 'Factura', entre otras. Necesito mostrar avisos, por ejemplo en forma de lista al entrar al programa, o cuando sea necesario. Por tanto, se generarán avisos por aquellas entidades suceptible de generar avisos (Agenda o Factura). Sería adecuado que la ventana / form que muestre los avisos presente un texto descriptivo del aviso y un enlace al formulario que trate el dato 'a revisar'.

Cita:
Empezado por Delphius Ver Mensaje
Hola Bauhaus1975,
Lo que más me nubla y cuesta interpretar es la diferencia entre la clase Gestion y la clase Aviso... ¿al final que hace cada una? ¿Que relación existe entre una y otra?
La Clase 'Gestion' es una clase que representa a Agenda o Factura (o cualquiera suceptible de generar avisos). A modo de ejemplo había usado un término genérico. También puedes pensar que es una clase padre de ambas. Esta clase implementa los métodos de la interfaz 'Aviso'.

La Clase 'Aviso' la había pensado para que ofreciera funcionalidad para mostrar los avisos. En una ventana con la lista antes comentada.

La Interfaz 'Aviso' es la que define el/los método/s necesarios para obtener los avisos. A implementarse en las Clases de tipo 'Gestion'.

Mi idea de usar una interfaz era para garantizar que el método que obtenga los avisos en cada entidad garantizara homogeneidad, es decir, que ofrezca un patrón de comportamiento. Por esto había pensado en usar una interfaz, si bien no es obligatorio. Y no porque estuviera pensando en términos de Java o traduciendo un programa de Java.

La idea de este post era dialogar con gente que ha tenido que implementar este caso para ver qué decisión han optado, o áprender de personas más expertas su opnión de como implementar este caso. Es por eso que a lo mejor necesito que me acerqueis a los 'purismos' que comentas de Delphi para ir implementando este caso de la mejor manera.

Muchas gracias por la atención y un saludo.
Responder Con Cita
  #4  
Antiguo 16-02-2009
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 19
Chris Va por buen camino
Estamos hablando en formas astractas. (Class TAviso, TGestion) y cómo las he de utilizar luego?

A cómo dijo delphius anteriormente, eso depende del punto de vista de cada uno. En lo personal YO antes de escribir e implementar una clase la visualizo desde el punto de como la he de llamar, cómo la quiero llamar y qué grado de fácilidad y flexivilidad quiero que tenga cunado la quiera llamar.

Si yo fuera tú, primero me pondría a pensar en que grado de dificultad que tendré al momento de utilizar clases o interfaces, así cómo también implementarlas.

Según la tarea y objetivo que buscas yo mejor dejaría las clases a un lado me utilizaría mejor algun tipo de función en, por ejemplo, la unidad de facturación que me devuelva todos los avisos de facturación y así sucesivamente.

Saludos.
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #5  
Antiguo 16-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Hola,

Creo que confunde un poco la terminología que usas. En principio, tal como yo lo entendería, para un sistema de avisos no necesitas ninguna interfaz ni clase ancestra común. Simplemente necesitarías un objeto central GestorAvisos con un método público ColocarAviso:

Código:
+------------------------------+
| GestorAvisos                 |
+------------------------------+
| +ColocarAviso(Aviso: TAviso) |
+------------------------------+
Cualquier clase del sistema puede colocar un aviso sin necesidad de implementar interfaz alguna.




No obstante, lo que tú tienes más parece ser una lista de pendientes. En tal caso, creo que podrías partir de una interfaz:

Código:
+-----------------------+
| IEntidad              |
+-----------------------+
| +getListaPendientes() |
+-----------------------+
que tendría que implementar cualquier clase que quiera publicar su lista de pendientes. Cada una de estas clases tendría que registrarse con un gestor central:

Código:
+--------------------------------------------+
| GestorPendientes                           |
+--------------------------------------------+
| -FEntidades                                |
+--------------------------------------------+
| +RegistrarEntidad(Entidad: IEntidad)       |
| +EnumerarPendientes()                      |
+--------------------------------------------+
Dicho gestor, en el momento que tú decidas (al principio de la aplicación, cuando lo requiera el usuario, cada cierto tiempo, etc.) revisará su lista de clases registradas (FEntidades) para saber a cuáles debe solicitar la lista de pendientes.

// Saludos
Responder Con Cita
  #6  
Antiguo 16-02-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
¡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,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #7  
Antiguo 16-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Yo me permito insistir un poco en la nomeclatura. El hecho de haya facturas pendientes es una situación, no un aviso. Porque mientras persista dicha situación, el objeto fuente tendría que estar generando el mismo aviso, que es lo que no me cuadra.

Ahora, más allá de los términos exactos, creo que éste es un caso en donde las interfaces aplican muy bien. Una entidad agenda y una entidad facturas, en principio podrían no tener nada en común salvo el hecho de poder publicar una lista de pendientes. En este caso, derivar ambas de una clase común podria ser algo forzado y no natural para efectos de la aplicación.

Cita:
Empezado por Delphius
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
A como veo las cosas, tiene que ser así. Porque el hecho de publicar un aviso no resuelve la tarea, es decir, la factura sigue pendiente por ejemplo, y desde luego, no puede ser el gestro de avisos quien cumplimente la operación, debe por fuerza ser la entidad que genera el aviso. Por ello es que aviso no es un término que me parezca adecuado.

Cita:
Empezado por Delphius
En este caso, tal vez TGestorAviso disponga de métodos como ObtenerPendientes()
Básicamente es lo que planteé con el método getListaPendientes de la interfaz IEntidad.

Cita:
Empezado por Delphius
y reciba como parámetro un TPublicadorAviso
aunque esta parte no le veo necesidad. Cada IEntidad (o IPublicadorPendientes) se registra con el Gestor de manera que éste simpemente debe ciclar sobre la lista de registrados llamando al método getListaPendientes:

Código Delphi [-]
for I := 0 to FEntidades.Count - 1 do
begin
  FEntidades[i].getListaPendientes(...);
end;

que básicamente sería lo que llamé EnumerarPendientes.

// Saludos
Responder Con Cita
  #8  
Antiguo 16-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Aquí va mi idea más desarrollada:

Partiremos de una clase TPendiente (si quieren llamarla TAviso está bien ) que represente un pendiente:

Código Delphi [-]
TPendiente = class
private
  FFuente: String;
  FDescripcion: String;

public
  property Fuente: String read FFuente write FFuente;
  property Descripcion: String read FDescripcion write FDescripcion;
end;

Fuente sería el nombre de la entidad que genera el pendiente o aviso y Descripcion sería la descripción del pendiente. Obviamente la estructura real de esta clase dependerá de lo que se quiera publicar.

Luego tenemos la interfaz que publica mensajes

Código Delphi [-]
IPublicadorPendientes = interface
['{B34CC894-1ED9-4968-BE00-09D48676F734}']
  procedure getListaPendientes(Lista: TList);
end;

Lo que está entre corchetes es el GUID (global unique identifier) de la interfaz y es necesario declararlo (Ctrl+Shift+G) para poder moldear una interfaz con el operador as.

getListaPendientes deberá llenar la lista que se le pasa como parámetro con los pendientes que haya.

Después tenemos el gestor de pendientes:

Código Delphi [-]
TGestorPendientes = class
private
  FPublicadores: TInterfaceList;

public
  constructor Create;
  destructor Destroy; override;

  procedure RegistrarPublicador(Publicador: IPublicadorPendientes);
  procedure EnumerarPendientes(Publicar: TPublicarPendiente);
end;

Este gestor mantiene una lista interna de las entidades que se registren para publicar pendientes. Obsérvese que es una lista de interfaces, no de clases. Dicha lista se crearía en el constructor Create y se destruiría en el destructor.

Un entidad que quiera publicar pendientes se registra con el método RegistrarPublicador, quien simplemente añade la entidad a la lista interna.

El método EnumerarPendientes es el encargado de recorrer todos los pendientes de todas las entidades registradas. Pero este método no publica el pendiente, ya que esto es materia de la parte visual de la aplicación, que decidirá si pone el pendiente en un ListView, en un Memo, o lo manda por correo, o cualquier cosa que quiera hacer con el pendiente.

Para ello, al método se le pasa como parámetro un procedimiento, que será el encargado de publicar el pendiente. El tipo TPublicarPendiente se define asi:

Código Delphi [-]
TPublicarPendiente = procedure(Pendiente: TPendiente) of object;

Así, por ejemplo, el formulario principal puede declarar un método

Código Delphi [-]
TMainForm = class(TForm)
private
  procedure PublicarPendiente(Pendiente: TPendiente);
end;

que pondrá el pendiente en el control visual que desee. Cuando se requiera listar los pendientes se llamará al gestor:

Código Delphi [-]
GestorPendientes.EnumerarPendientes(PublicarPendiente);

El método EnumerarPendientes podría implementarse así:

Código Delphi [-]
procedure TGestorPendientes.EnumerarPendientes(Publicar: TProcesarPendiente);
var
  Pendientes: TList;
  I, J: Integer;

begin
  Pendientes := TList.Create;

  try
    // Recorrer la lista de publicadores
    for I := 0 to FPublicadores.Count - 1 do
    begin
      // Obtener la lista de endientes de este publicador
      (FPublicadores[i] as IPublicadorPendientes).getListaPendientes(Pendientes);

      // Publicar cada pendiente de este publicador
      for J := 0 to Pendientes.Count - 1 do
      begin
        Publicar(TPendiente(Pendientes[J]));
      end;
    end;
  finally
    Pendientes.Free
  end;
end;

Como dije antes, EnumerarPendientes simplemente recorre la lista de pendientes más no hace nada con ellos excepto llamar al método que se le pasa como parámetro.

Esto nos permite usar distintos métodos según sea el caso. Por ejemplo, además del método PublicarPendiente del formulario principal, podríamos tener un EnviarPendiente, que se encargue de mandar el pendiente por correo, de manera que

Código Delphi [-]
GestorPendientes.EnumerarPendientes(EnviarPendiente);

tendría el efecto de enviar por correo la lista de pendientes.

// Saludos
Responder Con Cita
  #9  
Antiguo 16-02-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Yo me permito insistir un poco en la nomeclatura. El hecho de haya facturas pendientes es una situación, no un aviso. Porque mientras persista dicha situación, el objeto fuente tendría que estar generando el mismo aviso, que es lo que no me cuadra.
Pues yo la verdad no entiendo si al final se trata de facturas pendientes... y/o si debemos entender por aviso otra cosa.
Hace falta claridad en las explicaciones de Bauhaus1975 sobre el contexto en forma intregral (macro) del problema y no en éstas simples clases.

Cita:
Empezado por roman Ver Mensaje
Ahora, más allá de los términos exactos, creo que éste es un caso en donde las interfaces aplican muy bien. Una entidad agenda y una entidad facturas, en principio podrían no tener nada en común salvo el hecho de poder publicar una lista de pendientes. En este caso, derivar ambas de una clase común podria ser algo forzado y no natural para efectos de la aplicación.
Estaba pensando en ello también. Creo que el tener esta interfaz serviría, y además nos evitaría el tener que depender de alguna clase base.


Cita:
Empezado por roman Ver Mensaje
A como veo las cosas, tiene que ser así. Porque el hecho de publicar un aviso no resuelve la tarea, es decir, la factura sigue pendiente por ejemplo, y desde luego, no puede ser el gestro de avisos quien cumplimente la operación, debe por fuerza ser la entidad que genera el aviso. Por ello es que aviso no es un término que me parezca adecuado.
Pues yo no puedo decir, ni asegurar que deba ser ser así. Hay cosas que no están bien claras.
Efectivamente, creo que debemos partir de este punto. ¿Qué debemos entender por aviso?

Además, me suena un tanto extraño de que entidades, un tanto dispares como ser TAgenda y Factura deban dar respuesta a una misma problemática. ¿Que és este TAgenda? ¿Qué es esta TFactura? ¿Qué tiene que ver citas, agendas y facturas? No se, pero no me gusta mucho mezclar citas con negocios.
Yo pido que Bauhaus1975 se explique apropiadamente.

Cita:
Empezado por roman Ver Mensaje
Básicamente es lo que planteé con el método getListaPendientes de la interfaz IEntidad.

aunque esta parte no le veo necesidad. Cada IEntidad (o IPublicadorPendientes) se registra con el Gestor de manera que éste simpemente debe ciclar sobre la lista de registrados llamando al método getListaPendientes:

Código Delphi [-]for I := 0 to FEntidades.Count - 1 do begin FEntidades[i].getListaPendientes(...); end;


que básicamente sería lo que llamé EnumerarPendientes.

// Saludos
Eso noté luego. Tu idea me resulta mejor.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #10  
Antiguo 16-02-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Impresionante roman.
Cuando estaba respondiendo ví que habías puesto algo más concreto.

Me sorprende lo de pasar como parámetro el procedimiento. No se me hubiera ocurrido.

Hoy aprendo algo nuevo: desconocía TInterfaceList.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #11  
Antiguo 16-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
Además, me suena un tanto extraño de que entidades, un tanto dispares como ser TAgenda y Factura deban dar respuesta a una misma problemática. ¿Que és este TAgenda? ¿Qué es esta TFactura? ¿Qué tiene que ver citas, agendas y facturas?
Precisamente por eso viene lo de interfaces. Agendas, facturas y seguramente otras entidades del sistema del compañero, tiene poco a nada en común, salvo el hecho de notificar que hay tareas pendientes. Y es esta problemática la que resuelve la interfaz. No es que esas entidades deban dar respuesta a una misma problemática, sino que esta problemática es común (y quizá lo único común) a ellas.

// Saludos
Responder Con Cita
  #12  
Antiguo 16-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
Me sorprende lo de pasar como parámetro el procedimiento. No se me hubiera ocurrido.
Pues son de las cosas que te gustan. Si no me equivoco, no es más que el patrón Iterador (interno).

// Saludos
Responder Con Cita
  #13  
Antiguo 16-02-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Pues son de las cosas que te gustan. Si no me equivoco, no es más que el patrón Iterador (interno).

// Saludos
Había "escuchado" sobre ese patrón, pero no lo he estudiado. Más adelante le daré su debido tiempo de análisis y estudio y me documentaré al respecto.
Gracias por el dato.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #14  
Antiguo 17-02-2009
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 20
Bauhaus1975 Va por buen camino
Muy buenas compañeros. Me alegra ver como ha crecido el interés en el post (y eso que había empezado flojo).
Es cierto, probablemente lo que nos parece bien explicado no se entienda por diferente uso de términos. Y sin duda, los nombres que tomé inicialmente eran demasiado genéricos.

Cita:
Empezado por Delphius Ver Mensaje
Estaba pensando en ello también. Creo que el tener esta interfaz serviría, y además nos evitaría el tener que depender de alguna clase base.
Estupendo, me alegra que seas el primero que me de la razón en algo . Es broma, mi madre alguna vez ya lo hizo antes.

Cita:
Empezado por Delphius Ver Mensaje
¿Qué debemos entender por aviso?
Hasta donde yo había pensado, una descripción y un enlace que pueda abrir un formulario para acceder al dato y poder cambiar esa situación.
Y como apunto más adelante una propiedad 'prioridad' = (urgente, normal)

Cita:
Empezado por Delphius Ver Mensaje
Además, me suena un tanto extraño de que entidades, un tanto dispares como ser TAgenda y Factura deban dar respuesta a una misma problemática. ¿Que és este TAgenda? ¿Qué es esta TFactura? ¿Qué tiene que ver citas, agendas y facturas? No se, pero no me gusta mucho mezclar citas con negocios.
Yo pido que Bauhaus1975 se explique apropiadamente.
Nada que ver, evidentemente. Por eso Roman está acertado viendo lo conveniente de introducir una Interfaz que defina la funcionalidad necesaria para obtener el aviso. 'obtener' -> Aquí nos hemos creado confusión con el término. Cada entidad que quiera 'publicar' avisos debe implementar un método con sus propios criterios para obtener dichos elementos.
Es más, por eso he puesto así el ejemplo. Porque el sub-sistema que estamos definiendo quede aislado del contexto. Es decir, igual que hemos hablado de facturas y agenda podemos pensar en un artículo que se haya agotado y hay que pedirlo. (serviría a cualquier proyecto con entidades suceptibles de generar 'pendientes')

Otra cosa, como apuntais: No todos los avisos son iguales. Me explico, a lo mejor es bueno mostrar 'de vez en cuando' en la ventana de avisos los artículos que faltan, pero a lo mejor en cuanto a las facturas pendientes de pago es suficiente con que aparezcan al iniciarse el programa.
Por tanto puede que el objeto que represente a un item 'aviso' tenga 'prioridad' = (urgente, normal) prioridad normal podría ser sólo para mostrar en la ventana al iniciarse el programa, y urgente para mostrar periódicamente.

He leido detenidamente el análisis de Roman y me parece lo más acertado. Y, el uso del InterfaceList y el paso del procedimiento como parámetro impresionante ejemplo de elegancia.

Entonces podemos resumir las clases y sus responsabilidades:

TPendiente: representa a un item. con elementos como (prioridad, fuente, descripcion)
IPublicador: La interfaz que define el método para obtener los pendientes de clase con getListaPendientes(Lista: TList);
TGestorPendientes: Se encarga de ofrecer el registro a las clases que quieran publicar, y de enumerar los items a publicar
TPublicarPendiente: Un tipo procedimiento para que la acción 'publicar' sea cualquier cosa que implemente una clase encargada del tema gráfico u otros.

Podría quedar por sacar punta a como añadir la acción de abrir formulario de la entidad a la que se refiera el item (TPendiente)

Para el tema de controlar avisos de alta prioridad se puede incorporar un sistema de control periódico, si no recuerdo mal esto se ha tratado antes en otros post. (Abajo en la lista de relacionados puede verse algún ejemplo)

Espero que este laborioso estudio ofrezca información de este sistema y muchos compañeros puedan implementarlo cuando les haga falta. Yo estoy ya deseando de implementarlo, a ver si puedo sacar hueco porque estoy con varias cosas a la vez.

Un saludo.

Última edición por Bauhaus1975 fecha: 17-02-2009 a las 18:51:31.
Responder Con Cita
  #15  
Antiguo 17-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Bauhaus1975 Ver Mensaje
Cita:
Empezado por roman
Estaba pensando en ello también. Creo que el tener esta interfaz serviría, y además nos evitaría el tener que depender de alguna clase base.
Esto, en realidad, lo dijo Delphius.

Cita:
Empezado por Bauhaus1975
Podría quedar por sacar punta a como añadir la acción de abrir formulario de la entidad a la que se refiera el item (TPendiente)
La clase TPendiente puede tener una propiedad que apunte al formulario deseado.

Por otra parte estaba pensando que una ampliación que puede hacerse es la de incluir al gestor de mensajes en la interfaz IPublicador con objeto de que cada publicador pueda notificar al gestor cuando hay algún cambio en su lista de pendientes.

// Saludos
Responder Con Cita
  #16  
Antiguo 17-02-2009
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 20
Bauhaus1975 Va por buen camino
Cita:
Empezado por roman Ver Mensaje
Esto, en realidad, lo dijo Delphius.



La clase TPendiente puede tener una propiedad que apunte al formulario deseado.

Por otra parte estaba pensando que una ampliación que puede hacerse es la de incluir al gestor de mensajes en la interfaz IPublicador con objeto de que cada publicador pueda notificar al gestor cuando hay algún cambio en su lista de pendientes.

// Saludos
Perdón, lo rectifico ahora mismo.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Discusión sobre Patrones de diseño Delphius OOP 3 31-05-2008 20:38:03
Agenda con Avisos luxus Conexión con bases de datos 5 11-12-2007 22:23:38
Avisos parroquiales jam Humor 3 07-04-2006 09:15:31
Capturar Errores y/o avisos sergio_015 Varios 5 11-02-2004 06:06:35
lista de discusion allende Varios 2 03-12-2003 20:21:19


La franja horaria es GMT +2. Ahora son las 16:31:45.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi