Menu
Coddy logo textTech

Encadeamento de Métodos

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy — lição 81 de 107.

Encadeamento de métodos (method chaining) é uma técnica onde os métodos retornam o receptor, permitindo que múltiplas chamadas de método sejam vinculadas em uma única instrução. Você já viu isso no padrão Builder, mas é um conceito independente útil em muitos contextos.

A chave é retornar um ponteiro para a struct de 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
}

Agora você pode encadear estas chamadas fluentemente:

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

Isso soa quase como linguagem natural em comparação com instruções separadas. O encadeamento de métodos funciona melhor quando as operações configuram ou modificam um objeto sem a necessidade de retornar outros valores. É comumente usado em construtores de consultas, APIs de configuração e bibliotecas de asserção de testes.

Lembre-se de que cada método deve usar um receptor de ponteiro e retornar *StructType para que o encadeamento funcione corretamente.

challenge icon

Desafio

Fácil

Vamos construir um construtor de elementos HTML fluente que utiliza encadeamento de métodos para construir tags HTML com atributos e conteúdo! Esta é uma aplicação prática de encadeamento de métodos — você criará uma API que soa quase como linguagem natural ao construir elementos HTML.

Você organizará seu código em dois arquivos:

  • element.go: Defina seu construtor de elementos HTML com métodos encadeáveis.

    Crie uma struct Element que armazena o nome da tag, um mapa de atributos (string para string) e o conteúdo interno. Construa estes métodos encadeáveis que retornam *Element:

    • NewElement(tag string) - construtor que cria um novo Element com o nome da tag fornecido e um mapa de atributos inicializado (vazio)
    • Attr(key, value string) - adiciona um atributo ao elemento
    • ID(id string) - método de conveniência que define o atributo "id"
    • Class(class string) - método de conveniência que define o atributo "class"
    • Content(text string) - define o conteúdo interno do elemento

    Adicione um método Render() que retorna a string HTML. Os atributos devem aparecer em ordem alfabética pela chave. O formato é:

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

    Se não houver atributos, apenas renderize <tag>content</tag>. Se não houver conteúdo, renderize <tag attr="value"></tag>.

  • main.go: Construa elementos HTML usando encadeamento de métodos.

    Leia o nome da tag e, em seguida, leia uma contagem de operações a serem realizadas. Cada operação é uma das seguintes:

    • id seguido pelo valor do ID
    • class seguido pelo valor da classe
    • attr seguido pelo nome e valor do atributo (duas linhas)
    • content seguido pelo texto do conteúdo

    Encadeie todas as operações de forma fluente e, em seguida, imprima o HTML renderizado.

As seguintes entradas serão fornecidas:

  • Linha 1: Nome da tag
  • Linha 2: Número de operações
  • Linhas seguintes: Tipo de operação e valor(es)

Por exemplo, dado:

div
3
id
container
class
main-content
content
Hello World

Sua saída deve ser:

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

E dado:

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

Sua saída deve ser:

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

E dado:

input
2
attr
type
text
attr
placeholder
Enter name

Sua saída deve ser:

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

E dado:

p
1
content
Simple paragraph

Sua saída deve ser:

<p>Simple paragraph</p>

Observe como o encadeamento de métodos permite construir elementos passo a passo de uma forma legível. Cada método modifica o elemento e o retorna, permitindo que a próxima chamada de método seja encadeada diretamente.

Folha de consulta

O encadeamento de métodos (method chaining) é uma técnica onde os métodos retornam o receptor (geralmente *StructType), permitindo que várias chamadas de método sejam vinculadas em uma única instrução.

Cada método deve usar um receptor de ponteiro e retornar *StructType:

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
}

Encadeie chamadas de método de forma fluida:

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

O encadeamento de métodos funciona melhor quando as operações configuram ou modificam um objeto sem a necessidade de retornar outros valores. É comumente usado em construtores de consultas (query builders), APIs de configuração e bibliotecas de asserção de testes.

Experimente você mesmo

package main

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

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

	// Ler o nome da tag
	scanner.Scan()
	tagName := scanner.Text()

	// Ler o número de operações
	scanner.Scan()
	numOps, _ := strconv.Atoi(scanner.Text())

	// Criar o elemento
	element := NewElement(tagName)

	// Processar cada operação
	for i := 0; i < numOps; i++ {
		scanner.Scan()
		operation := scanner.Text()

		// TODO: Com base no tipo de operação, encadeie o método apropriado
		// As operações podem ser: "id", "class", "attr" ou "content"
		// - Para "id": leia a próxima linha como o valor do ID
		// - Para "class": leia a próxima linha como o valor da classe
		// - Para "attr": leia as próximas DUAS linhas (nome do atributo, depois o valor)
		// - Para "content": leia a próxima linha como o texto do conteúdo
		// Use o encadeamento de métodos para construir o elemento de forma fluente

		_ = operation // Remova esta linha ao implementar
	}

	// Imprimir o HTML renderizado
	fmt.Println(element.Render())
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos