paint-brush
Descubre el patrón de aliasby@raffaeleflorio
1,347
1,347

Descubre el patrón de alias

El patrón Alias se ocupa de dos problemas. El primero es extender la forma en que una clase final construye sus objetos. El segundo es tener muchos constructores con los mismos parámetros pero diferente semántica. Mientras lo hace, promueve la composición de objetos sobre la herencia. De hecho, no requiere subclases ni cambiar el código de la clase afectada. En cierta medida, puede verse como una forma de decorar objetos de construcción.

Company Mentioned

Mention Thumbnail
featured image - Descubre el patrón de alias
Raffaele Florio HackerNoon profile picture


Mientras escribo código OOP aplico algunas prácticas de Elegant Objects.


Una de ellas es que las clases deben ser definitivas. Esto quiere decir que no pueden extenderse por herencia sino sólo por composición.


La ventaja es la simplicidad. Quiero decir que, de esta manera, cada objeto se ve como un bloque cohesivo. Lo que interesa a sus clientes es su comportamiento expuesto. Nada mas. En cambio, a través de la extensión, un cliente puede romperlo.


Por ejemplo, un objeto puede interrelacionar dos de sus métodos. Entonces, si podemos reemplazar a través de la extensión de uno de ellos, podemos romper el otro. Por esta razón, para estar seguros, debemos verificar su implementación. De esta forma aumentamos el acoplamiento entre el extendido y la extensión.


En otras palabras, las clases finales refuerzan la idea de que solo debemos preocuparnos por el comportamiento expuesto. Y no de implementación. No obstante, requiere un cambio de cómo razonamos sobre ellos. El patrón Alias simplifica un aspecto de este cambio.

Intención

El patrón Alias permite extender la forma en que una clase puede construir sus objetos sin subclasificarlos o modificarlos.

Motivación

Supongamos una clase final que crea sus objetos usando algunos parámetros obligatorios. ¿Cómo podemos agregar otra forma de crear sus objetos? Por ejemplo, ¿cómo podemos agregar un constructor que use un valor predeterminado para uno o más de sus parámetros faltantes?


Un enfoque podría ser agregar otro constructor a la clase. Pero esto podría salirse de control. Además, podría no ser posible. Por ejemplo, la clase final antes mencionada podría estar en una biblioteca externa.


Otro inconveniente de este enfoque es que podemos contaminar la clase final. Por ejemplo, podemos tener una clase final que construya sus objetos dado un JSON. Pero después de un tiempo necesitamos agregar también XML. Como puede imaginar, agregar el código para mapear XML a JSON contaminará inevitablemente esa clase.


Sin embargo, el patrón Alias no se limita a las clases finales. Por ejemplo, no podemos tener dos constructores con los mismos parámetros pero diferente semántica.


Para resolver este problema, podemos agregar métodos de fábrica estáticos al código de la clase. Pero los mismos inconvenientes antes mencionados afectan a este enfoque. Es decir: esto se sale de control; esto no podría ser siempre posible; esto contaminará la clase.


Un mejor enfoque para ambos problemas es crear otra clase con el comportamiento de constructor deseado. Esta clase encapsula su propia lógica de construcción. Y delegará todo a la otra clase, incluida la creación real. Este es el patrón Alias.

Aplicabilidad

Utilice el patrón Alias cuando:


  • Debe agregar o modificar un constructor de una clase final;


  • Desea agregar o modificar un constructor de una clase sin modificarlo ni subclasificarlo;


  • Necesita dos o más constructores de una clase con los mismos parámetros sin modificarlos ni subclasificarlos.

Estructura

La estructura es sencilla. Necesitamos al menos dos clases que implementen la misma interfaz: un Alias y un Aliased.


Participantes


  • AnInterface
    • declara una interfaz.


  • Aliased
    • implementa AnInterface ;

    • expone uno o más constructores.


  • Alias
    • implementa AnInterface ;
    • expone uno o más constructores;
    • mantiene una referencia a un objeto con Aliased ;
    • delega todo al objeto Aliased al que se hace referencia.

Colaboración

  • Alias construye, según sus propias reglas, un objeto Aliased y mantiene una referencia del mismo. Luego delega todo al alias.


Consecuencias


El Patrón Alias tiene las siguientes consecuencias:


  • Permite agregar o modificar constructores fácilmente;
  • Promueve la composición sobre la herencia;
  • Aumenta el número de clases;
  • Reduce la duplicación de código cuando se usa para reemplazar una creación recurrente;
  • Las clases de alias duplican el código de delegación. Si esto es un problema, podría abordarse con una clase Alias abstracta básica.

Implementación

Para implementar el patrón Alias necesitas:


  1. para definir una interfaz;

  2. para implementar la interfaz previamente definida con una clase. Este será el alias;

  3. para implementar la interfaz previamente definida con una clase de alias, y necesita:

    1. para definir un constructor que construya un objeto con alias de acuerdo con algunas necesidades;
    2. una variable de instancia privada que hace referencia al objeto con alias construido previamente;
    3. to delega todo al objeto con alias.

Código de muestra

El siguiente código Java-ish expresa el patrón Alias. En este código, el alias inyecta un valor predeterminado para un parámetro obligatorio:


 interface AnInterface { void aMethod(); Something anotherMethod(); } final class Aliased implements AnInterface { private final A a; private final B b; Aliased(final A a, final B b) { this.a = a; this.b = b; } void aMethod() { // implementation } Something anotherMethod() { // implementation } } final class Alias implements AnInterface { private final Aliased aliased; Alias(final A a) { this( new Aliased( a, new InstanceOfB(...) ) ); } private Alias(final Aliased aliased) { this.aliased = aliased; } void aMethod() { this.aliased.aMethod(); } Something anotherMethod() { return this.aliased.anotherMethod(); } }


Patrones relacionados

Hasta cierto punto, el patrón Alias también podría verse como una forma de decorar la construcción de los objetos. Esta visión es especialmente cierta si vemos una clase como un objeto cuya responsabilidad es crear objetos.