Categories: Patrones Creacionales

Factory Method

Share

Índice

El patrón de diseño Factory Method (Método Fábrica) sirve para abstraer el proceso de creación de un objeto. A raíz de una clase se crearían todos los objetos con las propiedades y funciones tanto del objeto padre como de los hijos. Forma parte de los patrones de diseño creacionales.

En este ejemplo vamos a suponer que tenemos un objeto User que podrá ser de dos tipos, Normal y Premium. En función del tipo de usuario tendrá un estado diferente y mostrará o no anuncios.

Kotlin

Diagrama de flujo:

interface User {
    val name: String
    val surname: String
    fun getFullName() = "$name $surname"
    fun status(): String
    fun showAds(): Boolean
}

Estos serían los dos tipos de usuarios con las diferentes implementaciones de las funciones.

class Normal(override val name: String, override val surname: String) : User {
    override fun status() = "Normal"
    override fun showAds() = true
}

class Premium(override val name: String, override val surname: String) : User {
    override fun status() = "Premium"
    override fun showAds() = false
}

Para facilitar la comprobación de los diferentes usuarios, utilizaremos un Enum llamado UserType:

enum class UserType { Normal, Premium }

Para obtener ahora un usuario utilizaríamos la fabrica UserFactory, la cual nos instanciará un objeto en función del tipo, del nombre y del apellido:

object UserFactory {
    fun getUser(userType: UserType, name: String, surname: String): User {
        return when (userType) {
            UserType.Normal -> Normal(name = name, surname = surname)
            UserType.Premium -> Premium(name = name, surname = surname)
        }
    }
}

Aquí puedes ver como utilizar la UserFactory y para ver el código al completo pulsa en el ‘+’ a la derecha.

fun main() {
//sampleStart
    val normal = UserFactory.getUser(UserType.Normal, "James", "Smith")
    with(normal) {
        println(getFullName())
        println(status())
        println("Show ads: ${showAds()}")
    }

    val premium = UserFactory.getUser(UserType.Premium, "Peter", "Brown")
    with(premium) {
        println(getFullName())
        println(status())
        println("Show ads: ${showAds()}")
    }
//sampleEnd
}

interface User {
    val name: String
    val surname: String
    fun getFullName() = "$name $surname"
    fun status(): String
    fun showAds(): Boolean
}

class Normal(override val name: String, override val surname: String) : User {
    override fun status() = "Normal"
    override fun showAds() = true
}

class Premium(override val name: String, override val surname: String) : User {
    override fun status() = "Premium"
    override fun showAds() = false
}

enum class UserType { Normal, Premium }

object UserFactory {
    fun getUser(userType: UserType, name: String, surname: String): User {
        return when (userType) {
            UserType.Normal -> Normal(name = name, surname = surname)
            UserType.Premium -> Premium(name = name, surname = surname)
        }
    }
}


Java

Clase Main:

public class Main {
    public static void main(String[] args) {
        User normal = UserFactory.getUser(UserType.Normal, "James", "Smith");
        System.out.println(normal.getFullName());
        System.out.println(normal.status());
        System.out.println(String.format("Show ads: %s", normal.showAds()));

        User premium = UserFactory.getUser(UserType.Premium, "Peter", "Brown");
        System.out.println(premium.getFullName());
        System.out.println(premium.status());
        System.out.println(String.format("Show ads: %s", premium.showAds()));
    }
}

La clase Factory UserFactory:

public class UserFactory {
    public static User getUser(UserType userType, String name, String surname) {
        switch (userType) {
            case Normal: return new Normal(name, surname);
            case Premium: return new Premium(name, surname);
            default: return new Normal(name, surname);
        }
    }
}

La interfaz User:

public interface User {
    String getFullName();
    String status();
    boolean showAds();
}

Enum Polygon:

public enum UserType {Normal, Premium}

Las clases Normal y Premium:

public class Normal implements User {

    private String name;
    private String surname;

    public Normal(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    @Override
    public String getFullName() {
        return String.format("%s %s", name, surname);
    }

    @Override
    public String status() {
        return "Normal";
    }

    @Override
    public boolean showAds() {
        return true;
    }
}

public class Premium implements User {

    private String name;
    private String surname;

    public Premium(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    @Override
    public String getFullName() {
        return String.format("%s %s", name, surname);
    }

    @Override
    public String status() {
        return "Premium";
    }

    @Override
    public boolean showAds() {
        return false;
    }
}


Como veis hay hacerlo en 6 archivos mientras que en Kotlin podríamos hacerlo en 1 (2 o 3 en un caso real). Eso sin contar la diferencia total de líneas.


Enlaces de interés:

Recent Posts

  • Curso Interactivo

Variables

En esta lección aprenderás a declarar variables y los tipos básicos.

5 años ago
  • Curso Interactivo

Introducción al Curso Interactivo

La mejor forma de aprender algo en esta vida es a base de practicar. Espero…

5 años ago
  • Coroutines

Iniciar una Corrutina

La principal forma de iniciar una corrutina en Kotlin es con el coroutine builder launch…

5 años ago
  • Coroutines

Coroutines

Las coroutines en Kotlin vienen a tratar de solucionar todos los problemas y dificultades que…

5 años ago
  • Funciones Estándar

Resumen Elección de Modismo

Con este esquema te puedes guiar a la hora de elegir el modismo o función…

5 años ago
  • Funciones Estándar

With

El último que queda por ver es with qué en inglés significa "con". Por lo…

5 años ago