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 05-12-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Meter en una lista sólo las clases "punta" (descendientes sin hijas) de una jerarquía

Hola a todos.

Escribiendo un método, encontré que este necesita buscar en cierta colección de clases todas aquellas que desciendan, directa o indirectamente, de una clase en particular, y copiar éstas a una lista, pero solamente las que no tengan clases hijas.

Tomemos como ejemplo la siguiente jerarquía:
Código Delphi [-]
TA = Class
...
TB = Class (TA)
...
TC = Class (TA)
...
TD = Class (TC)
...
TE = Class (TC)
Me interesa poner en una lista sólo las clases TB, TD y TE. Esto porque, de todas las que derivan de TA, son las únicas que no tienen clases hijas. No hay más clases que deriven de TB, TD y TE, por tanto podemos decir que son clases "punta" o finales (end classes).

La implementación no tiene dificultades, pero es evidente que el proceso de búsqueda y selección podría quedar de mejor forma aislándolo en una clase o método creado especialmente para ello. Que disertemos sobre el diseño es lo que me interesa. De momento considero estas vías:

1. Definir una clase lista genérica, derivada de la TList genérica:
Código Delphi [-]
TEndClassList <TClassRef> = Class (TList <TClassRef>)
...
La cual tenga un método función Boolean llamado TryAdd:
Código Delphi [-]
If MiListaDeFinales.TryAdd (Clase) Then
El cual haría lo siguiente:
1.1 Verificar si la lista contiene una clase ancestro del parámetro Clase, en cuyo caso lo quitaría de la lista antes de agregar Clase (porque Clase está más abajo que su ancestro).
1.2 Verificar si la lista contiene una clase descendiente del parámetro Clase, y sólo en caso de no haberla agregar Clase.

2. Definir en una clase lista de clases general ya existente un nuevo método que haga la operación descrita en la opción 1.
Código Delphi [-]
MiListaDeClases.TryAddEnd (ClaseBase, Clase);  // O TipoReferenciaDeClase en lugar de ClaseBase

3. Un nuevo método en la colección original (la que contiene el universo de clases) encargado de "exponer" las clases finales que cumplan con el criterio antes explicado. Es decir, que en lugar de colocar la característica en el lado del receptor (la lista que alojará las clases finales), ésta quede en el lado del "emisor".

4. Dado que la funcionalidad de buscar clases finales podría requerirse para copiar de cualquier tipo de colección origen que contenga clases hacia cualquier tipo de lista destino que contenga clases, dicha funcionalidad podría implementarse mejor en una función o clase intermediaria (proxy). Haciendo enumeración en el origen para guardar las clases seleccionadas en el destino.

Bueno, espero haber sido claro. Someto a su consideración el planteamiento completo a fin de diseñar una buena solución para esta necesidad.

Un cordial saludo.

Al González.
Responder Con Cita
  #2  
Antiguo 10-12-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola amigos, no siempre escribo con tinta blanca.

Decidí por la opción 1, una clase lista especializada (lo de "genérica" era porque admite parámetro de tipo), de nombre tentativo TghLeafClassList. Analizando los demás caminos, descubro que todos ellos podrían apoyarse en ésta. Es decir, que esta clase especializada tendría un funcionamiento básico para apoyar soluciones más elaboradas

También recordé que uno de los términos usados para referirnos a esta categoría de clases es clase hoja (leaf class), por la semejanza que hay entre una jerarquía de clases y las ramas de un árbol. De éstas últimas pueden nacer otras ramas y de las últimas ramas nacer hojas. Sin embargo, queda la duda de si es incorrecto llamarles así a las clases que no tienen hijas, pero de las cuales sí hay libertad para derivar subclases: no me convence del todo la sentencia en Wikipedia de "no debería". ¿Ustedes qué opinan?

Un cordial saludo.

Última edición por Al González fecha: 10-12-2014 a las 17:34:19.
Responder Con Cita
  #3  
Antiguo 10-12-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
La razón de que "no debería" es debido al problema que se da en los códigos OO. Es un Code Smell.


"Plano es mejor que anidado". Es una (posible) falla de diseño el tener una jerarquia muy profunda. Es reconocido ahora que es mejor componer que heredar en la OO (y en general). Asi que la existencia de clases hoja puede indicar que es momento de "cerrar" la profundidad y dejar de que crear tanta subclase.

La OO es un arbol. Mientras mas grande y profundo, mas complejo y fragil. Mientras mas aplanado, mejor.

Pero eso es una idea para quien genera clases y quiere evitar una "explosion de clases". Cada nueva clase genera un crecimiento en la complejidad y eso hay que evitarlo.

Pero si estas haciendo introspección, el que esten "mal" o "bien" las clases es irrelevante. Tu tarea es analizar lo que hay, no criticarlo

P.D: Porque quieres hacer algo tan raro?

P.D.2: Te puede interesar mucho leer esta presentacion:

http://www.slideshare.net/ScottWlasc...s-buildstufflt

Tambien aqui se muestra que los patrones de diseño en OO son basicamente deficiencias de los lenguajes (en su implementacion de la OO):

http://www.norvig.com/design-pattern...n-patterns.pdf
__________________
El malabarista.

Última edición por mamcx fecha: 10-12-2014 a las 18:36:42.
Responder Con Cita
  #4  
Antiguo 10-12-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola Mario, muchas gracias por tomarte el tiempo para responder e iniciar la retroalimentación.

No había visto esa lista de recomendaciones de Jeff Atwood, pero le encuentro mucho valor. En general, y desde mi opinión, creo que son consideraciones que debemos tener presentes quienes nos dedicamos a diseñar y escribir código, y en mayor medida los programadores bibliotecarios.

La duda con la definición de Wikipedia es por lo laxo de que no debería. El artículo en inglés es actualmente escueto y el de la versión en español es prácticamente una calca del primero. Varios artículos sobre UML asientan lo anterior, eso le da un poco más de peso. Suponiendo que demos por asentada la restricción, ¿cómo podríamos llamar a las clases que no tienen subclases (descendientes) pero que sí pueden en determinado momento llegar a tenerlas? Es decir, cuando no existe tal prohibición, ¿end class?

Como habrás visto, una de las cosas que cuido mucho son los nombres que le doy a los elementos de programa, y básicamente debo decidir si será o no adecuado llamarle a mi clase LeafClassList considerando que las clases contenidas no necesariamente estarán selladas para derivación. ¿Será mejor EndClassList? Esa es mi principal duda ahora.

De cualquier forma, esto se mantiene abierto a todo tipo de sugerencias constructivas.

Saludos.
Responder Con Cita
  #5  
Antiguo 10-12-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Bueno, el punto es combatir la suposición que la solución a un problema es "hacer mas clases". Es mejor hacer menos que mas! = hacer lo justo.



Cita:
Empezado por Al González Ver Mensaje
debo decidir si será o no adecuado llamarle a mi clase LeafClassList considerando que las clases contenidas no necesariamente estarán selladas para derivación. ¿Será mejor EndClassList? Esa es mi principal duda ahora.
Sigo sin entender para que haces eso, pero te digo que ha pesar de saber un monton de Technobabble yo no sabria que rayos es un LeafClass al solo verlo.

Asi que diria que seria mejor que la funcion/clase se llame : XXXSinSubclases
__________________
El malabarista.
Responder Con Cita
  #6  
Antiguo 10-12-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Gracias, compañero. Estoy de acuerdo en que hay que hacer lo justo, y a veces lo justo es crear una clase. El asunto es que el término leaf class es algo que ya se usa bastante, el problema es el acotamiento mencionado en las definiciones encontradas.

Por otro lado, imagina que vas a crear esta clase. ¿Qué nombre le darías en inglés?

Explicar el origen de esta necesidad ameritaría abrir otro hilo, y quizá lo termine haciendo. Pero creo que un planteamiento en los foros es válido mientras esté mínimamente contextualizado (y creo que este lo está). Acá tengo la necesidad de conocer las clases "finales"/"hoja" de cierta jerarquía (que se encuentra en otra lista sin un orden definido), y preveo que esta necesidad puede darse con otro caso después, donde el origen no sea necesariamente otra lista (sin caer en la generalidad especulativa ). El proceso es fácil y ya lo tengo implementado, pero me inclino a pensar que agregar de forma selectiva a una lista de clases se termina convirtiendo en un objeto lista de clases selectiva, donde dicha selectividad esté definida en la propia clase del objeto.
Responder Con Cita
  #7  
Antiguo 10-12-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Agrego: En este par de artículos no se advierte sobre la supuesta prohibición de que una clase hoja "no debe" o "no puede" tener subclases.
https://docs.oracle.com/cd/B14099_19...3.htm#i1142056
http://eclipse.org/eclipselink/docum...1.htm#CHEEDJEH

Yo creo que es lógico decir que una clase hoja es sencillamente la que no tiene clases hijas (aunque normalmente sí tiene padre), pero que nada impide que esa hoja se convierta luego en rama si llega a definírsele una clase derivada.

Por otra parte, en la POO moderna se ha venido usando la palabra sellada (sealed) para indicar el impedimento de derivación. Por lo tanto, creo que podemos ir acuñando ya una distinción clara entre lo que es clase hoja: que no tiene subclases, y una clase sellada: que no puede tener subclases. Vaya, en términos de reproducción, que no es lo mismo inmadurez que esterilidad.

Última edición por Al González fecha: 11-12-2014 a las 00:07:53.
Responder Con Cita
  #8  
Antiguo 11-12-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por Al González Ver Mensaje
Agrego: En este par de artículos no se advierte sobre la supuesta prohibición de que una clase hoja "no debe" o "no puede" tener subclases.
No es una prohibición, es solo una recomendación. Nota ademas que en https://en.wikipedia.org/wiki/Leaf_c...er_programming) se marca el articulo como "Sin referencias ni fuentes" y como un "Stub = Incompleto". De solo mirarlo es claro que no es una fuente muy autoritaria sobre el tema.

La recomendación no tiene contexto, pero se deduce de la idea de que es preferible "composición sobre herencia", "plano sobre anidado" y simple y llano sentido común ("es mejor menos que mas!"), junto a "explicito sobre implicito". Si una clase no tiene subclases, porque no dejar eso claro? Aunque algunos lo usan como una tecnica de optimizaron, yo diria que es mas un asunto de hacer claro la intención: Porfa no hereden de esto, este es el final de esta rama del árbol.

Un sistema mejor estructurado (y si el lenguaje ayuda) se desliga de la idea de la OO "tradicional" y combina programacion por componentes , modulos, uso de POCO, funciones y estructuras/tuplas/arrays/listas/records o similar. La idea es que los OO son mas flexibles si se usan al estilo como el creador de smaltalk los visiono y que modernamente esta implementado el modelo de Actor.

Que es otra forma muy sofisticada de decir que es buena idea aplanar el arbol de herencia, pensar bien como se combinan las clases y usar funciones/datos (y tipos, si el lenguaje lo da) si es posible para reducir la necesidad de crear muchas clases.

Cita:
Empezado por Al González Ver Mensaje
Por otra parte, en la POO moderna se ha venido usando la palabra sellada (sealed) para indicar el impedimento de derivación. Por lo tanto, creo que podemos ir acuñando ya una distinción clara entre lo que es clase hoja: que no tiene subclases, y una clase sellada: que no puede tener subclases. Vaya, en términos de reproducción, que no es lo mismo inmadurez que esterilidad.
Volviendo a "como nombro esto?"

Veo al buscar que es claro que un Leaf Class es una clase sin hijos. Lo de que "no deberia" es una recomendación de diseño, pero no altera que igual esta no tiene hijos. Si el codigo solo lo ve tu libreria da igual, pero si esto lo ve un programador X, creo que es mas claro decir "NoChilds" que "LeafClass". Nunca hay que dudar que la mayoria no esta empapado de la terminologia tecnica de todo esto.

No se como se llaman las otras clases (la de si tiene hijos y no se que mas) como para ver que "estilo" o tema tienes al nombrar las cosas, para mantener la simetria.

Puede ser ListLeafClasses o ListNoChildClasses...

P.D: Por otro lado, si la idea es tener una lista de clases, no veo porque hay que crear una clase que diga "esto es una lista de clases sin hijos". Me parece mas simple tener 1 funcion que me devuelva una Lista/Array y ya.
__________________
El malabarista.

Última edición por mamcx fecha: 11-12-2014 a las 04:10:22.
Responder Con Cita
  #9  
Antiguo 11-12-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Gracias, Mario.

Está claro todo lo que dices, si bien tengo algunas reservas. Pero qué bueno que vamos aclarando lo de la famosa prohibición: tienes razón, debemos tomarla más bien como una mera recomendación o idea de quienes escribieron eso. Esto me gusta porque se va asentando la diferencia entre clase hoja y clase sellada.

Mis clases y funciones (intento que esto forme parte de GH Freebrary), usan nombres cortos pero formales, empleando términos bien definidos o acuñados. Si bien tengo una larga lista de abreviaciones y no me gustan demasiado los artículos, las preposiciones y las negaciones en los identificadores, he de decir que trato de cuidar el orden, género, tiempo, número y persona de las palabras, acorde a la lengua de Mark Twain. El "ListLeafClasses" que sugieres sería más bien LeafClassList, contracción de leaf class list, que en castellano sería lista de clases hoja.

Volviendo a la justificación de crear la nueva clase. Primero diría que me resulta sumamente interesante crear una clase lista de clases "genérica" —con parámetro de tipo— derivada de la nativa TList genérica, la cual admita sólo clases de una rama en particular (los genéricos en Delphi lo simplifican mucho). Creo que sería útil en muchos casos, además de contar con algunos métodos auxiliares para el tratamiento específico de items clase.

Ahora, en esa misma clase lista podría incluir la funcionalidad de que sólo admita clases hojas. Pero estarás de acuerdo en que, si así fuera, tal característica tendría que ser opcional, y la clase estar preparada para trabajar (e incluso ajustar el contenido actual) según esa opción esté activa o no. Lo anterior pega directo en el punto que señalas de no hacer complejo lo que puede ser simple. Así que en lugar de agregar complejidad a una clase lista, agregándole esta funcionalidad extra opcional, mejor le derivo una subclase donde la funcionalidad quede circunscrita, llana, simple y con menos requerimientos de control. Cierto, no parece que vaya a haber muchos casos de uso, pero al menos yo ya tengo uno, y, como se trata de una biblioteca pública, puede que a alguien más le sirva luego también.

OK, queda la opción de ponerlo como una función suelta. Eso tendría la ventaja de poder operar con varios tipos de listas, pero creo que tendría yo que agregar código y validaciones adicionales para considerar particularidades de esas otras listas (más complejidad). Consideraciones que no tendría que tener con una lista cuyo comportamiento y datos estén perfectamente encapsulados (además hoy en día es trivial copiar el contenido de una lista a otra). Un argumento más a favor es que el método virtual Notify queda perfecto para hacer las revisiones necesarias, cada vez que se agregue una nueva clase a la lista.

Por los anteriores razonamientos es que le encuentro sentido a la lista especializada. Parece poca y rara cosa, pero queda bien en forma de clase de propósito específico.

Salvo que algo más me convenza de lo contrario...
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
La "CASTA" politica retratada en sólo 30 segundos Casimiro Notevi La Taberna 13 08-09-2012 04:50:55
Necesito llamar a métodos de clases "hija" desde su clase "padre" Flecha OOP 17 20-04-2007 00:03:53
Uso y abuso del elemento "lista de opciones" papulo HTML, Javascript y otros 9 12-01-2006 17:34:24
La lista completa de los "papers" de Borcon! mamcx Noticias 1 14-04-2005 13:01:59
Lista preliminar "Que hay de nuevo" en diamonback/D9 mamcx Noticias 5 17-09-2004 21:12:38


La franja horaria es GMT +2. Ahora son las 22:27:53.


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