Factory https://refactoring.guru/es/design-patterns/abstract-factory
Introducción
Cómo aprender Go avanzado: concurrencia, patrones de diseño y net
Concurrencia
Race condition: el problema de depositar y retirar
Sync Mutex: Lock y Unlock
Mutex de lectura y escritura
Sistema de caché sin concurrencia
Sistema de caché con concurrencia
Reutilización de computación intensiva
Patrones de diseño
¿Qué son los patrones de diseño?
Factory
Singleton
Adapter
Observer
Strategy
Net
Escaneador de puertos sin concurrencia
Escaneador de puertos con concurrencia
Netcat
Servidor de chat en Go con net
Terminando el chat
Conclusión
Resumen del curso de Go avanzado
1 Estudiante
Más popular
$21/mes
Un pago anual de $249
Aportes 8
Preguntas 2
Acá unas modificaciones que agregué al Código, espero les sirva:
// ToString function
func (c *Computer) String() string {
s := fmt.Sprintf("Product: %s, with Stock: %d", c.name, c.stock)
return s
}
// This is the factory
func ComputerFactory(computerType Product) (Product, error) {
switch computerType.(type) {
case *Desktop:
return NewDesktop(), nil
case *Laptop:
return NewLaptop(), nil
default:
return nil, fmt.Errorf("Unknown computer type: %T", computerType)
}
}
La función main se vería algo así al hacer el proceso de creación:
func main() {
laptop, _ := ComputerFactory(&Desktop{})
desktop, _ := ComputerFactory(&Laptop{})
fmt.Println(laptop)
fmt.Println(desktop)
}
Factory
Es un patrón creacional, que nos permite crear una “fabrica” de objetos a partir de una clase base y a su vez va implementar comportamientos polimórficos que permite modificar el comportamiento de las clases heredadas
package main
import (
"fmt"
"strings"
)
type IProduct interface {
setStock(stock int)
getStock() int
setName(name string)
getName() string
}
type Computer struct {
name string
stock int
}
func (c *Computer) setStock(stock int) {
c.stock = stock
}
func (c *Computer) setName(name string) {
c.name = name
}
func (c *Computer) getName() string {
return c.name
}
func (c *Computer) getStock() int {
return c.stock
}
type Laptop struct {
Computer
}
func newLaptop() IProduct {
return &Laptop{
Computer: Computer{
name: "Laptop computer",
stock: 25,
},
}
}
type Desktop struct {
Computer
}
func newDesktop() IProduct {
return &Desktop{
Computer: Computer{
name: "Desktop computer",
stock: 35,
},
}
}
func GetComputerFactory(computerType string) (IProduct, error) {
if strings.ToLower(computerType) == "laptop" {
return newLaptop(), nil
}
if strings.ToLower(computerType) == "desktop" {
return newDesktop(), nil
}
return nil, fmt.Errorf("Invalid computer type")
}
func printNameAndStock(p IProduct) {
fmt.Printf("Product name: %s, with stock %d\n", p.getName(), p.getStock())
}
func main() {
laptop, _ := GetComputerFactory("laptop")
desktop, _ := GetComputerFactory("desktop")
printNameAndStock(laptop)
printNameAndStock(desktop)
}
package main
import "errors"
// Patron Creacional
// Interface que define el comportamiento de un producto
type IProduct interface {
setStocked(stock int)
getStocked() int
getName() string
setName(name string)
}
// Implementacion de la interfaz IProduct para el producto de tipo "Computadora"
type Computer struct {
name string
stock int
}
// Implementando de forma implicita la interfaz IProduct
func (c *Computer) setStocked(stock int) {
c.stock = stock
}
func (c *Computer) getStocked() int {
return c.stock
}
func (c *Computer) getName() string {
return c.name
}
func (c *Computer) setName(name string) {
c.name = name
}
// Creando clase base de computadora, por composicion sobre herencia
type Laptop struct {
Computer
}
func NewLaptop() IProduct {
return &Laptop{Computer{"Laptop", 25}}
}
type Desktop struct {
Computer
}
func NewDesktop() IProduct {
return &Desktop{Computer{"Desktop", 35}}
}
// Creando fabrica de productos: Factory pattern
func GetComputerFactory(computerType string) (IProduct, error) {
switch computerType {
case "Laptop":
return NewLaptop(), nil
case "Desktop":
return NewDesktop(), nil
default:
return nil, errors.New("invalid computer type")
}
}
// Trying polymorphism
func PrintNameAndStock(product IProduct) {
println("Name:", product.getName(), "Stock:", product.getStocked())
}
func main() {
laptop, _ := GetComputerFactory("Laptop")
desktop, _ := GetComputerFactory("Desktop")
PrintNameAndStock(laptop)
PrintNameAndStock(desktop)
}
Aquí dejo mi código con comentarios
package main
import "fmt"
// interfaz que cumple la estructura Computer
type IProduct interface {
setStock(stock int)
getStock() int
setName(name string)
getName() string
}
//Las estructuras son literalmente clases
type Computer struct {
name string
stock int
}
//metodos de Computer para satisfacer la interfaz
func (c *Computer) setStock(stock int) {
c.stock = stock
}
func (c *Computer) setName(name string) {
c.name = name
}
func (c *Computer) getName() string {
return c.name
}
func (c *Computer) getStock() int {
return c.stock
}
// Podríamos decir que la estructura Laptop es hija de la
// estructura Computer
type Laptop struct {
Computer //composition over inheritance
}
// Constructor para crear una nueva laptop
func newLaptop() IProduct {
return &Laptop{
Computer: Computer{
name: "Laptop Computer",
stock: 25,
},
}
}
// Estructura hija de Computer, por lo que obtiene todos sus
// métodos
type Desktop struct {
Computer
}
// Constructor para crear una instancia de la estructura Desktop
func newDesktop() IProduct {
return &Desktop{
Computer{
name: "Desktop Computer",
stock: 35,
},
}
}
// Creamos función para determinar cuál estructura se debe
// instanciar
func GetComputerFactory(computerType string) (IProduct, error) {
if computerType == "laptop" {
return newLaptop(), nil
} else if computerType == "desktop" {
return newDesktop(), nil
}
return nil, fmt.Errorf("Invalid computer type")
}
// imprimimos los productos deseados utilizando la interfaz
func printNameAndStoc(p IProduct) {
fmt.Printf("PRoduct name: %s, with stock %d\n", p.getName(), p.getStock())
}
func main() {
laptop, _ := GetComputerFactory("laptop")
// instancia de la estructura Laptop
desktop, _ := GetComputerFactory("desktop")
// instancia de la estructura Desktop
printNameAndStoc(laptop)
printNameAndStoc(desktop)
}
Excelente explicación! 😄
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?