Patrones de diseño en Android - Builder

Los patrones de diseño son soluciones reutilizables para los problemas de software más comunes. Pueden acelerar el proceso de desarrollo al proporcionar una forma comprobada de resolver problemas frecuentes.

En esta serie de artículos, me gustaría presentar los patrones de diseño más comunes con ejemplos de implementaciones de Android en la práctica.

Introducción

Los patrones de diseño se pueden dividir en tres secciones:

  • Creational Design Patterns ofrece soluciones para crear clases, objetos (Singleton, Factory, Builder, etc.)
  • Los patrones de diseño estructural tratan sobre la disposición de clases y objetos (por ejemplo, compuesto, fachada, adaptador)
  • Los patrones de diseño de comportamiento nos dan formas de comunicarnos entre objetos y clases (comando, observador, estrategia, etc.)

Constructor

El patrón de construcción simplifica la creación de objetos de una manera muy limpia y legible. Es muy útil cuando tenemos algunas clases de modelos con muchos parámetros. Podemos hacer que algunos de ellos sean opcionales o obligatorios, y no obligamos al usuario a usar un orden específico (como en el constructor). Al usar el patrón Builder resultamos con la elegante cadena de los métodos. El uso más común es en la clase AlertDialog.Builder ():

nuevo AlertDialog.Builder (este)
        .setTitle ("Patrones de diseño")
        .setMessage ("El generador es increíble")
        .crear();

¿Cómo podemos crear la clase Builder para nuestro propio uso?

Constructor en la práctica

Supongamos que tenemos alguna clase de modelo para el usuario:

Usuario de clase pública {
    Nombre de cadena privada;
    Cadena privada apellido;
    int int privado;
}

Y en lugar de crear objetos de esta clase usando constructores, queremos crearlos usando el patrón Builder de esta manera:

nuevo User.Builder ()
        .setFirstName ("Leonardo")
        .setLastName ("da Vinci")
        .setAge (67)
        .crear();

¿Cómo podemos hacer eso? En primer lugar, necesitamos crear una clase de generador dentro de la clase de usuario que tendrá los métodos para construir nuestro objeto. La clave para tener métodos de encadenamiento es que los métodos de construcción devuelven la clase de construcción. Mira el ejemplo:

generador de clase estática {
    Nombre de cadena privada;
    Cadena privada apellido;
    int int privado;

    public Builder setFirstName (cadena final firstName) {
        this.firstName = firstName;
        devuelve esto;
    }

    public Builder setLastName (cadena final lastName) {
        this.lastName = lastName;
        devuelve esto;
    }

    public Builder setAge (int int final age) {
        this.age = age;
        devuelve esto;
    }

    Usuario público create () {
        devolver nuevo usuario (este);
    }
}

Para cada parámetro tenemos un setter: la diferencia es que esos métodos devuelven el tipo Builder. Al final, tenemos un método que utiliza el constructor de la clase Usuario y devuelve el objeto Usuario: aquí está el lugar donde nuestro desastre se mantiene oculto.

Luego, necesitamos crear un constructor con todos los parámetros en la clase de modelo Usuario:

Usuario de clase pública {
    Nombre de cadena privada;
    Cadena privada apellido;
    int int privado;

    Usuario privado (final Builder Builder) {
        firstName = builder.firstName;
        lastName = builder.lastName;
        age = builder.age;
    }
}

Lo importante aquí es que el constructor Usuario es privado, por lo que no se puede acceder desde la otra clase y debemos usar el Generador para crear un nuevo objeto.

Por supuesto, podemos hacer algunos de los parámetros requeridos (ya que por ahora todos son opcionales) modificando nuestro método create () y lanzando algunas excepciones, por ejemplo:

Usuario público create () {
    Usuario usuario = nuevo usuario (nombre, apellido, edad);
    if (user.firstName.isEmpty ()) {
        lanzar nueva IllegalStateException (
           "¡El nombre no puede estar vacío!");
    }
    usuario de retorno;
}

Eso es. ¡De esta forma creamos nuestra clase User.Builder ()!

Constructor - protip

Si fue lo suficientemente paciente como para leer toda la publicación del blog, tengo un consejo para usted con respecto al patrón de Builder: ¡puede generar toda la clase de Builder usando IntelliJ!

Todo lo que necesita hacer es colocar el cursor en el constructor de su clase y elegir Refactor -> Reemplazar constructor con constructor en el menú contextual. La clase de generador con todos los métodos se generará automáticamente, lista para usar.

Puede leer más aquí: IntelliJ: Reemplazar constructor con constructor

Conclusión

El patrón de construcción es un gran enfoque, no solo para las clases de modelo, sino para cada objeto que tiene más de tres o cuatro parámetros. Con un poco de trabajo adicional, podemos aumentar la legibilidad de nuestro código. Los patrones de diseño se reconocen como la mejor práctica, por lo que es una gran ventaja si conoce algunos de ellos y Builder es una buena opción para comenzar.

¡Mantente sintonizado para más!