patron_I

Patrones de diseño en Android (I): Patrones de creación

Patrones de diseño en Android (I) : Patrones de creación
Patrones de diseño en Android (II): Patrones estructurales

El desarrollo de software no es una ciencia cierta. Siempre tenemos que realizar tareas diferentes, pero dentro de estas tareas, muchas veces nos encontramos con un mismo problema recurrente.

 

Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, así como la solución a ese problema, de tal modo que se pueda aplicar esta solución un millón de veces, sin hacer lo mismo dos veces.

 

Bajo esta premisa, realizaron los patrones de diseño. En el libro “Patrones de diseño” de Erich Gamma se dice que “…un patrón de diseño nomina, abstrae, e identifica los aspectos clave de una estructura de diseño común,lo que los hace útiles para crear un diseño orientado a objetos reutilizable..”

 

Los patrones de diseño en el ámbito del desarrollo software se dividen en tres categorías diferentes.

  • Patrones de creación, encargados de abstraer el proceso de creación de nuevas instancias de nuestra clase.
  • Patrones estructurales, que se ocupan de como combinar clases y objetos para formar estructuras mas grandes.
  • Patrones de comportamiento, los cuales no solo se encargan de describir patrones de clases y objetos, sino también la comunicación entre ambos.

En esta primera entrada nos vamos a centrar en los patrones de creación, en especial en los patrones “Builder”, “Singleton”, y “Factory Method”

Patrón Builder

Patrón utilizado para crear instancias de elementos complejas. Con este patrón se tiene un proceso de creación mas fácil e intuitivo para el desarrollador. Es un patrón muy utilizado dentro del desarrollo android, ya que permite crear nuevas instancias muy personalizadas. Un ejemplo muy claro es la clase “AlertDialog”, la cual se puede instanciar mediante este tipo de patrón.

/**
 * Entity that represents a "Car".
 *
 * @author asanchezyu@gmail.com
 * @version 1.0.
 * @since 8/4/16.
 */
public class Car {

    private final String plateNumber;
    private final String ownerDrivingLicenseId;
    private final String colour;
    private final String type;
    private final String year;

    private Car(Builder builder) {
        this.plateNumber = builder.plateNumber;
        this.ownerDrivingLicenseId = builder.ownerDrivingLicenseId;
        this.colour = builder.colour;
        this.type = builder.type;
        this.year = builder.year;
    }

    public String getColour() {
        return colour;
    }

    public String getOwnerDrivingLicenseId() {
        return ownerDrivingLicenseId;
    }

    public String getPlateNumber() {
        return plateNumber;
    }

    public String getType() {
        return type;
    }

    public String getYear() {
        return year;
    }

    /**
     * Builder class.
     */
    public static class Builder {

        private final String plateNumber;
        private final String ownerDrivingLicenseId;
        private String colour;
        private String type;
        private String year;

        public Builder(String plateNumber, String ownerDrivingLicenseId) {
            this.plateNumber = plateNumber;
            this.ownerDrivingLicenseId = ownerDrivingLicenseId;
        }

        public Builder setColour(String colour) {
            this.colour = colour;
            return this;
        }

        public Builder setType(String type) {
            this.type = type;
            return this;
        }

        public Builder setYear(String year) {
            this.year = year;
            return this;
        }

        public Car build() {
            return new Car(this);
        }
    }
}
Builder

Patrón Singleton

Este patrón nos permite tener una sola instancia de una clase en toda nuestra aplicación. Este patrón es muy útil cuando utilizamos managers de bases de datos, de peticiones REST, cola de tareas en background, ya que solo queremos que se instancie una sola vez. Si se trabaja sobre la instancia en diferentes hilos, debemos tener control sobre la concurrencia, tal y como se ve en el siguiente ejemplo.

/**
 * Database manager.
 *
 * @author asanchezyu@gmail.com.
 * @version 1.0.
 * @since 8/4/16.
 */
public class DbManager {

    private static volatile DbManager instance = null;

    private DbManager() {
        // No instances created from outside.
    }

    public static DbManager getInstance() {
        if (instance == null) {
            synchronized (DbManager.class) {
                if (instance == null) {
                    instance = new DbManager();
                }
            }
        }
        return instance;
    }

}
Singleton

 

Patrón Factory Method

Este patrón de creación nos permite desde una clase abstracta constructora crear instancias de otros objetos que a su vez, heredan o implementan un elemento en común . Este patrón es muy útil cuando desde nuestra aplicación, por ejemplo, tenemos varios entornos de desarrollo (desarrollo, pre-producción y producción), y cada uno de ellos tiene un endPoint diferente. Gracia a este patrón, el cambiar de entorno se simplifica en un cambio de variable.

Pongamos el anterior ejemplo en práctica:

Nuestra aplicación tendrá dos entornos (“environments”). Ambos entornos nos tendrán que devolver la url de nuestro blog. Para ello creamos una intefaz “Environment” y dos clases que la implementan, “DevEnvironment” y “ProductionEnvironment”.

/**
 * Interface that defines the methods of one environment.
 *
 * @author asanchezyu@gmail.com.
 * @version 1.0.
 * @since 8/4/16.
 */
public interface Environment {

    String getBlogUrl();

}
Environment
/**
 * Class that represents one type of enviroment: Development Environment.
 *
 * @author asanchezyu@gmail.com.
 * @version 1.0.
 * @since 8/4/16.
 */
public class DevEnvironment implements Environment {

    @Override
    public String getBlogUrl() {

        return "http://localhost:8080/myBlog";

    }
}
DevEnvironment
/**
 * Class that represents one type of enviroment: Production Environment.
 *
 * @author asanchezyu@gmail.com.
 * @version 1.0.
 * @since 8/4/16.
 */
public class ProductionEnvironment implements Environment {

    @Override
    public String getBlogUrl() {

        return "http://blog.asanchez-portfolio.es";

    }
}
ProductionEnvironment

Para crear instancias de estos elementos, crearemos una factoría abstracta “EnvironmentFactory” y que a su vez será implementada por la factoría de nuestra aplicación “ApplicationEnvironmentFactory”.

/**
 * Interface that defines needed methods for one environment factory.
 *
 * @author asanchezyu@gmail.com.
 * @version 1.0.
 * @since 8/4/16.
 */
public interface EnvironmentFactory {

    enum EnvironmentType {
        DEVELOPMENT,
        PRODUCTION
    }

    Environment getEnvironment(EnvironmentType environmentType);

}
EnvironmentFactory
/**
 * Class that represents one type of environment creator: Our application environment factory.
 *
 * @author asanchezyu@gmail.com.
 * @version 1.0.
 * @since 8/4/16.
 */
public class ApplicationEnvironmentFactory implements EnvironmentFactory {

    @Override
    public Environment getEnvironment(EnvironmentType environmentType) {
        Environment environment;

        switch (environmentType) {
            case DEVELOPMENT:
                environment = new DevEnvironment();
                break;
            case PRODUCTION:
                environment = new ProductionEnvironment();
                break;
            default:
                environment = new DevEnvironment();
                break;
        }

        return environment;
    }
}
ApplicationEnvironmentFactory

Una vez hecho esto, desde la clase que queramos utilizar la factoría, solo debemos realizar lo siguiente:

...

EnvironmentFactory environmentFactory = new ApplicationEnvironmentFactory();

Environment debugEnvironment = environmentFactory.getEnvironment(EnvironmentFactory.EnvironmentType.DEVELOPMENT);

Environment productionEnvironment = environmentFactory.getEnvironment(EnvironmentFactory.EnvironmentType.PRODUCTION);

System.out.println("Blog url from debug  " + debugEnvironment.getBlogUrl());

System.out.println("Blog url from production  " + productionEnvironment.getBlogUrl());

...
How to use

Puedes ver el código en github


Deja un comentario

cinco − 1 =