![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
|||||||
| Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
|
Herramientas | Buscar en Tema | Desplegado |
|
#5
|
||||
|
||||
|
Hola, voy a hablar un poco en el aire porque no he revisado esto con detenimiento.
A mi me parece que hay una confusión de conceptos. Cita:
Al hacer esto (carga estática de paquetes), sigues teniendo la ventaja de la modularidad que proporcionan los paquetes: puedes hacer cambios en el paquete sin tener que recompilar ni redistribuir toda la aplicación porque el paquete como tal no está en el ejecutable, únicamente el enlace a él. Así que, antes de proseguir te conviene preguntarte si no te es suficiente esto. Posiblemente lo sea y ya no has de darle más vueltas al asunto. El uso de paquetes dinámicos- aquellos cargados dinámicamente con LoadPackage -tiene otra finalidad, una ventaja extra sobre los paquetes estáticos. Veamos un ejemplo. Tienes una aplicación que exporta datos a una base. Para ello tienes una rutina en tu aplicación principal que recibe un DataSet:
Supón ahora que la aplicación debe poder exportar los datos bien sea a MySql, Firebird o cualquier otro motor que el cliente desee en un futuro. Para ello debes proporcionar a la rutina de exportación el DataSet adecuado al motor (TZTable, TIBTable, etc...). Claro que lo más fácil sería:
pero esto condena tu aplicación a usar sólo esos dos motores. Para cualquier otro tendrás que agregar la condición correspondiente, recompilar y redistribuir toda la aplicación. Claro que puedes obtener el DataSet de un paquete; pero si el enlace es estático el cliente tendría que cambiar uno por otro cada vez y reiniciar la aplicación. Aquí es donde la carga dinámica adquiere sentido. El cliente proporciona, desde la aplicación, el nombre del paquete, lo cargas con LoadPackage y obtienes el DataSet que proporcione ese paquete. Si una necesidad similar es la que realmente requieres entonces sí tendrás que estudiar como obtener el objeto BD del cuál hablas. Regresando al principio; incluir la unidad en tu aplicación no sirve porque fuerzas un enlace estático. La solución Cita:
Para usar paquetes dinámicos- evitando el enlace estático, tu aplicación no puede contener ninguna referencia al paquete, ni en la lista de run time packages ni en las cláusulas uses. Si no hay ninguna referencia entonces ¿cómo puedes usar los objetos de los paquetes? Una posible solución es mediante el uso de clases abstractas. Defines una clase base que declare los métodos que requiera tu aplicación pero que no los implemente:
Esta clase la colocas o bien directamente en tu aplicación o bien en un paquete enlazado estáticamente. Con esto tu aplicación compila sin problemas y al ejecutable sólo le estás agregando, por así decirlo, la definición de los métodos. La implementación real de la clase (una clase descendiente) la colocarías en un paquete que, éste sí, cargarás dinámicamente:
Como ves, el paquete también enlaza estáticamente la clase base. Pero esto no es una carga ya ésta clase sólo define pero no implementa. Nota que la clase descendiente TDBZeos ni siquiera tiene que estar en la sección interface. En tu aplicación principal cargas el paquete con LoadPackage tal como lo has hecho y obtienes la dirección de la función CrearObjetoDB que exporta el paquete:
Como la aplicación sí usa la unidad DB_Base que define la clase base, el compilador no protesta ni en la declaración de la variable BD ni en la llamada al método HazAlgo. Pero el polimorfismo hace que el objeto real sea de tipo TDBZeos. En cualquier momento puedes programar otro paquete para otro motor de datos y tu aplicación estará lista para usarlo tan sólo especificando el nombre del paquete. Nota además, que ni siquiera se requiere el uso de RegisterClass ni GetClass con lo cual no estás restringido a usar descendientes de TPersistent. Espero no estar equivocado en los conceptos y que esto te aclare las cosas. // Saludos |
|
|
|