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);
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.