Menu
Coddy logo textTech

Ocultação de Informações em Go

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 50 de 107.

Ocultação de informações vai além de simplesmente tornar os campos não exportados. Trata-se de projetar seus tipos para que o código externo saiba apenas o que precisa saber. Nada mais.

O objetivo é expor o comportamento por meio de métodos, mantendo a estrutura interna completamente oculta. Considere esta abordagem:

type Counter struct {
    value    int
    maxLimit int
}

func NewCounter(limit int) *Counter {
    return &Counter{maxLimit: limit}
}

func (c *Counter) Increment() bool {
    if c.value >= c.maxLimit {
        return false
    }
    c.value++
    return true
}

func (c *Counter) Value() int {
    return c.value
}

Código externo não sabe que Counter usa um int internamente. Ele poderia ser um float64, uma fatia ou algo completamente diferente. A implementação pode mudar sem afetar nenhum código que use Counter, desde que os métodos se comportem da mesma maneira.

Esse princípio também se aplica às funções auxiliares. Mantenha a lógica interna não exportada:

// Exportado - parte da API pública
func (c *Counter) Reset() {
    c.value = 0
}

// não exportado - auxiliar interno
func (c *Counter) isAtLimit() bool {
    return c.value >= c.maxLimit
}

Ao ocultar isAtLimit(), você fica livre para alterá-la ou removê-la posteriormente. A ocultação de informações cria um limite claro entre o que seu pacote promete aos usuários externos e como ele funciona internamente.

challenge icon

Desafio

Fácil

Vamos criar um sistema de carteira segura que demonstre o encapsulamento de informações. Você criará uma carteira digital em que o controle do saldo interno e o histórico de transações ficam completamente ocultos do código externo: somente o comportamento é exposto por meio de métodos.

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

  • wallet.go: crie uma struct Wallet que oculte todo o seu estado interno. A carteira deve controlar internamente o saldo atual e um limite de gastos, mas o código externo nunca deve saber como eles são armazenados ou representados. Exponha o comportamento por meio destes métodos:
    • NewWallet(limit float64) *Wallet - construtor que cria uma carteira com o limite de gastos fornecido e saldo zero
    • Deposit(amount float64) bool - adiciona dinheiro à carteira e retorna true se for bem-sucedido (o valor deve ser positivo)
    • Spend(amount float64) bool - remove dinheiro se houver saldo suficiente E o valor não exceder o limite de gastos, retornando true se for bem-sucedido
    • Balance() float64 - retorna o saldo atual
    • Status() string - retorna uma mensagem de status no formato: Balance: $[balance] (Limit: $[limit])
    Mantenha qualquer lógica auxiliar (como verificar se uma transação é válida) como funções ou métodos não exportados. Esses são detalhes internos de implementação que podem mudar posteriormente.
  • main.go: leia a configuração da carteira e as transações da entrada, crie uma carteira, execute as operações e exiba os resultados após cada ação.

As seguintes entradas serão fornecidas:

  • Linha 1: Limite de gastos
  • Linha 2: Valor do depósito
  • Linha 3: Primeiro valor a gastar
  • Linha 4: Segundo valor a gastar

Depois de criar a carteira, imprima seu status inicial. Em seguida, execute cada operação e imprima o status atualizado (se for bem-sucedida) ou Transaction failed (se a operação for rejeitada). Formate todos os valores em dólares com duas casas decimais.

Por exemplo, dadas as entradas 50, 100, 30 e 80, sua saída deve ser:

Balance: $0.00 (Limit: $50.00)
Balance: $100.00 (Limit: $50.00)
Balance: $70.00 (Limit: $50.00)
Transaction failed

A última transação falha porque $80 excede o limite de gastos de $50, embora haja saldo suficiente. A carteira aplica suas regras internamente sem expor como toma essas decisões. O código externo simplesmente chama métodos e recebe resultados, sem nunca conhecer os detalhes internos de implementação.

Experimente você mesmo

package main

import (
	"fmt"
)

func main() {
	// Ler entradas
	var limit float64
	var depositAmount float64
	var spend1 float64
	var spend2 float64

	fmt.Scanln(&limit)
	fmt.Scanln(&depositAmount)
	fmt.Scanln(&spend1)
	fmt.Scanln(&spend2)

	// TODO: Criar uma nova carteira com o limite de gastos fornecido

	// TODO: Imprimir o status inicial

	// TODO: Perform deposit and print result (status or "Transaction failed")

	// TODO: Realizar o primeiro gasto e imprimir o resultado

	// TODO: Realizar o segundo gasto e imprimir o resultado
}
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

Pratique por conta própria: Compilador de Go online