Executando verificação de segurança...
4

Go não é POO!

É isso mesmo, você não leu errado. Go não é POO e por padrão não possui suporte para o paradigma.

"Mas como assim? Eu ja vi vários vídeos no YouTube de pessoas explicando como podemos utilizar Go com POO..."

Esse também foi meu argumento quando estava aprendendo. Apesar de Go suportar métodos, composição, polimorfismo e encapsulamento não há suporte para herança por padrão e também não existem objetos. Talvez essas informações sejam um balde de agua fria para alguns e para outros nem tanto.

Vindo de uma linguagem que suporta fortemente os recursos da POO (Typescript e Java), só depois de um tempo fazendo alguns projetos que pude notar o erro que estava cometendo. É natural que tentamos replicar o que estamos acostumados a fazer todos os dias, afinal esse paradigma é algo tipico das linguagens de programação de mercado, além de que POO é uma opção quase que indispensável para se trabalhar e construir a maioria dos softwares e aplicações do cotidiano.

É possivel que podemos programar OO com Go, não de forma natural e padronizada, mas como uma espécie de POO virtualizada, pois utilizamos de alguns artificios a partir do recurso que a linguagem nos oferece para o estilo de programar com a mesma. Veja este exemplo abaixo:

package main

import (
	"fmt"
	"time"
)

type User struct {
	name, country string
	age           int
}

type IUser interface {
	calcBirthYear() int
}

func (u *User) calcBirthYear() int {
	return time.Now().Year() - u.age
}

func calcBirthYear(u IUser) {
	fmt.Printf("Your age is %d", u.calcBirthYear())
}

func main() {
	user := User{
		name:    "Fulano de Tal",
		country: "Brasil",
		age:     23,
	}

	calcBirthYear(&user) //Your age is 2000
}

Criamos uma struct bem simples com 3 dados, name, country e age, uma interface com um metodo chamado "calcBirthYear" que abaixo satisfaz esta mesma interface que calculará o ano de nascimento do usuário e em seguida hidratamos a struct com os dados que foram definidos. até ai bem parecido com a POO, mas perceba que logo de cara, notamos que uma struct não é uma classe, a principal diferença é que uma struct armazena tipos de dados enquanto uma classe contém um modelo de tipos de dados e comportamentos e pode server como modelo para vários dados. Um exemplo:

interface IUser {
  calcBirthYear(): number;
}

class User implements IUser {
  public name: string;
  public country: string;
  public age: number;

  constructor(name: string, country: string, age: number) {
    this.name = name;
    this.country = country;
    this.age = age;
  }

  calcBirthYear(): number {
    return new Date().getFullYear() - this.age;
  }
}

const user = new User("Fulano de Tal", "Brasil", 23)

console.log(`age: ${user.calcBirthYear()}`) //age: 2000

A principal diferença esta exatamente nos recursos e no objetivo que ambas as linguagens oferecem para trabalhar com tal paradigma pois ambas se assemelham muito quando o assunto é sintaxe, mesmo assim Go não foi feito para a programação OO, sim, pode não fazer tanto sentido vendo esses exemplos, na verdade parece estar na cara que dá sim para usar OO com Go, mesmo de uma forma não natural, no entanto quanto mais vamos utilizando a linguagem mais entendemos suas limitações quando queremos criar algo mais complexo com POO.

Então você deve estar se perguntando "Se Go não é OO e algumas pessoas programam mesmo assim, qual paradigma serve melhor para Go?"

A comunidade do Go costuma não rotular a linguagem a partir de um paradigma X ou Y, sendo assim Go tem seu próprio jeito de codar, o famoso Go way. E isso também se aplica ao objetivo de cada linguagem, Go não foi pensado numa linguagem para suportar a OO, mas sim para ter bastante performance ao mesmo tempo que se mantém simples. Muito cuidado ao adicionar complexidade onde não deveria existir.

Carregando publicação patrocinada...
7

Legal postar isso. E está correto, por uma escola que define OOP assim. Há quem questione, provavelmente por usar outra escola.

De fato precisa adaptar o código ao estilo da linguagem, se não fizer isso provavelmente está usado a linguagem de forma errada e não a aproveitando bem o que ela oferece, e foi uma escolha errada.

Sim, OOP não é universalmente definida.

OOP é dispensável em boa parte das aplicações. Hoje a maioria não sabe mais desenvolver sem ela porque só aprendeu assim. Estritamente falando ela é dispensável em todos os softwares, mas em alguns podemos dizer, grosso modo, que ela é indispensável porque realmente ajuda muito. Existem muitos softwares que ela é 100% dispensável. Quem tem experiência completa na computação sabe disso.

Não é por acaso que algumas linguagens mais modernas resolveram não facilitar o uso desse paradigma secundário.

Essa estória de Go way é conversa mole, alguém inventa um termo que não faz muito sentido e as pessoas adotam sem questionar. Ou inventou um paradigma e ele precisa ser universalizado, mesmo que apenas uma linguagem o adote hoje, ou usa um já existente.

OO gera complexidade para gerenciar complexidade. A grande vantagem de Go é tentar evitar isso se atentando mais ao paradigma imperativo sem pendurar outro paradigmas secundários de forma clara.

Go tem objetos sim. Toda linguagem tem. Pode não ter objetos com certas características, mas mesmo dentro de algumas definições mais restritas me parece que Go também tem objetos. Se não for então preciso de melhores argumentos.

Faz sentido para você?

Espero ter ajudado.


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

1

De fato na altura em que estamos hoje em dia, é quase que nula a possibilidade de programarmos sem pelo menos um dos aspectos do OO, mas de modo geral, objetos estão por todos os cantos de nosso código, mesmo que indiretamente hoje em dia, as possibilidades de muitas linguagens terem uma estrutura para escondar dados e ter comportamentos é grande!

5

Quando alguém diz que determinada linguagem é (ou não é) OOP, primeiro devemos nos perguntar: de qual OOP estamos falando?

Pois é. Não existe uma definição única, canônica, oficial e universalmente aceita sobre o que é orientação a objeto. No fundo ninguém concorda.

O que temos são escolas, ou se preferir, vertentes. No link já indicado pelo Maniero tem uma análise bem detalhada, sugiro que leia tudo pra entender o histórico e as contradições que as pessoas infelizmente não param mais pra pensar a respeito. Mas de forma bem resumida, podemos dizer que as principais vertentes são a de Alan Kay e Bjarne Stroustrup:

Alan Kay vs Bjarne Stroustrup - diferentes definições de OOP

O primeiro é "só" o cara que cunhou o termo "orientação a objeto" (veja aqui e aqui o que ele mesmo tem a dizer sobre isso) e o segundo criou um tal de C++, acho que vc já ouviu falar :-)

Bom, o link já indicado tem todos os detalhes, mas só pra resumir, uma das vertentes é que para ser OOP basta seguir os 3 pilares (encapsulamento, herança e polimorfismo - há vertentes que incluem outros, mas não vamos nos alongar). Note que não é obrigatório usar classes, já que elas são apenas um mecanismo que facilita tudo isso, mas nem de longe é pré-requisito. JavaScript, por exemplo, usa protótipos (até existe a palavra-chave class, mas é só um syntax sugar, pois debaixo dos panos continua usando protótipos). Até mesmo em C é possível "programar orientado a objeto" (ou seja, seguindo os 3 pilares, caso vc siga tal vertente).


Por isso, quando dizemos que uma linguagem é ou não OOP, primeiro temos que saber de qual escola estamos falando. E mesmo assim é complicado, porque a maioria das linguagens - senão todas - hoje em dia são híbridas, contendo um pouco de cada paradigma. Dizer que ela é somente uma coisa costuma ser uma simplificação, muitas vezes até marketeira.

O próprio FAQ oficial da linguagem Go possui a pergunta "Go é orientada a objeto?" e a resposta é "Sim e não".


Objeto

Quanto à definição de objeto, ela pode ser tão confusa quanto a de OOP. O Maniero também já colocou o link, no qual podemos ver que a definição de objeto é bem mais ampla do que costumamos ver por aí. Praticamente qualquer coisa (variável, estrutura, função/método, etc), qualquer região da memória que contenha um valor e possa ser acessada e manipulada pode ser um objeto.

O problema é que cada linguagem também costuma ter sua própria definição, muitas vezes mais restrita que o conceito geral. Por exemplo, em JavaScript a MDN define como "uma coleção de propriedades". Em Python, um objeto é uma "abstração para dados". Em outras linguagens, é "uma instância de uma classe". Em C11, na seção 3.15, objeto é "uma região de armazenamento de dados no ambiente de execução, cujo conteúdo pode representar valores".

Então tem que ver qual a definição que Go dá para "objetos" (mas tecnicamente falando, ela tem sim).

3

Em uma linguagem de programação imperativa, existem apenas duas coisas: valores e comportamentos. Só. Tooodo o resto é derivado disso. Go é essencial, é elementar, é lindo. Aprendi a ser um programador melhor ao entender a beleza e a simplicidade embutidas na linguagem Go. Projetos partem sempre do simples e tendem a crescer apenas o necessário.
Go usa a chamada lightweight OO, cortando um monte de coisa, e só vinculando valores com comportamento (métodos), o que é perfeitamente substituível por funções que têm o mesmo tipo de receiver como padrão. Claro, tem interfaces também, o que é bem útil.
Go não veio pra revolucionar a ciência da computação e todos os conceitos que amamos mastigar em cafés. Go veio resolver problemas da forma mais simples e direta o possível.

1

Interessante, nunca gostei de classe, e sempre achei que o Struct deveria ter sido melhor aproveitado, sempre achei falho esse negócio de classe no C++.

Quando eu vi, a sintaxe do RUST, de cara falei, é isso. É assim que o verdadeiro sucessor do C deveria ser.

Interessante saber que o Go pegou a mesma sacada, isso é interessante e todo esse negócio de orientação a objetos chega a ser ilusório, rs.