Uso de mixins en Dart

Añadiendo funcionalidad.

Luis Herrera Gárnica
Recetario
Published in
4 min readOct 3, 2019

--

Glosario

  • Widget (GUI) — Elemento de control: Un widget (cachivache o pequeña cosa que no se sabe el nombre o no se recuerda), en el contexto de las interfaces gráficas de usuario, son elementos de interacción, por ejemplo el widget que nos muestra la hora en el teléfono, que además de presentarnos información, posee propiedades modificables e interacción con el usuario.

¿Qué es un mixin?

“Mixins, son una forma de usar el código de una clase, en múltiples jerarquías de clase”.

Al menos eso es lo que dice la definición en la documentación oficial de Dart. Este tipo de estrategias ya la hemos probado en “otros sabores”, donde los denotan como traits.

Quizás esta definición no ha sido suficiente, para comprender esta técnica perteneciente al paradigma de orientación a objetos. Entonces es muy recomendable que continuemos con la lectura.

Podría seguir agregando definiciones al más puro estilo de la documentación oficial; pero nada mejor para hacer set en nuestro cerebro desarrollador que un ejemplo.

Supongamos que tenemos dos clases:

Clase 1: MiWidget .

class MiWidget {
bool visible;
bool set Visible(boolean visible) // Muestra u oculta el widget ...
}

Clase 2: Coleccion .

class Coleccion {
porCadaElemento() // método que por cada elemento hará algo …
}

Un widget puede estar compuesto por varios otros pequeños widgets, es decir que podríamos personalizar un tipo de especial de widget, que pueda ser un widget y además una Coleccion.

Si queremos una solución rápida, lo que estaríamos tentados a realizar es crear una clase e implementar todas las funcionalidades que necesitemos.

class WidgetCompuesto {
bool visible // ...
bool set Visible(boolean visible) // ...
porCadaElemento(); // ...
}

Esto soluciona el problema, ya que MiWidget y Coleccion, tienen máximo dos métodos, pero; ¿Que pasaría si fueran muchos más?. No podríamos estar reescribiendo decenas de funcionalidades, ya que esto no sería productivo.

Sabemos que utilizando herencia, podemos reutilizar funcionalidades desde otra clase. Entonces veamos como implementaríamos la solución utilizando la herencia.

Heredamos de la clase MiWidget , esto nos ahorra tener que implementar los métodos de esta clase.

// acá ya viene la funcionalidad de MiWidget.
class WidgetCompuesto extends MiWidget {
porCadaElemento(); // ...
}

Pero aún debemos seguir implementando el método de la clase Coleccion , a menos que lo heredemos también.

// Disclaimer: Esta sección de código no funcionará.
class WidgetCompuesto extends Widget y además extends Coleccion{
// ...
}

Si hemos tenido la experiencia, sabremos que heredar de múltiples clases es una mala idea, ya que podemos heredar de una clase que hereda de la nuestra, causando ambigüedades, es por eso que en `Dart` no existe la herencia múltiple.

Si todos los desarrolladores de un proyecto, se organizan y utilizan la herencia múltiple con mucha responsabilidad, sería una herramienta muy útil, siguiendo algunas reglas, como no heredar de una clase que nos herede :). Lamentablemente en el mundo estocástico del desarrollo, es mejor ponernos algunas restricciones para evitar sorpresas desagradables, restricciones como no permitir la herencia múltiple.

¿Entonces?, ¿Como puedo tener mi colección de widgets, que tenga las funcionalidades de MiWidget además de Coleccion?

En la herencia, reutilizamos muchas de las funcionalidades de otra clase; pero debemos tomar atención a la definición o cuerpo de una clase, es decir, lo que está entre llaves.

{
porCadaElemento() // ...
}

Entonces, vemos que en la definición se encuentra la funcionalidad que ofrece una clase y a dicha funcionalidad, le llamaremos Mixin.

¿Por qué, a la funcionalidad de una clase le llamamos `mixin`?.

El propósito general del uso de los mixins, es poder añadir funcionalidad a una herencia, esto lo hacemos mezclando ”MIX IT IN” funcionalidades. Dicho de otra forma, una clase que usa mixinsusa herencia con algunos cachivaches extras.

la clase WidgetCompuesto que hereda de MyWidget con con el mixin de Coleccion es {
// ...
}

Ahora veamos la implementación correcta de lo que se expuso, veremos que agregando a una herencia la palabra reservada with es lo mismo que decir “Una Herencia Con…”.

class WidgetCompuesto extends MyWidget with Coleccion {
// Todas las funcionalidades incluidas
}

si queremos agregar muchos más mixins los listamos usando comas.

class WidgetCompuesto extends MyWidget with Coleccion, Colores, Sabores {
// Todas las funcionalidades incluidas
}

¿Como definimos un mixin?

Si hablamos de mixins, como vimos en los ejemplos, hablamos de clases, es decir que los mixinsson clases; pero unas clases especiales, que deben cumplir con algunas reglas:

  • No debe tener implementado el constructor. (Sí, poseerá el constructor automático; pero eso no nos importa, nosotros no lo implementaremos).
  • No debe heredar. (Sí, sabemos que una clase ya hereda de Object , pero ninguna otra herencia está permitida).

A partir de Dart 2.1.0 podemos utilizar la palabra reservada mixin para poder implementar un mixin en reemplazo de la palabra reservada class .

class Mezclalo {
// ...
}
// desde Dart 2.1.0mixin Mezclalo {
// ...
}

Quizás no está demás decir que la idea de un mixin no es crear una instancia de ella, si no que como hemos dicho, solamente agregar funcionalidad.

--

--