27 de septiembre de 2017

¿Por qué son importantes las interfaces?

Artículo original: Why interfaces are important?
http://www.eps-cs.com/VFPConversion/ConversionBlog.aspx?messageid=90b096b1-65db-48c5-b7d5-e6fe2dd54f9f
Autor: Markus Egger
Traducido por: Ana María Bisbé York


.NET soporta el concepto de las interfaces junto con las clases. Eso también lo hace VFP. Sin embargo, las interfaces VFP se requieren solamente en escenarios especiales, mientras que en .NET se utilizan todo el tiempo. Esto es algo que los desarrolladores VFP necesitan saber.

Pero, ¿porqué exactamente es así? Existe un grupo de razones debido las cuales las interfaces son increíblemente importantes y útiles. Este comentario representa sólo un escenario de ejemplo. Antes de verlo, necesitamos preguntarnos "¿qué es exactamente una interfaz?" Una interfaz es la definición de métodos y propiedades que tiene un objeto. En VFP, al crear un objeto, terminará teniendo todos los métodos y propiedades definidos (lo que también es cierto para .NET). Sin embargo, con una definición específica de interfaz, es posible configurar lo que se espera. Esto es muy importante para la reutilización del código y programación genérica.

Vamos a examinar un ejemplo sencillo de VFP: Digamos que deseo crear una barra de herramientas que tenga un botón Guardar. Siempre que se oprima el botón Guardar, va a invocar al método Save() en el formulario activo. Esto significa que yo espero que el formulario tenga un método Save(). En otras palabras: Espero que el formulario "implemente una interfaz que tenga el método Save()". En VFP, puedo llamar al método Save() de esta forma:

_Screen.ActiveForm.Save()

En VFP, no tenemos que especificar que el formulario activo implemente una interfaz específica. Si un formulario tiene un método Save(), se invocará. Esto hace las cosas muy sencillas; pero tiene también un lado malo: si el formulario activo no tiene método Save(), (puede ser que el desarrollador se olvidó de agregarlo), entonces, ocurrirá un error durante la ejecución. El compilador no tiene forma de verificar si  el objeto ActiveForm tiene o no un método Save()

La escritura fuertemente tipada de .NET soluciona este problema. En .NET, las referencias de objeto siempre son de un tipo específico (o clase...lo que es lo mismo que un tipo en .NET). Entonces, digamos que tenemos una referencia a un formulario activo llamada "ActiveForm". Por ahora, no nos preocupa como ocurre). Esta referencia debería no sólo ser tipada como un objeto (como en VFP), sino que debería ser del tipo "System.Windows.Forms.Form". En VB.NET, lo podríamos definir así:

Dim ActiveForm As System.Windows.Forms.Form
ActiveForm.Save() ' Falla!!!

Sin embargo, la clase "Form" no tiene el método Save(). Por tanto, el compilador no nos permitirá seguir adelante con la definición de una referencia como "Form" y una llamada al método Save(). En su lugar, deberíamos crear una clase form especial que va a tener un método Save():

Public Class SaveForm
  Inherits System.Windows.Forms.Form
  Public Function Save() As Boolean
    ' Guarda y devuelve el código correcto en las subclases
    Return False
  End Function
End Class

Ahora, podemos utilizar este formulario para definir el tipo de nuestra variable, y entonces seremos capaces de llamar al método Save(), ya que el compilador puede verificar que cada referencia de objeto puede guardarse en esta variable puede tener un método Save():

Dim ActiveForm As SaveForm
ActiveForm.Save() ' Funciona !!!

Hasta aquí vamos bien. El problema con esto es que la herencia es una técnica muy estática. Al igual que en VFP,  podemos subclasear sólo una clase desde la clase padre en .NET. Y en este escenario, significa que estamos ya al límite de nuestras opciones. Entonces, si tenemos alguna clase muy buena, que queramos utilizar como clase padre, no podemos, porque necesitaremos heredar siempre de "SaveForm". Una vez más en  VFP no es problema, porque podemos agregar el método Save() a nuestro formulario nuevo. Pero, nuevamente podríamos tener un problema de calidad no acorde con el desarrollo moderno. Y he aquí donde las interfaces juegan su papel.

Las interfaces nos permiten definir que determinados objetos tienen determinados métodos, sin desaprovechar la relación heredada. Así que en lugar de crear una clase, podemos definir una interfaz.

Public Interface ISaveForm
  Function Save() As Boolean
End Class

Ahora, podemos crear un formulario que subclase de otra clase formulario que deseemos, y además, siempre vamos a implementar la interfaz que acabamos de definir:

Public Class MyCoolForm
  Inherits SomeOtherForm
  Implements ISaveForm
  Public Function Save() As Boolean
    ' Guardar...
    Return True
  End Function
End Class

Cuando hablamos ahora de un objeto creado a partir de esta clase, podemos verlo en formas diferentes: Ahora lo vemos como una forma genérica (sin el método Save()), o podemos verlo como el tipo "MyCoolForm" (los que tienen un método Save(); pero nuestro botón de la barra de herramientas podría no saber que desde que no tiene el concepto de que "MyCoolForm" es), o como tipo "ISaveForm" (la que tiene un método Save() y la barra de herramientas puede ser utilizado). Entonces, podemos hacer esto:

Dim ActiveForm As ISaveForm ' Utiliza la Interfaz!!!
ActiveForm.Save() ' Funciona, no importa que sea un formulario subclaseado 

Algo agradable es que es muy fácil hacerlo (una vez que estemos confortables con este concepto), y es mucho más sencillo de controlar, una vez que el compilador puede verificar 100 %, y nuestro código va a trabajar en tiempo de ejecución.

No hay comentarios. :

Publicar un comentario

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.