Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Coloboración Paypal con 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: 22
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: 27
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: 22
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: 21
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: 27
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
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 06:43:12.


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