Foro NoterosChile
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

Programación Orientada a Objetos II

Ir abajo

Programación Orientada a Objetos II Empty Programación Orientada a Objetos II

Mensaje por JoseRios Mar Feb 26, 2008 1:12 pm

La teoría de la herencia

Antes de tratar en las complejidades de la herencia, echemos un vistazo breve a la teoría primero. En los libros de Programación Orientada a Objeto, la herencia es a menudo llamada una relación "es un". Un coche es un tipo de vehículo, un Porsche es un tipo de coche, y así. Plátanos, manzanas, y fresas son todas tipos de frutas. Aqui tenemos otro diagrama tradicional de Orientación a Objetos.
[img]http://juanfco.ruiz.name/A55AAB/lbh.nsf/resources/art003_01/$FILE/notart_0302.jpg[img]

Las subclases son clases que heredan de otra clase. Las subclases se conocen tambien como clases derivadas o clases hijas. Una subclase puede heredar de otra subclase. En el diagrama de arriba, el todoterreno y la furgoneta son ambas subclases que heredan de otra subclase. Las clases base son simplemente esas clases que no heredan de otras clases. ListITem, BetterList, y EnhancedUIDoc son todas clases base. No importa que BetterList y EnhancedUIDoc hagan uso de la composición y así contengan otras clases. Nunca heredan de la otra clase y eso las hace clases base. En el diagrama, vehículo es la unica clase base.


Crear clases utilizando la herencia

Podríamos simplemente poner solo las capacidades que queremos en cada formulario dentro de EnhancedUIDoc y dejarlas ahi. Nosotros tendremos significantes beneficios aun. Podemos hacerlo incluso mejor. Haciendo uso de la herencia, podremos crear rápidamente clases nuevas que pueden mejorar, cambiar o sobreescribir el funcionamiento de las clases existentes.

Una forma de hacer esto es usa EnhancedUIDoc como una clase base abstracta. Las clases abstractas no existen al ser creadas ( o, en el lenguaje formal de la Orientación a Objetos, "instanciadas" ). Sólo existen para ser utilizadas como una clase base desde la cual otras clases heredarán. No hay una forma fácil de forzar a una clase a ser abstracta en LotusScript ( esto es, no podemos prevenir que alguien la use directamente ), pero en realidad no necesitamos forzarla. Podríamos usar EnhancedUIDoc como el objeto creado cuando un formulario se crea, y eso funcionaría bien; pero podemos elegir tratarla como abstracta, y creer que hay una ventaja en eso. Encuentro que usando una clase base abstracta mas una subclase específica para cada formulario que necesita heredar una funcionalidad común es un esquema más flexible. Haciendo esto, cualquier código personalizado para un formulario es aislado en una subclase asociada con ese formulario. Similarmente, el código necesario para todos los formularios se aisla en la clase base.

Ahora tenemos una clase que extiende a NotesUIDocument. ¿Cómo y dónde creamos esta clase de forma que apunte al documento UI correcto? Recuerda, esto hay que hacerlo antes que varios eventos de inicio ocurran de forma que podamos saltarnos estos eventos cuando sucedan. Haremos esto en el evento Queryopen del formulario. No es posible hacer esto más pronto ya que la propiedad NotesUIWorkspace.CurrentDocument no devolverá un valor utilizable antes de este evento.

Código:
Sub Queryopen( Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)
  Set g_CurrUIDoc = New EnhancedUIDoc(Source)
End Sub

La variable global g_CurrUIDoc se utiliza para mantener la pista del objeto perteneciente a la ventana del documento actualmente visible.

Aqui existen dos clases que heredan de EnhancedUIDoc. En la primera linea, nosotros declaramos que la clase SubClassUIDoc hereda de EnhancedUIDoc utilizando la palabra clave As. La clase que está indicada despues del As es la clase de la cual la nueva clase va heredar. Ambas son subclases de EnhancedUIDoc desde que ambas heredan de ella. Una de ellas, SubclassUIDoc, no cambia nada aunque contiene una sentencia print para ayudar a ilustrar el orden en el cual son llamados los métodos. La otra, NewEventUIDoc, contiene código que dará capacidades que no se encuentran en EnhancedUIDoc. Los documentos creados usando NewEventUIDoc aparecerán mostrando reglas y barras de scroll horizontales. Estas nuevas capacidades se añaden en el método ProcessSpecialPostopen. NewEventUIDoc tambien deshabilita las capacidades de seguir la pista a los campos que pusimos en su clase base, NotesUIDocument. Se hace esto mediante la sentencia "on event ... remove".

Código:
Class SubclassUIdoc As EnhancedUIDoc
  Sub new (uid As NotesUIDocument)
      Print ( "SubclassUIDoc - sub new")
  End Sub
End Class
Class NewEventUIDoc As EnhancedUIDoc
  Sub new (uid As NotesUIDocument)
      Print ( " NewEventUIDoc - sub new")
      On Event QuerySave From m_uidoc Remove
      On Event QuerySave From m_uidoc Call ProcessSpecialQuerySave
      On Event Postopen From m_uidoc Call ProcessSpecialPostopen
  End Sub
  Sub ProcessSpecialQuerySave ( Source As Notesuidocument, Continue As Variant )
      Print ("NewEventUIDoc - ProcessSpecialQuerySave")
  End Sub
  Sub ProcessSpecialPostOpen( Source As NotesUIDocument )
      m_uidoc.HorzScrollBar = True
      m_uidoc.Ruler = True
  End Sub
End Class

Fijate en la sentencia "On Event QuerySave From m_uidoc Remove". Sin esa línea, veríamos una llamada a ProcessSpecialQuerySave y ProcessQuerySave antes de salvar un objeto de la clase NewEventUIDoc. La documentación de LotusScript nos dice que el orden al llamar múltiples subrutinas de eventos para un objeto no está definido. No hay forma de saber con certeza cual de ellos será llamado primero. Ten cuidado de escribir código que asuma que una subrutina de un particular evento será llamada antes que otra. En este ejemplo, hemos evitado el problema desactivando la subrutina original.

Ahora que hemos creado estas dos subclases, tenemos que considerar un nuevo efecto. ¿Qué ocurre con los constructores en la subclase y la clase base cuando se crea un objeto de la subclase? Cuando creamos un objeto de la subclase, hacer una llamada a la subrutina New de la subclase tambien causa una llamada a la subrutina New de la clase de la que se hereda. En otras palabras, la subrutina New de la clase base es llamada primero, seguida de la subrutina New de la subclase. Lo contrario ocurre cuando se llama a un destructor. Las llamadas son echas primero al destructor de la subclase y entonces al destructor de la clase base. Hay sentencias print en el código que muestran esto.

Los constructores y destructores son los únicos métodos de la clase que automáticamente llaman a métodos de las clases de las que heredan. Los constructores pueden tener argumentos. Si los tienen, hay dos situaciones posibles de subclases. Si los argumentos de la subclase coinciden con los argumentos de la clase padre exactamente, todo va bien. Si no coinciden, el constructor de la subclase debe declarar qué argumentos serán pasados al contructor del padre. Mira el tópico Propiedad y Método Sobreescritura de la Ayuda del Domino R5 Designer para una descripción más completa de cómo hacer esto. Los destructores no tienen argumentos.

Sobreescribiendo propiedades y métodos

Las subclases pueden sobreescribir las propiedades y metodos de sus clases padre. Esto puede ser realizado definiendo una propiedad o método en la subclase con el mismo nombre que tienen en la clase padre. Las listas de parámetros deben ser idénticas en ambos elementos. ¿Porqué querríamos hacer esto? Un ejemplo puede ser una clase base y una subclase en las que ambas tienen un metodo RestoreDefaultValues. Cada clase necesita esta capacidad, pero cada una tiene un conjunto diferente de valores por defecto a restaurar. ¿Qué pasa si una subclase necesita hacer algo que su clase base tambien puede hacer? Sabemos ya que duplicar el código es una mala idea. Un subclase puede llamar a cualquiera de los métodos o propiedades sobreescritos de cualquiera de las clases de las que hereda usando la notación punto-punto (..) . La notación punto-punto es válida sólo dentro de las clases. Mira la entrada de la Ayuda del Domino R5 Designer sobre la notación punto-punto para una descripción más completa de cómo hacer esto.

Los objetos y la gestión de la memoria

Aunque LotusScript maneja la mayoría de los eventos de gestión de memoria por nosotros, tendrás que poner más atención en ello cuando trates con objetos, especialmente si almacenas objetos en listas. ¿Y esto porqué? Cada objeto que tu creas toma una cierta cantidad de memoria. Si tu creas una gran cantidad de objetos sin poner cuidado de lo que haces con ellos, tu ordenador puede enlentecerse e incluso puede colgarse. Un objeto creado dentro del alcance de una función será liberado automáticamente cuando la función acabe, pero un objeto colocado en una lista no será liberado hasta que la lista en sí misma se libere. Esto puede no suceder hasta que la base de datos en cuestión se cierre, si existe cualquier variable global apuntando a la lista de objetos.

Dado que hay restricciones en el número de documentos que pueden abrirse a la vez y que hay usualmente menos de varios cientos de campos por documento, no tendremos este problema con EnhancedUIDoc. Por otro lado, una aplicación que trate de crear un objeto complejo para cada documento en una base de datos y guarde cada uno de esos objetos en una lista puede muy bien ir escasa de memoria cuando el número de documentos exceda la capacidad de la computadora de almacenar los objetos que los representan.

¿Cómo evitar este problema? Asegúrate de borrar los objetos cuando hayas acabado con ellos. Tambien, diseña tu código de forma que no necesites un número excesivo de objetos disponibles a la vez. La sentencia Erase puede ser utilizada para borrar todos los objetos de una lista; puede tambien ser utilizada para borrar solo un objeto de la lista.

Limitaciones

Si vas a empezar a usar objetos por tu cuenta, hay unos pocos consejos que deberías saber antes de empezar. Los objetos deben estar definidos en la sección de Declaraciones de un script, y existe un límite de 64K en la cantidad de código que puede ser colocada en una sección. Si creas montones de clases, puede que no entren todas en una sola librería de scripts. Si ves este mensaje "Operación actual abortada porque el buffer está lleno" cuando estas trabajando o salvando tu librería de scripts, has alcanzado el límite de 64K. Considera el partir una librería de script que se pasa en tamaño en múltiples librerías de scripts con las clases relacionadas agrupadas.

A veces, el trabajar con eventos puede ser complicado. No todos los objetos predefinidos de Notes están disponibles en todos los eventos. En particular, no serás capaz de acceder al objeto NotesUIDocument antes del evento QueryOpen del formulario. Además, el documento back-end de Notes para un documento que se está creando, NotesUIDocument.Document no está disponible hasta el evento PostOpen.

Tambien, ten en cuenta que LotusScript se compila diferente en la versión 4 que en la versión 5. En la versión 4, si intentas salvar un librería de scripts que define una clase A y una clase B donde la clase A contiene un objeto de la clase B y la clase A está definida antes de la clase B, obtendrás un mensaje de error "Clase o nombre de tipo no encontrado". El mismo código se salvará correctamente en la versión 5. Si estás desarrollando para ambas versiones de Notes, estate prevenido de esta situación.

Finalmente, una palabra de advertencia: No te arriesgues y pongas todo el código dentro de las clases solo para que seas capaz de alardear de la frase Orientado a Objetos. Recuerda que el que el código esté orientado a objetos no lo hace buen código. Es perfectamente posible escribir código malo orientado a objetos. En particular, puede ser dificil entender un codigo que usa más de tres o cuatro niveles de herencia. Haz uso de las clases cuando y donde tengan sentido. Como con cualquier código, los comentarios buenos y la documentación harán tu código orientado a objetos más fácil de usar y mantener.

Conclusión

Hemos examinado cinco clases de LotusScript en el rango de simple a más compleja. Fueron construidas usando dos técnicas principales : composición y herencia. Hemos visto cómo la composición puede ser utilizada para extender los objetos predefinidos de Notes, los cuales no se pueden extender por herencia. Usamos herencia para compartir un conjunto básico de

comportamientos entre formularios mientras se permitían mejoras específicas y excepciones. Tambien hemos visto como sustituir eventos y revisado el manejo de errores, gestión de memoria, y limitaciones de las clases en LotusScript.

Tomado en conjunto, hemos demostrado como las características orientadas a objeto de LotusScript pueden añadir nuevas capacidades a LotusScript y como las clases pueden ayudar a evitar código duplicado. Espero que los ejemplos dados aquí te inspiren para crear algunas clases útiles por ti mismo.

Recursos Adicionales
Ayuda del diseñador de Domino R5

La Ayuda del diseñador de Domino R5 tiene algunas entradas útiles sobre objetos. Si bien tienes que saber dónde buscar. Inténtalo en la subseccion "Tipos de datos definidos por el usuario y Clases" del tópico "Lenguaje LotusScript" como punto de inicio.

Tambien puedes encontrar de particular interés los siguientes tópicos del tópico "Sustitución de propiedades y métodos" :

  • "Extendiendo la subrutina New en clases derivadas"
  • "Llamando la subrutina New y la subrutina Delete"
  • "Accediendo a propiedades y metodos de la clase base"
  • "Usando referencias a objetos como argumentos y valores de retorno"
  • "Usando la sentencia Set con objetos de clases derivadas."


Libros

Probablemente los dos libros más conocidos que tratan sobre la programación orientada a objetos sean Object-Oriented Analysis and Design With Applications , de Grady Booch, Addison-Wesley, 1994, y Design Patterns : Elements of Reusable Object-Oriented Software , de Eric Gamma, Richard Helm, Ralph Johnson, y John Vlissides, Addison-Wesley, 1995. El libro Desing Patterns muestra las combinaciones de clases comunmente utilizadas.

Sitios web

Las plantillas son combinaciones de clases frecuentemente utilizadas. Aquí tienes dos sitios web que pueden ayudarte a aprender más sobre ellas. El sitio web Patterns FAQ incluye respuestas a preguntas frecuentes. La web Patterns Home Page incluye tutoriales.

Original: http://juanfco.ruiz.name/A55AAB/lbh.nsf/articles/HALL-6U9QKY
JoseRios
JoseRios

Cantidad de envíos : 39
Edad : 39
Localización : Santiago, Chile
Fecha de inscripción : 25/02/2008

http://noteroschile.wordpress.com

Volver arriba Ir abajo

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.