Debate: Interfaces o Clases Abstractas?

 El  miércoles pasado la pregunta se tiró en el thread "abstract vs interface" del Foro de Arquitectura en MSDN. Quiero reflejar acá mi posición sobre esta otra pregunta frecuente, tanto para el desarrollador como para el arquitecto (sobre todo al planear un framework que oculte la complejidad de ciertas API’s)

Normalmente en diseños que se pretenden desacoplados, desprejuiciados a un punto que a futuro puedan flexiblemente reconfigurarse, definir interfaces siempre suena a "adecuado" en la medida en que, al no definir el contenido de ningún método, los implementadores de la interfaz no quedan atados más que a la firma de dichos métodos

En el caso de una clase abstracta, al heredar algunos de los métodos, estamos atados a esa lógica. No es heredemos obligatoriamente todos los métodos ya que algunos métodos son abstractos y otros se pueden reescribir (claro: la idea es no reescribir absolutamente todo porque si no para qué heredamos, digo. No?)

Pero aún siendo "interfaces" la alternativa "políticamente correcta", persisten algunas consideraciones adicionales. Veamos:

Supongamos que tenemos una jerarquía de clases donde, algún miembro de la misma, cercano a la raíz (llamémoslo A), implementa cierta lógica "plantilla" que es heredada hacia abajo en la "dinastía". Esa lógica es súper útil para los herederos, que se ahorran porciones importantes de código en tanto que implementan su propias particularidades allí donde es necesario "despegarse"

Usar una clase abstracta acá es ideal para limitar parte de la implementación en la serie de clases descendientes

O sea que siendo que "interfaz" era la respuesta natural, acá aparece un caso natural donde una interfaz calza, pero agrega poco valor a lo que una clase abstracta puede hacer

El debate quizás no está necesariamente centrado en la jerarquía que queremos construir, y si debe ésta implementar una interfaz o heredar de una clase abstracta por la jerarquía en sí sino por la relación de esta jerarquía con el resto de las clases

Vamos a ver: supongamos que tenemos una clase B, ajena a la jerarquía, tal que B tiene un método B.MetodoB(…) que recibe una instancia de la jerarquía como argumento. La cuestión es si a B.MetodoB(…) le concierne la existencia de A o no

Opción 1: sí le concierne. Sí le concierne? Ok, entonces la firma del método debería ser algo de la pinta B.MetodoB(A a, …). Es decir, hacer mención directa a A y así limitar, dentro de la jerarquía en la que A está enmarcada, cuáles miembros están admitidos dentro del método

Opción 2: no, no le concierne la existencia de A ni de ninguna superclase de A en particular. Sólo le importa los métodos que están expuestos, pero en absoluto le interesa cómo hayan podido ser implementados ninguno de todos ellos. Bien, en ese caso, si no se definió interfaz aún -sea de A o alguna superclase más genérica de A-, estaría bien extraer alguna interfaz (idealmente, la q exponga sólo los miembros que desde el interior de B.MetodoB(…) van a ser necesarios. De esta manera, la firma queda B.MetodoB(IA a, …) y no nos acoplamos a ninguna implementación en particular que nos limite en el futuro

Al menos, ésa, mi regla del pulgar. No obstante, dependiendo de la etapa en el proyecto (si ya empecé a codificar, si aún estoy diseñando), puedo no estar claro aún si a B.MetodoB(…) le concierne la existencia de A o no. En esos casos, cuando no estoy seguro, me juego por la variante "políticamente correcta" y aplico interfaz. Pero cuando voy completando el diseño y antes de codificar ese método vuelvo sobre la cuestión, a ver si ya tengo más claro que a B no le concierne ni le debera concernir, o que lo tenga un cacho en cuenta no es tan malo. En este último caso es posible que cambie la firma para limitar el argumento a descendientes de A

Como cierre, un link a un artículo interesante que aborda el tema y propone hints según escenarios
http://msdn.microsoft.com/architecture/default.aspx?pull=/library/en-us/vbcon/html/vbconabstractclassesversusinterfaces.asp

Opiniones, comentarios? Escriban ché, no sean fiacas

Esta entrada fue publicada en Software Architecture. Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s