Linguagens de Programação

Associatividade e precedência de operadores

Associatividade e precedência de operadores é um assunto um pouco marginalizado no estudo de linguagens de programação. Em algum momento todo desenvolvedor vai se deparar com um problema relacionado a isso.

Por exemplo, a expressão 8 * 2 - 1 pode ser vista como (8 * 2) - 1 ou 8 * (2 - 1) e essa diferença muda a forma dela ser calculada e, consequentemente, o seu resultado. Essa ambiguidade foi resolvida lá nos primórdios pelos matemáticos através de regras de precedência e associatividade. Essas mesmas regras são aplicadas nos projetos das linguagens de programação. Quando um projetista de linguagem vai criar a especificação dela, ele precisa definir de antemão todas essas regras.

Precedência: um operador possui maior precedência que outro se ele precisar ser analisado antes em todas as expressões sem parênteses que envolverem apenas os dois operadores. Na matemática, na expressão 8 * 2 - 1, a multiplicação é sempre avaliada antes da subtração, ou seja, ela possui maior precedência. Portanto, a expressão equivalente seria: (8 * 2) - 1.

Já a associatividade especifica se os operadores de igual precedência devem ser avaliados da esquerda para a direita ou da direita para a esquerda. De volta à matemática, o operador “menos” possui associatividade à esquerda, portanto, 10 - 9 - 8 é equivalente a (10 - 9) - 8.

Na matemática

Precedência na matemática, da maior pra menor:

  • 1) Parênteses;
  • 2) Expoentes;
  • 3) Multiplicações e divisões; (da esquerda para a direita);
  • 4) Somas e subtrações. (da esquerda para a direita);

Grande parte das linguagens de programação seguem (sempre que possível) as convenções matemáticas comuns para associatividade e precedência.

Na maioria das linguagens de programação os operadores de atribuição são definidos com associatividade à direita. Ou seja, a = b = c é o equivalente a a = (b = c), que alimenta as variáveis a e b com o valor armazenado em c. As linguagens de programação possuem em suas documentações uma tabela dos operadores e suas precedências, da maior pra menor, bem como a associatividade desses operadores. Portanto, a regra aqui é avaliar essa tabela na linguagem que você utiliza.

Forçando precedência

Assim como na matemática, as linguagens permitem que usemos parênteses para forçar uma maior precedência. Essa expressão aqui:

x = 8 + 9 * 2; // 26

Em qualquer linguagem, vai resultar em 26, pois a multiplicação possui maior precedência que a subtração. No entanto, se utilizarmos parênteses entre a operação de soma, ela passa ter precedência maior que a multiplicação e, consequentemente, o resultado muda:

x = (8 + 9) * 2; // 34

Sem uma definição clara de precedência as expressões com múltiplos operadores se tornariam ambíguas. Um exemplo disso:

x = 4/2*1+3; // 5

Que resultado você espera ter? Pra quem está lendo essa expressão, não é tão óbvio como calculá-la. Por isso forçar precedência é uma boa prática, traz mais legibilidade e coerência para sua operação.

O resultado da expressão acima é diferente do resultado que força precedência:

x = (4/2)*(1+3); // 8

Precedência é sobre agrupamento

Uma observação muito importante a ser feita é que precedência não determina a ordem de avaliação, precedência apenas determina como a operação vai ser agrupada para depois ser avaliada. Ou seja, precedência especifica que a expressão:

f1() + f2() * f3()

Será agrupada como:

f1() + (f2() * f3())

Ou seja, precedência não fala que a função f2() vai ser avaliada primeiro que f1(). A ordem de avaliação padrão da maioria das linguagens de programação é da esquerda para a direita, mas as regras de associatividade podem alterar isso no meio do caminho.

Então, a ordem de avaliação das funções acima seria primeiro a f1(), depois a f2() e por fim a f3(), da esquerda para a direita. A função da precedência foi apenas agrupar as duas expressões (f2() * f3()).

Abaixo exemplos de como diferentes expressões são agrupadas no processo de parsing de uma linguagem de programação (na construção da árvore sintática abstrata):

-a * b                      => ((-a) * b)
!-a                         => (!(-a))
a + b + c                   => ((a + b) + c)
a * b * c                   => ((a * b) * c)
a * b / c                   => ((a * b) / c)
a + b / c                   => (a + (b / c))
a + b * c + d / e - f       => (((a + (b * c)) + (d / e)) - f)
3 + 4 * 5 == 3 * 1 + 4 * 5  => ((3 + (4 * 5)) == ((3 * 1) + (4 * 5)))

Por exemplo, a expressão:

1 + 2 + 3;

No parsing da linguagem, depois de se aplicar as regras de precedência, ela é agrupada dessa forma:

((1 + 2) + 3)

A representação da árvore abstrata dessa expressão seria algo como:

Representação abstrata de precedência

Ou seja, mais à esquerda temos uma expressão que um lado do seu nó é o literal 1 e o outro lado o 2. E essa expressão está à esquerda da expressão que tem o nó do literal 3.

Tabela de precedência e associatividade

Na documentação da sua linguagem de programação, você deverá encontrar uma tabela parecida com essa abaixo, onde os operadores são ordenados pelos de maior precedência e uma coluna especificando a associatividade:

NomeOperador(es)Associatividade
Unário!direita
Aritmética* / %esquerda
Aritmética- +esquerda
Comparação< > <= >=esquerda
Comparação== !=esquerda
Atribuição= += -= *=direita

Nessa especificação temos claro que a operação aritmética de multiplicação * tem precedência maior que a subtração - (por estar numa ordem superior na tabela). Da mesma forma, os operadores ariméticos possuem maior precedência que os operadores de atribuição.

O operador unário ! de negação tem associatividade à direita, ou seja, quer dizer que primeiro a expressão da direita será avaliada antes de fazer a negação. Da mesma forma os operadores de atribuição vão resolver as espressões à direita antes de fazer a atribuição.

Apesar de as linguagens de programação seguirem regras parecidas, não há como generalizar, há sempre algumas diferenças, portanto, não deixe de consultar a documentação da sua linguagem.

Até a próxima!

Quais as diferenças entre tipagens: estática ou dinâmica e forte ou fraca

Quando vemos uma nova linguagem de programação, uma das primeiras coisas que as pessoas costumam colocar na descrição dela é a tipagem. Neste artigo vamos falar um pouco sobre os tipos de tipagem.

Tipagem Estáticas

Linguagens com tipagem estática não permitem ao desenvolvedor alterar o tipo da variável depois de declarada. Geralmente a verificação de tipo é feita em tempo de compilação. Podemos ver o exemplo abaixo na linguagem Java:

public class MyClass {
    public static void main(String args[]) {
      int variavel = 10;

      variavel = "Elton Fonseca"; //error: incompatible types: String cannot be converted to int
    }
}

Quando tentamos atribuir um valor de um tipo diferente do que foi declarado na variável temos um erro.

Java - Fundamentos
Curso de Java - Fundamentos
CONHEÇA O CURSO

Tipagem Dinâmica

A tipagem dinâmica está ligado a habilidade da linguagem de programação em escolher o tipo de dado de acordo com o valor atribuído à variável em tempo de execução dinamicamente. Veja o exemplo abaixo na linguagem PHP:

$variavel = "Elton Fonseca";

echo gettype($variavel); //string

$variavel = 340;

echo gettype($variavel); //integer

$variavel = 340.89;

echo gettype($variavel); //double

$variavel = true;

echo gettype($variavel); //boolean

Muita gente confunde, acha que linguagem de tipagem dinâmica não possui tipos. Na verdade, ela possui tipos normalmente, a diferença está apenas na capacidade da linguagem em escolher o tipo automaticamente.

PHP - Fundamentos
Curso de PHP - Fundamentos
CONHEÇA O CURSO

Inferência de tipo

Algumas linguagens estáticas podem fazer a inferência de tipo na declaração de variáveis, mas não permite que o tipo seja alterado após a declaração. Veja esse exemplo na linguagem C#:

using System;

public class Program
{
    public static void Main()
    {
        var variavel = "Treinaweb";

        Console.WriteLine(variavel.GetType()); //System.String

        variavel = 28; //Compilation error (line 11, col 14): Cannot implicitly convert type 'int' to 'string'
    }
}

Ele apresenta um erro quando tentamos atribuir um valor de tipo diferente a variável. Isso porque ele apenas realiza a inferência do tipo inicial da variável, depois disso como a linguagem possui características estáticas não permite alterar o tipo.

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Tipagem Fraca

A tipagem fraca está ligada a característica da linguagem de realizar conversões automaticamente entre tipos diferentes de dados. Veja o exemplo abaixo abaixo em Javascript:

var nome = "Elton Fonseca"; //string

var idade = 28; //number

console.log(nome + " " + idade); //Elton Fonseca 28
JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

Tipagem Forte

Linguagens fortemente tipadas não realizam conversões automaticamente. Vamos pegar como exemplo a linguagem Python. Ela possui tipagem forte, se formos executar o exemplo acima em Python teríamos um erro:

nome = "Elton Fonseca" #str
idade = 28 #int

print(nome + " " + idade) #TypeError: can only concatenate str (not "int") to str
Python - Fundamentos
Curso de Python - Fundamentos
CONHEÇA O CURSO

Considerações finais

Muitas linguagens de programação não se enquadram exatamente entre tipagem estática ou dinâmica e tipagem forte ou fraca. Principalmente pelo fato de cada uma destas abordagens possuírem vantagens e desvantagens, as linguagens mais modernas tendem a mesclar alguns aspectos de cada uma.

5 motivos para estudar Java

Quando começamos a estudar sobre desenvolvimento de software ou quando desejamos aprender uma nova plataforma de desenvolvimento, é normal que tenhamos dúvidas sobre a partir de qual linguagem começar. Fatalmente, uma das primeiras opções que acaba sendo considerada como uma possibilidade é o Java.

O Java é uma linguagem de programação majoritariamente orientada a objetos multiplataforma. Com o Java, é possível desenvolver toda uma gama de soluções que vão desde aplicações embarcadas até aplicações web e mobile. Sendo assim, será que ainda vale a pena estudar Java? Este artigo irá lhe apresentar cinco fortes motivos para que você estude a plataforma de desenvolvimento da Oracle.

Java - Fundamentos para Web
Curso de Java - Fundamentos para Web
CONHEÇA O CURSO

1. O Java é uma das linguagens mais populares em todo mundo

O Java está entre as três linguagens de programação mais utilizadas no mundo atualmente, alternando posições junto ao C e C++. A versatilidade e o aspecto multiplataforma do Java justificam a utilização da plataforma em uma gama enorme de soluções.

O TIOBE Index é um índice que classifica diferentes linguagens de programação mensalmente de acordo com o número de pesquisas pela linguagem nos sites de busca. No ranking de setembro de 2019, é possível notar que o Java está em primeiro lugar, posição esta que é ocupada pelo Java já há algum tempo.

Na imagem acima, está o gráfico com as cinco primeiras linguagens de setembro de 2019, o que inclui o Java. Observando o gráfico, é possível constatar a força do Java como plataforma de desenvolvimento frente a outras linguagens.

2. Existem várias oportunidades de emprego para desenvolvedores Java

A popularidade do Java como linguagem reflete diretamente em um ponto: a quantidade de vagas disponíveis para profissionais que trabalham com a plataforma. Existem várias vagas de emprego para desenvolvedores Java no Brasil e no exterior, vagas estas por vezes com salários e benefícios muito atrativos.

Uma rápida pesquisa por “Java” limitada ao Brasil no painel de vagas do LinkedIn trouxe mais de 6500 resultados. Entre as vagas retornadas pela pesquisa, apareceram oportunidades em empresas relevantes no meio de tecnologia da informação, como CI&T, Guiabolso, Sensedia, PagSeguro e Accenture. Também existiam vagas para todos os níveis profissionais, de estágios até mesmo para desenvolvedores nível sênior e especialistas.

3. A comunidade Java é muito grande e ativa

O Java apresenta uma das maiores comunidades open source. Somente a Apache Software Foundation, uma das maiores organizações voltadas a open source no mundo, ajuda a manter atualmente 235 projetos voltados ao Java em vertentes que vão desde ferramentas de build a servidores como o Tomcat.

Uma pesquisa por “java” no GitHub revela a existência de mais de 700 mil repositórios abertos fundamentados no Java, totalizando mais de 18 milhões de commits. Várias outras soluções de outras plataformas acabaram se baseando em soluções desenvolvidas inicialmente para o Java, como o NHibernate para linguagens baseadas em .NET, framework este fortemente inspirado no Hibernate do Java. E isso tudo sem contar ainda com o Android, o sistema operacional mobile utilizado em mais de 75% de dispositivos do mundo e que é fundamentado no Java. Estes dados deixam muito clara a força do Java como plataforma de desenvolvimento no mundo nos dias de hoje.

4. O Java está presente em uma infinidade de soluções diferentes

O aspecto multiplataforma do Java o fez ficar popular em uma série de ambientes e configurações distintas. É possível criar aplicações embarcadas com o Java através do Java Embedded, criar aplicações mobile para o Android através do Android SDK, aplicações desktop com o Java SE e aplicações web e corporativas de larga escala através do Java EE.

Desenvolvedores Java ainda podem contar com uma infinidade de alternativas da própria comunidade para o desenvolvimento dos mais variados tipos de aplicações, como o Spring, Quartz, Vaadin e JasperReports. Isso tudo faz com que o Java seja uma alternativa para o desenvolvimento de aplicações eficientes para os mais variados ambientes de execução, compartilhando uma grande base de código entre estes diferentes ambientes.

Desenvolvedor Java Júnior
Formação: Desenvolvedor Java Júnior
A formação Desenvolvedor Java nível Júnior da TreinaWeb tem como objetivo fornecer uma introdução ao desenvolvimento através do Java e todo o ecossistema para desenvolvimento da Oracle. Nesta formação, são abordados tópicos como o desenvolvimento da capacidade analítica, o paradigma orientado a objetos, a preparação do ambiente de desenvolvimento para o Java através do Eclipse e o controle de versão de código através do Git e do GitHub. Além disso, também são abordados aspectos mais essenciais da linguagem e estruturas importantíssimas dentro do ecossistema do Java, como a Stream API, que auxilia a lidar com coleções de dados; a implementação das estruturas de dados mais tradicionais como listas, filas e pilhas; e a API de coleções.
CONHEÇA A FORMAÇÃO

5. O Java está em evolução

Apesar de um período de estagnação pós a aquisição da Sun pela Oracle, hoje o Java é uma linguagem moderna e aderente aos novos paradigmas de desenvolvimento. Além da forte veia orientada a objetos da linguagem, é perfeitamente possível escrever código em outros paradigmas, como o paradigma funcional e o paradigma orientado a aspectos. Novas e poderosas APIs foram implementadas nas últimas versões do Java, como a API de Streams (que dá uma “cara” mais “funcional” para a linguagem), a API Date and Time e a API de I/O.

O Java hoje também suporta recursos naturais a qualquer linguagem moderna que está entre as mais utilizadas do mundo, como expressões lambda, inferência de tipagem, princípios de pattern matching e template strings. O Java hoje também possui um ciclo mais acelerado de lançamento de versões, sendo que uma nova versão é lançada a cada cerca de 6 meses. Isso mostra o quão acelerado é o ritmo de inovação e transformação da linguagem.

O que são as linguagens funcionais?

Ultimamente, as linguagens ditas funcionais estão ganhando cada vez mais a atenção dos desenvolvedores em geral. Já não é tão difícil encontrarmos projetos que utilizem uma linguagem funcional para resolver problemas que envolvem principalmente paralelismo e/ou processamento de quantidades grandes de dados. As ideias fundamentadas pelo paradigma funcional dão essa “vocação” para o paralelismo e processamento de quantidades extensas de dados para estas linguagens ditas funcionais.
Mas, no final das contas, o que torna as linguagens funcionais tão adequadas para a resolução destes tipos de problemas? E quais são os contrapontos entre o paradigma funcional e o paradigma orientado a objetos? Será que o paradigma funcional pode substituir completamente o paradigma orientado a objetos?

O que é o paradigma funcional?

Antes de qualquer coisa: não, o paradigma funcional não tem esse nome porque ele funciona.

O paradigma funcional possui esse nome porque ele está fortemente fundamentado nos conceitos das funções matemáticas.
Mas calma! Muita gente já “torce o nariz” ao ouvir falar de matemática, mas os conceitos envolvidos na descrição do paradigma funcional podem ser mais tranquilos de se entender do que você imagina.

Relembrando alguns conceitos de funções matemáticas

Vamos recapitular um pouco sobre uma função matemática. Uma função matemática tem essa aparência:

Se verificarmos, uma função matemática possui uma única entrada. Em uma função matemática, essa única entrada sofre um tipo de processamento, processamento este que retorna uma saída de qualquer maneira. No caso da função acima:

  • A entrada é definida por x;
  • O processamento é a elevação de x ao quadrado mais 3;
  • A saída é o resultado do processamento descrito acima.

Mais um exemplo: se entrarmos com o número 2 nessa função matemática, teremos a saída 7, pois 2^2 (4) + 3 é igual a 7.

Existem alguns detalhes importantes. A função acima, além de sempre retornar um resultado compulsoriamente, ela sempre retornará a mesma saída para uma determinada entrada. Por exemplo: podemos “chamar” esta função passando para ela a entrada 2 hoje, amanhã ou daqui 10 anos… Não importa: o resultado dela sempre será 7, independente da situação. Nós chamamos esta característica de determinismo. Por isso, dizemos que funções matemáticas em sua essência são determinísticas.
Outro fato interessante: funções matemáticas não possuem o conceito de escopo. Isso quer dizer que a entrada é processada e a saída correspondente é devolvida imediatamente. Não existem “variáveis” intermediárias que só podem ser acessadas dentro da função matemática: só existe a entrada e a saída.

Java - Fundamentos
Curso de Java - Fundamentos
CONHEÇA O CURSO

Trazendo conceitos de funções matemáticas para as linguagens de programação

O paradigma funcional se baseia fortemente nos conceitos de funções matemáticas que discutimos no tópico anterior. E, sendo um paradigma, não necessariamente precisa ser implementado com uma linguagem funcional…
Por exemplo, poderíamos reescrever a função matemática anterior com o seguinte código Java:

public int doFunction(int x){
    return (x * x) + 3;
}

System.out.println(doFunction(2)); // A saída será "7"!

Veja que, na função acima:

  • Temos uma única entrada;
  • Não existe o conceito de escopo, pelo menos não explicitamente (já que não existem variáveis criadas dentro do método doFunction());
  • O método sempre irá produzir uma saída;
  • O método é determinístico, pois ele irá sempre produzir a mesma saída para uma mesma entrada.

Sendo assim, conseguimos criar um código funcional, mesmo utilizando o Java, que não é uma linguagem essencialmente funcional.
Acima, ainda temos uma outra característica intrínseca ao paradigma funcional que é fantástica: a imutabilidade! Veja que, em nossa versão Java da função matemática, a entrada nunca é modificada: ela simplesmente sofre um processamento, produzindo uma saída. A saída produzida também nunca é modificada… Isso é fantástico, pois ao final, estamos quase que trabalhando com constantes o tempo inteiro.
Obviamente, o Java e outras linguagens majoritariamente orientadas a objeto não dão um suporte 100% para estes conceitos que descrevemos… Porém, se pegarmos linguagens majoritariamente funcionais, nós teremos estes princípios básicos levados mais à risca. Por exemplo: vamos considerar a reescrita desta função em F#, uma linguagen funcional:

let doFunction x = (x * x) + 3

let result = doFunction 2
printfn "Resultado: %i" result

Acima, temos a mesma função reescrita em uma linguagen funcional. Veja que os conceitos de ausência de escopo, massa de entrada e saída e determinismo são respeitados aqui. Aliás, se você tentar modificar a “variável” result (que aqui é chamada de binding), o compilador irá produzir um erro.

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Por que linguagens funcionais podem ser interessantes para paralelismo, assincronia e processamento de grandes quantidades de informações?

Nós estamos, em maioria, acostumados a escrever código orientado a objetos, e uma das premissas da orientação a objetos é a transição de estado: nós criamos variáveis e/ou objetos que mudam de conteúdo o tempo inteiro, fazendo com que o nosso código tome decisões em cima destas flutuações de estado que acontecem. Isso não existe dentro do paradigma funcional, tendo em vista o determinismo e a imutabilidade.
Quando estamos falando sobre o processamento de quantidades muito grandes de dados, tornar esse processamento assíncrono e paralelo é essencial. E isso pode se tornar um problema muito complicado quando falamos de transição de estado neste cenário. Um exemplo simples: quando criamos threads, uma thread não pode acessar o conteúdo que está sendo processado por outra thread. Quando precisamos que threads por alguma razão compartilhem alguma varíavel, nós acabamos precisando recorrer a patterns (como o famigerado singleton ). E no final, nós ainda precisamos nos preocupar em garantir que a modificação destes recursos compartilhados não irá ocorrer de maneira concorrente, com uma thread sobrescrevendo ou passando por cima do resultado de uma outra thread ao mesmo tempo. Para isso, precisamos recorrer a recursos como semáforos e monitores. Veja que, somente por termos um código baseado em transições de estados, nós precisamos recorrer a uma certa complexidade de código para garantir que tudo ocorra bem. Logicamente isso é factível, mas é extremamente trabalhoso.
Linguagens funcionais não possuem estes problemas, pois elas já trabalham com imutabilidade e determinismo nativamente. Imutabilidade e determinismo são pilares do paradigma funcional. Se não existem transições de estado, nós não teríamos este tipo de problema se utilizássemos uma linguagem funcional.

F# (F Sharp) - Fundamentos
Curso de F# (F Sharp) - Fundamentos
CONHEÇA O CURSO

Então devo chutar a orientação a objetos e aprender somente o paradigma funcional?

Não! Não faça isso!
O paradigma funcional também possui seus problemas… A curva de aprendizado tende a ser ligeiramente maior do que a curva do paradigma orientado a objetos, principalmente porque muitas pessoas já criam um “bloqueio” pela associação à matemática. Existem também alguns conceitos dentro do paradigma funcional que não são tão “naturais” de serem entendidos, como currying e monads. Sendo assim, a curva de aprendizado tende a ser um pouquinho mais íngreme.
Também temos o fato de que pouca coisa no mundo real é determinística: estamos falando das típicas situações de I/O. O acesso a uma tabela de um banco de dados, por exemplo, não pode ser determinístico: nós podemos tanto conseguir acessar a tabela como podemos em algum momento ter uma queda de conexão… Logicamente, as linguagens funcionais modernas são preparadas para também lidar com situações não-determinísticas, mas cada uma delas pode tratar de maneira diferente, o que contribui para aumentar um pouco mais o processo de aprendizagem e aplicação correta em situações do dia-a-dia.
Existe também a questão de legibilidade do código. Eu particularmente observo que é mais fácil produzir código ilegível em linguagens funcionais do que em linguagens orientadas a objeto. Tudo bem, um desenvolvedor iniciante (ou um desenvolvedor infelizmente ruim) irá produzir código ruim de qualquer maneira… Mas observo que as linguagens funcionais dão uma “forcinha” a mais nesse sentido por diferentes fatores: sintaxe propriamente dita das linguagens que implementam este paradigma, a maior ocorrência da não-observância dos pilares funcionais, entre outros.
Por isso, pelo menos para mim, o ideal é: aprenda e domine os dois paradigmas. Ambos serão muito úteis, dependendo-se da situação. Precisa criar uma página de cadastro de algo? Provavelmente a orientação a objetos pode ser mais aplicável… Precisa gerar um CSV a partir de um conjunto grande de dados? Provavelmente uma linguagem ou até mesmo uma abordagem funcional será mais aplicável. Aqui vale o velho mantra: não existe bala de prata no mundo de desenvolvimento de software. Aprenda os dois paradigmas e seja feliz!

3 linguagens de programação que continuam em alta

Você provavelmente já se pegou pensando em qual linguagem você deve focar seus estudos. Seja se você está iniciando ou não, é sempre bom ver o que o mercado está pedindo. Claro que não devemos avaliar apenas o mercado, mas também suas preferências. A ideia é fazer uma junção dessas duas coisas: escolher uma linguagem em alta, mas que dentre elas, você escolha a que mais se identificar.

No começo deste ano fizemos um post sobre as linguagens promissoras para se estudar neste ano. Mas como na área de TI tudo muda muito rápido, será que agora, perto do final do ano, essas linguagens ainda estão no topo? Vamos focar hoje nas 3 principais do momento.

1) JavaScript

Assim como no começo do ano, o JavaScript aparece em primeiro lugar. Como é uma linguagem dinâmica pode ser utilizada para várias coisas. Temos um post que aborda justamente isso: O que se pode fazer com JavaScript hoje em dia?

O site Stack Overflow sempre realiza uma pesquisa para obter estatísticas da comunidade de desenvolvedores. E nas tecnologias mais populares, está ela, em primeiro lugar, com uma porcentagem de 69,8%.

O GitHub (site de compartilhamento de código) também diz que o JavaScript é o mais utilizado.

Como podemos ver acima, em segundo aparece a linguagem Python, que veremos a seguir.

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

2) Python

Desde o começo do ano ela era uma das linguagens mais promissoras, e ela ainda está no pódio. O Python é uma linguagem poderosa e que cada vez mais ganha popularidade em meio aos desenvolvedores.

Podendo ser utilizada por uma variedade de tarefas, desde desenvolvimento web, aprendizado de máquina, análise de dados e muitas outras.

Ainda na pesquisa do Stack Overflow, quase 40% dos usuários utilizam Python em seus projetos. E ainda tem mais: segundo o site TIOBE, podemos ver como o Python tem crescido.

Python - Fundamentos
Curso de Python - Fundamentos
CONHEÇA O CURSO

3) Java

Muitas pessoas quando pensam em estudar uma linguagem, já pensam logo no Java. Se você gostar, porque não? Apesar de não ter aparecido como uma das linguagens mais promissoras para este ano, o Java voltou a ser um dos centros a partir de julho/2018.

Como é uma linguagem de programação bem versátil, você pode utilizá-la para diversas finalidades como desktop, web e até mobile. Para tudo isso, o Java atenderá suas necessidades.

Java - Fundamentos
Curso de Java - Fundamentos
CONHEÇA O CURSO

Concluindo

Agora você pode estar se perguntando… “Ok, então eu tenho que escolher uma dessas três linguagens?” e a resposta é: não exatamente…

Por que não aprender as três? Essas são as linguagens mais bem classificadas pelos sites como pudemos ver acima.

Quanto maior o seu conhecimento, tanto na linguagem em si quanto na quantidade, pode abrir um leque de oportunidades. Você pode estudar uma por vez, para poder levar sua carreira a um próximo nível.

Até a próxima! 😊

Qual linguagem devo aprender primeiro?

Quando iniciamos na área de TI, ficamos com muitas dúvidas sobre como entrar na área de programação, sobre qual é o primeiro passo etc. É comum esse tipo de dúvida pois temos hoje uma infinidade de opções, seja de desenvolvimento desktop, web e mobile.

Não existe uma linguagem que você tem que aprender primeiro, o que temos são bases que nos auxiliam. É que veremos a seguir, independente da linguagem que formos escolher depois.

1. Lógica de Programação

Esse é o primeiro passo e muitas pessoas não dão o devido valor ao estudar a lógica de programação. A lógica é o primeiro conhecimento que você deve procurar adquirir, funcionando como um pré-requisito para se aprender qualquer linguagem. Aí você pode até pensar que não se tem utilidade em aprender lógica já que todos nós já temos essa habilidade de raciocínio lógico. Mas você deve saber também que devemos aprimorar e desenvolver cada vez mais nossa lógica, ainda mais na programação que devemos passar nossa lógica de uma forma que o computador entenda.

Por ser mais teoria pode parecer muito chato, mas você verá a utilidade dela mais para frente e, se você não tiver conhecimentos básicos nesse quesito, poderá ter dificuldades na hora de colocar a mão na massa com uma linguagem de programação.

Lógica de Programação Completo
Curso de Lógica de Programação Completo
CONHEÇA O CURSO

2. Lógica Orientada a Objetos

A maioria das linguagens de programação são orientadas a objetos ou implementam orientação a objetos (C#, Java, PHP, Python, Ruby entre outras), portanto se você deseja aprender alguma delas é necessário trabalhar a lógica voltada a orientação a objetos.

Aprender e compreender a orientação a objetos é importante para que seu código fique de acordo com o paradigma orientado a objetos.

Vale lembrar que este estudo é voltado a lógica com foco na orientação a objetos, ele não substitui os conhecimentos adquiridos na lógica de programação.

Lógica Orientada a Objetos Completo
Curso de Lógica Orientada a Objetos Completo
CONHEÇA O CURSO

3. HTML5 e CSS

HTML e CSS são conhecimentos que todo desenvolvedor deve saber. Uma hora ou outra você irá precisar deles. Eles funcionam como uma porta de entrada no desenvolvimento web. O HTML e o CSS são utilizados para criar páginas web e atuam de forma complementar. Todos os sites utilizam HTML e CSS de uma forma ou de outra.

O HTML é uma linguagem muito fácil de se aprender e em pouco tempo você já poderá criar um website com facilidade. Com um pouquinho mais de tempo e dedicação, você poderá estilizar suas páginas utilizando o CSS, conseguindo um resultado mais profissional.

HTML5 e CSS3 - Desenvolvimento web Básico
Curso de HTML5 e CSS3 - Desenvolvimento web Básico
CONHEÇA O CURSO

4. Linguagens back-end

Depois de aprender os tópicos anteriores, você já tem conhecimentos suficientes para escolher uma linguagem back-end. Você pode escolher a linguagem que quiser para estudar. Alguns exemplos de linguagens back-end são Java, C++, C#, PHP, Ruby, Python, Go, dentre outras…

Se seu foco for desenvolver aplicativos ou games, saiba que muitas vezes saber uma determinada linguagem é essencial. Por exemplo, se você quer desenvolver aplicativos cross-platform você pode utilizar o Xamarin, mas a base dele é em C#.

Para o desenvolvimento de games, utilizando o Unity, você também deverá saber a linguagem C#. Não são todos que tem alguma linguagem por trás, por isso é importante verificar antes se a sua escolha tem, se tiver se torna essencial aprendê-la.

Você pode ver a relação dos cursos de back-end que ministramos clicando aqui.

5. Banco de dados

Conhecer pelo menos um banco de dados é importante. Assim você pode até fazer com que suas aplicações web se integrem com o banco. O SQL é uma linguagem universal e comum para todos os bancos de dados relacionais. A partir dele podemos ter outras variações do SQL que são específicas de cada banco: o Oracle e o MySQL têm o plSQL, o SQL Server tem o T-SQL e o PostGre tem o pgSQL. Por isso, aprender o SQL se torna um requisito.

Você pode ver a relação dos cursos de bancos de dados que ministramos clicando aqui.

Concluindo

Esses são alguns tópicos que podem te ajudar caso você não saiba por onde começar. Começar direto em uma linguagem pode não ser uma boa experiência, muitas vezes pular etapas pode fazer com que a pessoa que está entrando na área desanime caso não consiga entender coisa nenhuma. Com esses passos esperamos que você possa ter um melhor aproveitamento em cada quesito. Boa sorte!

5 linguagens de programação promissoras para se estudar em 2018

Que tal aproveitar esse início de ano e traçar uma meta de estudos envolvendo as linguagens mais promissoras para esse ano?

Se você é iniciante, é uma ótima maneira de começar para poder estar apto ao que o mercado está pedindo. Para você que já é da área, nunca é demais estudar e se aprimorar nas linguagens que você já conhece ou se aventurar em uma nova, pois sabemos que em nossa área o estudo é constante… então vamos começar?

JavaScript

O JavaScript é uma linguagem que está praticamente em tudo! Esse já é um bom motivo para o qual você não estará perdendo tempo estudando ele. Vai chegar uma hora que você precisará saber nem que seja um pouco. Além disso, ele funciona tanto do lado do cliente como do servidor, assim você também poderá criar aplicativos e até executá-los em dispositivos IoT (Internet das coisas).

O JavaScript é uma linguagem de programação universal e continuará sendo. Caso você já domine ele, pode dar uma olhada no TypeScript, um superset de JavaScript.

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO
TypeScript - Primeiros Passos
Curso de TypeScript - Primeiros Passos
CONHEÇA O CURSO

Python

O Python sempre foi uma linguagem popular para se aprender a programar, justamente por ter uma sintaxe bem clara e fácil de se aprender. Recentemente lançamos um post sobre ele especialmente para quem quer iniciar: “Como começar com Python“, se você ainda não viu dá uma olhada lá.

Além do Python ser uma ótima linguagem de programação para iniciantes, ela também se aplica para programadores mais experientes, pois é uma linguagem vastamente utilizada no mercado de trabalho.

O Python é uma linguagem que está em expansão principalmente na área de Machine Learning (com R), além de poder ser utilizada com vários propósitos. É possível desenvolver desde scripts até aplicações web e mobile.

Python Básico
Curso de Python Básico
CONHEÇA O CURSO

C#

O C# é uma das linguagens de programação mais modernas e populares hoje em dia, e esse ano não será diferente. Você pode utilizá-la para desenvolver para plataformas web, dispositivos móveis e aplicações desktop.

Com a praticidade dessa linguagem, você pode, de forma relativamente fácil, desenvolver desde projetos mais simples até projetos complexos e multiplataforma.

Além disso, o C# é usado em Unity, então se você deseja se aprofundar na área de games será realmente valioso, para que assim você possa se aventurar nas experiências de AR (Realidade Aumentada) e VR (Realidade Virtual).

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Go

O Go é uma linguagem que vem subindo rapidamente sua popularidade. É uma linguagem simples, mas muito poderosa.Ela foi criada pela Google com o objetivo de ser uma linguagem de programação ideal e você poderá se surpreender do tanto que essa linguagem pode atender as suas expectativas.

Se você já tiver uma base de conhecimentos em programação, se sentirá mais confortável em aprender Go.

Go Básico
Curso de Go Básico
CONHEÇA O CURSO

Kotlin com Android

O Kotlin é uma linguagem recente, onde você pode desenvolver aplicativos para Android com ela. Agora, a Kotlin é a linguagem oficial suportada na plataforma Android, se tornando uma substituição gradual ao Java.

Com o apoio do Google e JetBrains, não é surpresa que o Kotlin tenha tido um aumento tão grande em popularidade. Então se você deseja criar aplicativos para Android, já pode começar a estudar o Kotlin.

Kotlin com Android - Primeiros Passos
Curso de Kotlin com Android - Primeiros Passos
CONHEÇA O CURSO

Concluindo

Vale lembrar que essas são as linguagens que julgamos promissoras para este ano. Se você gosta e/ou precisa aprender alguma outra não há problema nenhum, o importante é o estudo constante. 😉

O que é e como começar com C# (C Sharp)?

Atualmente são tantas as opções de linguagens de programação à nossa disposição que ficamos perdidos em qual estudar. Para lhe ajudar nessa escolha, vamos apresentar a linguagem C#.

O C# é uma linguagem de programação muito popular, sendo uma excelente escolha devido a sua baixa curva de aprendizado e simplicidade (mas sem deixar de ser uma linguagem poderosa). Além disso, ela é a linguagem principal do .NET Framework, o framework para desenvolvimento da Microsoft.

Se você não tem nenhum conhecimento sobre programação, não tem problema: o C# é ótimo para você começar seus estudos, pois aprendê-lo é muito mais fácil do que parece. Caso você já tenha uma bagagem em alguma linguagem (como por exemplo Java ou C++), você não encontrará problemas em se ambientar com ele.

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

O que é C#?

O C# é uma linguagem de programação multiparadigma criada pela Microsoft, sendo a principal da plataforma .NET. Por ser uma linguagem que suporta, entre outros paradigmas, a orientação à objetos, ela suporta conceitos comuns como encapsulamento, herança e polimorfismo. Trata-se também de uma linguagem fortemente tipada e case-sensitive, ou seja, faz diferenciação entre letras minúsculas e maiúsculas.

O C# veio para facilitar o processo de desenvolvimento, tendo inúmeros recursos que proporcionam uma grande produtividade para os desenvolvedores que a utilizam.

O que pode ser feito?

O C# é uma linguagem multiplataforma. Sendo assim, você pode utilizá-la para desenvolver para plataformas web, dispositivos móveis e aplicações desktop. Com a praticidade dessa linguagem, você pode, de forma relativamente fácil, desenvolver desde projetos mais simples até projetos complexos e multiplataforma.

Sintaxe do C#(C Sharp)

A sintaxe do C# é simples. Veja o tradicional “Hello World”:

public class Exemplo
{
    public static void Main()
      {
        System.Console.WriteLine("Hello World!");
      }
 }

Utilizar estruturas de tomada de decisão com C# é muito fácil. Veja o tradicional “if/else”.

int idade = 18;
if ( idade >= 18 )
{
    Console.WriteLine( "Você é maior de idade“ );
}
else
{
    Console.WriteLine( "Você é menor de idade" );
}

Você também pode utilizar estruturas de repetição, como a estrutura “for”, sem problemas… Veja o código abaixo, onde fazemos uma verificação e imprimimos somente os números que forem menores ou iguais a 5:

class Exemplo
{
    static void Main() 
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine(i);
        }
    }
}

Mercado de trabalho

Você pode escolher uma linguagem de programação que mais te agrade, mas também é importante observar como anda o mercado de trabalho. O C# é uma das linguagens mais utilizadas no mundo e o mercado está em alta para essa linguagem.

Segundo o site TIOBE (Programming Community Index Definition), o C# é uma das 5 linguagens mais utilizadas no mundo! Além disso, grandes empresas utilizam o C# em seus produtos, empresas como Microsoft (em uma infinidade de soluções: desde soluções Web até soluções mobile multiplataforma através do Xamarin), Amazon, StackOverflow (toda a stack web do StackOverflow é construída em cima de C# e .NET) e nós aqui no TreinaWeb (algumas de nossas aplicações foram escritas com C# e .NET Framework Full e .NET Core). Você pode até mesmo desenvolver jogos com C# através da Unity.

Então, se você estudá-la e se especializar, certamente não ficará fora do mercado. =D

Como aprender C#?

Aqui no TreinaWeb temos uma trilha voltada para C#. O curso de “C# Básico” é ótimo para você dar os primeiros passos nessa linguagem de fácil compreensão e com recursos poderosos. No curso básico, além de você aprender todos os conceitos básicos dessa linguagem, você acompanhará a construção de um projeto com todo o seu passo a passo.

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Conheça nossa metodologia

Nosso ambiente de aprendizagem é 100% online. Nossa metodologia de ensino é baseada em vídeo aulas, apostilas, exercícios aula-a-aula e exemplos completos. Você estuda no seu tempo e ao final pode baixar o seu certificado digital ou solicitar o certificado impresso.

Na parte escrita, fornecemos um material totalmente atualizado e completo para que você possa usufruir do conteúdo, utilizando-se de textos e imagens. Já as vídeo-aulas são bem explicativas e práticas, abordando todo o conteúdo passo-a-passo, para que você entenda tudo da melhor maneira possível.

Além disso, você encontrará exercícios para poder fixar, praticar e aplicar todo o conteúdo aprendido. São exercícios que são propostos em cada aula do curso. Eles podem variar entre alguns formatos, como por exemplo questões de escolha única, questões de múltipla escolha e complemento de trechos de código.

Se ainda assim você tiver alguma dúvida, você poderá pedir ajuda aos nossos professores através de tickets de atendimento. Funciona como um canal direto entre você e o professor, onde você poderá realizar perguntas que serão respondidas muito brevemente!

Além disso, ainda pelo sistema suporte, você também poderá consultar todas as perguntas que já foram respondidas a outros alunos! =)

Quais conhecimentos preciso ter para iniciar este curso?

O curso é recomendado para você iniciar seus estudos na linguagem C#, no entanto, é interessante saber as bases necessárias para aprender qualquer linguagem de programação: “Lógica de Programação” e “Lógica de Programação Orientada a Objetos”.

Também ministramos esses cursos:

Lógica de Programação Completo
Curso de Lógica de Programação Completo
CONHEÇA O CURSO
Lógica Orientada a Objetos Completo
Curso de Lógica Orientada a Objetos Completo
CONHEÇA O CURSO

Gostou do que viu?

Se entusiasmou com a linguagem? Gostaria de conhecê-la com mais detalhes? Sim, você pode dar uma espiadinha. Acesse o link do curso de C# Básico e veja algumas aulas de exemplo. =D

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Bons estudos!

Top 5 das linguagens de programação mais populares de 2017

O ano está acabando e você, sabe quais foram as linguagens de programação mais utilizadas / populares neste ano?

Isso é algo interessante de se saber, pode te ajudar a escolher uma linguagem para estudar. Claro que isso varia da região que você mora, do que a sua empresa geralmente usa, dentre outros fatores.

Vamos tomar como base dois sites que avaliam a popularidade das linguagens, o TIOBE e o IEEE Spectrum, e vamos listar aqui as cinco principais do ranking.

Nos dois sites houveram similaridade nas linguagens, porém, em posições diferentes, como podemos ver mais pra frente.

O primeiro ranking é do site TIOBE Index, mantido por uma empresa de mesmo nome, onde todo mês o ranking é atualizado.

Em quesito de posição, as primeiras linguagens não tiveram muita diferença de colocação nos últimos meses. Podemos ver também uma comparação entre o mês de novembro deste ano em relação a novembro do ano passado, onde somente as linguagens Python e C# trocaram de posição.

Ranking - Linguagens de Programação - TIOBE

O segundo ranking é do site IEEE Spectrum, uma revista de tecnologia, onde os rankings são criados por ponderação e combinação de 12 métricas de 10 fontes. Neste site você pode ver o ranking das linguagens separados por segmentos como web, mobile, enterprise, desktop, entre outros.

Ranking - Linguagens de Programação - IEEE

Agora vamos abordar sobre as cinco linguagens mais utilizadas. Claro que tem muitas outras que também são bem utilizadas, mas para este artigo não ficar extenso, vamos limitar dessa maneira a nossa avaliação.

Como nos rankings as posições estão diferentes, vamos abordar por ordem alfabética.

C

O C é uma linguagem de programação voltada ao desenvolvimento de sistemas embarcados. Por ser muito rápido e poderoso, ele é muito requisitado principalmente no ramo de telecomunicações. Com ele podem ser desenvolvidas várias coisas como sistemas de usuário, sistemas operacionais e até mesmo outras linguagens de programação.

C Básico
Curso de C Básico
CONHEÇA O CURSO

C++

O C++ é um aprimoramento da linguagem C, mas com elementos de orientação a objetos. É recomendada principalmente para desenvolvimento de sistemas para desktop e games. Assim como a linguagem C, ela pode ser utilizada para desenvolvimento de sistemas embarcados, sistemas operacionais etc.

C++ Básico
Curso de C++ Básico
CONHEÇA O CURSO

C#

O C# é a principal linguagem de programação da Microsoft, fazendo parte do framework .NET, onde você pode criar desde serviços e plataformas web como também aplicativos para celular.

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Java

Não é segredo para ninguém que o Java é a linguagem de programação orientada a objetos mais utilizada, seja para desenvolvimento web ou mobile.

Java - Fundamentos
Curso de Java - Fundamentos
CONHEÇA O CURSO

Python

O Python é uma linguagem bastante utilizada por ser orientada a objetos, multiplataforma e de alto nível. Ela pode ser utilizada em aplicações web, inteligência artificial, computação científica. Com o Python você consegue atingir praticamente todo o mercado de programação: web, mineração, controle de máquina, servidor, desktop etc.

Python - Fundamentos
Curso de Python - Fundamentos
CONHEÇA O CURSO

Imutabilidade de objetos no PHP

Imutabilidade é uma característica forte nas linguagens funcionais, onde a alteração de estado não é frequente e, quando ela acontece, é controlada. Há de se observar que, o PHP, uma linguagem multi-paradigma e fracamente tipada, não implementa (ainda) nenhum mecanismo padrão para lidar com imutabilidade.

Linguagens de programação são naturalmente opinativas e é difícil fazer com que elas se comportem de uma determinada forma se não foram cultura e tecnicamente desenvolvidas para servir aquele propósito específico. Por exemplo, não adianta eu querer acessar diretamente um endereço da memória usando o PHP, a linguagem não nasceu com essa premissa, não é uma linguagem para se desenvolver sistemas embarcados, por exemplo. Consegue perceber? As linguagens possuem “culturas” e características e, quando escolhemos uma delas, temos que nos “encaixar” nesses aspectos.

Disso, infere-se que, por mais que tentemos, programar em PHP nunca será 100% thread safe, será sempre mutável. No entanto, podemos usar características da linguagem a fim de emular diferentes comportamentos e características, dentre elas, a imutabilidade (mesmo que parcial, se estritamente avaliado). Há de se destacar que, sim, é possível programar usando o paradigma funcional em PHP desde a versão 5.3 com a introdução de Lambda’s e Closure’s.

PHP Básico
Curso de PHP Básico
CONHEÇA O CURSO

Imutabilidade

Um objeto imutável é, por definição, aquele que não pode ter o seu estado alterado depois da sua criação.

Abrindo um parênteses aqui, uma constante é a única estrutura realmente imutável no PHP. Tanto as constantes do escopo global quanto as constantes de classe garantem que o valor declarado permanecerá estático durante todo o ciclo de vida de execução do script.

class FooClass
{
    const PI = 3.14159265359;

    public function __construct()
    {
        static::PI = 3.14; // FATAL ERROR syntax error, unexpected '=' on line number 7
    }
}

$foo = new FooClass(); // Error

Mas, constantes só trabalham com valores escalares (int, string, float, boolean), nulos e arrays (um tipo composto).

Objetos mutáveis

A alternância de estados é uma das características mais fortes do paradigma imperativo, logo, essa também é uma característica evidente no paradigma orientado a objetos (que é imperativo). Há muitos benefícios, claro. Os princípios SOLID são conceitualmente incríveis, aumentam a legibilidade e a manutenibilidade dos softwares. Mas, às vezes, lidar com centenas de objetos pode nos levar à perigosas armadilhas.

Um problema que a mutabilidade pode nos trazer é o efeito colateral. Um código mutável fica a mercê de alterações não previstas do seu estado, então, num determinado ciclo da execução ele pode ter o estado A e em outro ciclo o estado B, ele fica suscetível à violações.

Vamos a um exemplo didático? Considere uma classe para trabalhar com simples cálculos monetários:

class Money
{
    /**
     * @var mixed
     */
    private $amount;

    /**
     * Money constructor.
     * @param $amount
     */
    public function __construct($amount)
    {
        $this->amount = $amount;
    }

    /**
     * @param $amount
     * @return $this
     */
    public function plus($amount)
    {
        $this->amount += $amount;

        return $this;
    }

    /**
     * @param $amount
     * @return $this
     */
    public function sub($amount)
    {
        $this->amount -= $amount;

        return $this;
    }

    /**
     * @return string
     */
    public function amount()
    {
        return $this->amount;
    }
}

Suponhamos, então, que temos uma classe Payment que utiliza a Money:

class Payment
{
    /**
     * @param $valor
     * @return array
     */
    public function process($valor)
    {
        $valorBruto = new Money($valor);

        // TODO

        $valorLiquido = $valorBruto->sub(20);

        // TODO

        return [
            'valor_bruto' => $valorBruto->amount(),
            'valor_liquido' => $valorLiquido->amount(),
        ];
    }
}

Integrando e utilizando o exemplo:

$payment = new Payment();
$result = $payment->process(100);

Avaliando a classe Payment subtende-se como senso comum que teremos armazenado na variável $result o seguinte array:

[
    'valor_bruto' => 100,
    'valor_liquido' => 80,
]

Uma vez que a entrada foi 100 e o valor líquido é o valor bruto menos 20. Certo?

Mas não é o que acontece. O resultado é:

[
    'valor_bruto' => 80,
    'valor_liquido' => 80,
]

Se você programa em PHP regularmente sabe que, quando atribuímos um objeto a uma variável, uma referência desse objeto é nos retornada. Isso quer dizer, no nosso exemplo, tanto a variável $valorBruto quanto a $valorLiquido trabalham com exatamente o mesmo endereço de objeto na memória, por isso tivemos esse efeito colateral do valor bruto ser 80 e não 100, como esperado.

Não teríamos tido tal problema se no exemplo tivéssemos explicitamente clonado o objeto $valorBruto usando o operador clone, assim:

$valorLiquido = clone $valorBruto;
$valorLiquido->sub(20);

Uma clonagem de um objeto significa a cópia de toda a estrutura interna dele, mas em outro endereço de memória. É um objeto igual em atributos / características, mas diferente.

Se alterarmos o objeto $valorBruto isso não será refletido no $valorLiquido e vice versa. São objetos distintos, moram em outro “endereço”, mesmo que iguais (no sentido de ser, ambos são do tipo Money).

Mas, que fique claro, isso não tira o fato de que esses objetos continuarão sendo suscetíveis à consecutivas mudanças de estado no ciclo de execução. É agora que entra a parte que “toca” o objetivo desse artigo.

PHP Intermediário
Curso de PHP Intermediário
CONHEÇA O CURSO

Objetos imutáveis

Não tem como definirmos um objeto essencialmente 100% imutável no PHP, ele pode ser violado por reflexão, métodos mágicos, bindings de funções, truques com referências etc. Por exemplo, um objeto pode ser alterado pelos métodos mágicos __set(), __unset(), no uso das funções serialize() e unserialize().

No entanto, podemos chegar bem próximos disso, seguindo algumas regras:

  • Declare a classe como sendo final (a impede de ser estendida);
  • Declare as propriedades como sendo privadas;
  • Evite métodos setters, no lugar, utilize o construtor da classe para receber o valor.
  • Quando for preciso modificar o valor do objeto, retorne uma cópia (um clone) dele, nunca ele próprio;
  • Evite que esse objeto receba outro objeto e, caso seja preciso, ele também precisa ser imutável;

Vamos transformar a nossa classe Money em uma “classe imutável” usando os recursos que temos disponíveis no PHP?

final class Money
{
    /**
     * @var mixed
     */
    private $amount;

    /**
     * Money constructor.
     * @param $amount
     */
    public function __construct($amount)
    {
        if( ! is_numeric($amount)) {
            throw new \InvalidArgumentException('The amount must be numeric.');
        }

        $this->amount = $amount;
    }

    /**
     * @param $amount
     * @return Money
     */
    public function plus($amount)
    {
        return new self($this->amount + $amount);
    }

    /**
     * @param $amount
     * @return $this
     */
    public function sub($amount)
    {
        return new self($this->amount - $amount);
    }

    /**
     * @return string
     */
    public function amount()
    {
        return $this->amount;
    }
}

O que fizemos:

  • A classe agora é final;
  • Garantimos no construtor receber só o tipo de valor que queremos;
  • Nos métodos plus() e sub(), ao invés de alterarmos o objeto atual, retornamos sempre um novo objeto com o valor da operação em questão. Essa é a parte mais importante.
  • O estado de $amount agora estará protegido, ademais, é um atributo privado.

Observe os métodos plus() e sub():

/**
 * @param $amount
 * @return Money
 */
public function plus($amount)
{
    return new self($this->amount + $amount);
}

/**
 * @param $amount
 * @return $this
 */
public function sub($amount)
{
    return new self($this->amount - $amount);
}

Eles sempre vão retornar uma nova instância de Money e isso faz com os nossos objetos não tenham seus estados alterados durante o ciclo de execução.

Observe que, se queremos um objeto imutável, as alterações realizadas nele precisam criar uma nova estrutura que compartilhe características da original. Em termos gerais, tudo o que for invocado no objeto não pode alterar o estado dele, ao contrário disso, deve-se retornar o resultado dessa transformação em uma nova estrutura.

Vamos testar isso na prática?

$valor1 = new Money(20);
$valor1->sub(10);

echo $valor1->amount();

Qual será o valor da impressão?

Será 20. Estamos subtraindo 10, mas o método sub() nos retorna um novo objeto. Não estamos “tocando” no objeto $valor1. Ele permaneceu intacto.

Isso pode ser constatado se compararmos os dois objetos, veremos que são diferentes:

$valor1 = new Money(20);
$valor2 = $valor1->sub(10);

if($valor1 === $valor2) {
    echo 'São iguais';
} else {
    echo 'São diferentes.';
}

O resultado será:

São diferentes.

Alguns dos benefícios da imutabilidade:

  • A aplicação se torna um pouco mais previsível, já que o estado dos objetos não alteram durante a execução;
  • Fica mais fácil identificar onde determinado problema aconteceu, já que não há variáveis compartilhando a referência para o mesmo objeto;

Com essa alteração, você pode voltar a testar a primeira versão da classe Payment:

class Payment
{
    /**
     * @param $valor
     * @return array
     */
    public function process($valor)
    {
        $valorBruto = new Money($valor);

        // TODO

        $valorLiquido = $valorBruto->sub(20);

        // TODO

        return [
            'valor_bruto' => $valorBruto->amount(),
            'valor_liquido' => $valorLiquido->amount(),
        ];
    }
}

O resultado será:

[
    'valor_bruto' => 100,
    'valor_liquido' => 80,
]

Sem surpresas.

RFC: Immutable classes and properties

Há um RFC aberto para o PHP que discute a inclusão de classes e propriedades imutáveis no PHP. Se aprovado para alguma futura versão, teremos uma sintaxe assim:

immutable class Email
{
  public $email;

  public function __construct ($email)
  {
    // validation

    $this->email = $email;
  }
}

$email = new Email("foo@php.net");
$emailRef = &$email->email;
$emailRef = "bar@php.net" // Call will result in Fatal Error

Observe que, mesmo esse Value Object tendo o atributo $email púbico não é possível, nem fazendo um truque com referência, alterá-lo. Isso torna menos verboso a construção objetos imutáveis e sem a necessidade de terem seus membros protegidos, além de garantir uma maior segurança (tira do desenvolvedor ter que cuidar de tais detalhes de implementação).

Aproveitando a deixa, temos na standard library do PHP uma classe chamada DateTimeImmutable para trabalhar com data e hora. Um objeto dessa classe nunca têm o estado modificado, ao contrário disso, uma nova instância é sempre retornada (como fizemos com a classe Money).

Concluindo

Há situações onde o uso de objetos imutáveis são essenciais para se garantir integridade ou até mesmo um comportamento previsível. Em DDD o uso de Value Objects (que são imutáveis por essência) é bastante encorajado. Naturalmente você se deparará com esse conceito quando lidar com programação reativa com concorrências ou com qualquer outra característica da programação funcional.

Um abraço!

PHP Avançado
Curso de PHP Avançado
CONHEÇA O CURSO

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200