Menu
Coddy logo textTech

Encadenamiento de métodos

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy. Lección 81 de 107.

El encadenamiento de métodos es una técnica en la que los métodos devuelven el receptor, lo que permite enlazar varias llamadas a métodos en una sola instrucción. Ya has visto esto en el patrón Builder, pero es un concepto independiente útil en muchos contextos.

La key es devolver un puntero a la estructura desde cada método:

type Query struct {
    table   string
    columns []string
    where   string
    limit   int
}

func (q *Query) Select(cols ...string) *Query {
    q.columns = cols
    return q
}

func (q *Query) From(table string) *Query {
    q.table = table
    return q
}

func (q *Query) Where(condition string) *Query {
    q.where = condition
    return q
}

func (q *Query) Limit(n int) *Query {
    q.limit = n
    return q
}

Ahora puedes encadenar estas llamadas de forma fluida:

query := &Query{}
query.Select("name", "email").From("users").Where("active = true").Limit(10)

Esto se lee casi como lenguaje natural en comparación con declaraciones separadas. El chaining de métodos funciona mejor cuando las operaciones configuran o modifican un objeto sin necesidad de devolver otros valores. Se usa comúnmente en constructores de consultas, API de configuración y bibliotecas de aserciones para pruebas.

Recuerda que cada método debe usar un receptor puntero y devolver *StructType para que la cadena funcione correctamente.

challenge icon

Desafío

Fácil

¡Construyamos un generador fluido de elementos HTML que use el encadenamiento de métodos para construir etiquetas HTML con atributos y contenido! Esta es una aplicación práctica del encadenamiento de métodos: crearás una API que se lee casi como lenguaje natural al construir elementos HTML.

Organizarás tu código en dos archivos:

  • element.go: Define tu generador de elementos HTML con métodos encadenables.

    Crea una estructura Element que almacene el nombre de la etiqueta, un mapa de atributos (de string a string) y el contenido interno. Crea estos métodos encadenables, cada uno de los cuales devuelve *Element:

    • NewElement(tag string) - constructor que crea un nuevo Element con el nombre de etiqueta indicado y un mapa de atributos inicializado (vacío)
    • Attr(key, value string) - añade un atributo al elemento
    • ID(id string) - método práctico que establece el atributo "id"
    • Class(class string) - método práctico que establece el atributo "class"
    • Content(text string) - establece el contenido interno del elemento

    Añade un método Render() que devuelva la cadena HTML. Los atributos deben aparecer en orden alfabético por clave. El formato es:

    <tag attr1="value1" attr2="value2">content</tag>

    Si no hay atributos, simplemente representa <tag>content</tag>. Si no hay contenido, representa <tag attr="value"></tag>.

  • main.go: Construye elementos HTML usando el encadenamiento de métodos.

    Lee el nombre de la etiqueta y después lee un recuento de operaciones que se realizarán. Cada operación es una de las siguientes:

    • id seguido del valor del ID
    • class seguido del valor de la clase
    • attr seguido del nombre y el valor del atributo (dos líneas)
    • content seguido del texto del contenido

    Encadena todas las operaciones de forma fluida y después imprime el HTML renderizado.

Se proporcionarán las siguientes entradas:

  • Línea 1: Nombre de la etiqueta
  • Línea 2: Número de operaciones
  • Líneas siguientes: Tipo de operación y valor(es)

Por ejemplo, dada la siguiente entrada:

div
3
id
container
class
main-content
content
Hello World

Tu salida debe ser:

<div class="main-content" id="container">Hello World</div>

Y dada la siguiente entrada:

a
3
attr
href
https://example.com
attr
target
_blank
content
Click here

Tu salida debe ser:

<a href="https://example.com" target="_blank">Click here</a>

Y dada la siguiente entrada:

input
2
attr
type
text
attr
placeholder
Enter name

Tu salida debe ser:

<input placeholder="Enter name" type="text"></input>

Y dada la siguiente entrada:

p
1
content
Simple paragraph

Tu salida debe ser:

<p>Simple paragraph</p>

Observa cómo el encadenamiento de métodos te permite construir elementos paso a paso de forma legible. Cada método modifica el elemento y lo devuelve, lo que permite encadenar directamente la siguiente llamada al método.

Pruébalo tú mismo

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	// Leer el nombre de la etiqueta
	scanner.Scan()
	tagName := scanner.Text()

	// Leer el número de operaciones
	scanner.Scan()
	numOps, _ := strconv.Atoi(scanner.Text())

	// Crear el elemento
	element := NewElement(tagName)

	// Procesar cada operación
	for i := 0; i < numOps; i++ {
		scanner.Scan()
		operation := scanner.Text()

		// TODO: Según el tipo de operación, encadena el método apropiado
		// Las operaciones pueden ser: "id", "class", "attr" o "content"
		// - Para "id": lee la siguiente línea como el valor del ID
		// - Para "class": lee la siguiente línea como el valor de la clase
		// - Para "attr": lee las siguientes DOS líneas (nombre del atributo, luego el valor)
		// - Para "content": lee la siguiente línea como el texto del contenido
		// Usa el encadenamiento de métodos para construir el elemento de forma fluida

		_ = operation // Elimina esta línea al implementar
	}

	// Imprime el HTML renderizado
	fmt.Println(element.Render())
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Go online