The factory method

The factory method

The Factory Method es un patron de diseño creacional, este sugiere usar metodos factory para la creacion de objetos sin especificar la clase exacta del objeto a crear. Esto puede ser implementado con una interfaz que puede ser implementada por varias clases. Puntos a tomar en cuenta:

Existen 3 maneras de implementar este patron The factory idiom, The static factory method y The concrete factory method

The factory idiom

Esta implementacion es la mas usada por muchos desarrolladores y consiste en delegar la creacion de objetos a una clases en particular, comunmente esta clase tendra un metodo que recibira algun tipo de valor que permitira saber que tipo de objeto retornar.

Imaginemos que tienes un restaurante de hamburguesas y que estas son las opciones de tu menu:

  • Hamburgesa sencilla
  • Hamburgesa doble
  • Hamburgesa angus
  • Hamburgesa vegana

Entonces tu codigo podria verse algo asi:

class Burger()

class RegularBurger(): Burger()
class DoubleBurger(): Burger()
class AngusBurger(): Burger()
class VeggieBurger(): Burger()

class Restaurant {

    fun prepareBurger(type: String): Burger {
        return if ("regular") {
            RegularBurger()
        } else if ("double") {
            DoubleBurger()
        } else if ("angus") {
            AngusBurger()
        } else if ("veggy") {
            VeggieBurger()
        }
    }

}

siguiendo con uno de las ventajas The factory method, podriamos delegar la creacion de las burgers a una clase que su unica obligacion sea la creacion de nuevas burgers, aqui es donde crearemos una clase que se llame FactoryBurger y que por medio de un metodo llamado createBurger devolvera una hamburguesa a quien lo solicite, entonces nuestro codigo se veria algo asi.

class FactoryBurger {
    fun createBurger(type: String): Burger {
        return when (type) {
            "regular" -> {
                RegularBurger()
            }

            "double" -> {
                DoubleBurger()
            }

            "angus" -> {
                AngusBurger()
            }

            "veggie" -> {
                VeggieBurger()
            }

            else -> throw Exception("burger not supported")
        }
    }
}

como puedes ver hemos usado when en lugar de if para hacer el codigo mas legible, sin embargo la responsabilidad sigue siendo la misma, de acuerdo al tipo de hamburgesa que nos soliciten, procederemos a retornar una instancia de la misma. De esta manera nuestro restaurante quedaria asi:

class Restaurant(private val factoryBurger: FactoryBurger) {

    fun prepareBurger(type: String): Burger {
        val burger = factoryBurger.createBurger(type)
        return burger
    }

}