<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucas Cavalcante</title>
    <description>The latest articles on DEV Community by Lucas Cavalcante (@lucascavalcante).</description>
    <link>https://dev.to/lucascavalcante</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F185469%2F0298a109-8514-4dcc-aca9-a29317416029.jpeg</url>
      <title>DEV Community: Lucas Cavalcante</title>
      <link>https://dev.to/lucascavalcante</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucascavalcante"/>
    <language>en</language>
    <item>
      <title>Mas afinal, o que significa escalar a aplicação?</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 19 May 2021 22:49:27 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/mas-afinal-o-que-e-significa-escalar-a-aplicacao-4kc7</link>
      <guid>https://dev.to/lucascavalcante/mas-afinal-o-que-e-significa-escalar-a-aplicacao-4kc7</guid>
      <description>&lt;p&gt;Resolvi criar este post com o objetivo de destrinchar em pequenas partes o macro-conceito de "escalar a aplicação".&lt;/p&gt;

&lt;p&gt;Hoje em dia, ouvimos muito falar sobre criação de aplicações estáveis e escaláveis, que sejam tolerante à falhas, que façam balanceamento de carga, etc. Para quem já se perdeu na parte de "aplicações estáveis..." o resto já começa a não fazer nenhum sentido.&lt;/p&gt;

&lt;p&gt;Então, vamos lá começar a destrinchar essa sopa de palavras e tentar deixar os conceitos mais claros e acessíveis para todas as pessoas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura Tradicional
&lt;/h2&gt;

&lt;p&gt;Antes de começarmos a falar de uma arquitetura escalável, vamos entender como que funciona uma arquitetura tradicional, que não leva em conta variáveis de escala.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0aj1rdu04gjnpwlp2pt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0aj1rdu04gjnpwlp2pt.png" alt="Arquitetura Tradicional"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem, temos o clássico exemplo de arquitetura cliente-servidor. Onde tudo fica hospedado em um servidor, com uma estrutura básica contendo um servidor web (como o Apache, IIS, etc) e um banco de dados (como o MySQL, MongoDB, etc).&lt;/p&gt;

&lt;p&gt;Esse servidor fica aguardando alguma requisição vinda de algum cliente para processar e devolver a este mesmo cliente o resultado esperado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura Escalável
&lt;/h2&gt;

&lt;p&gt;A arquitetura escalável é focada em resolver problemas de sobrecarga de acessos e, a partir daí, gerenciar melhor os recursos para evitar um custo altíssimo com toda essa estrutura que podemos configurar.&lt;/p&gt;

&lt;p&gt;Quanto mais a sua aplicação ganha usuários, maior será a quantidade de requisições que ela irá receber simultaneamente. E quanto maior for esse número, maior terá que ser sua preocupação com a infraestrutura em termos de dimensionamento (escala).&lt;/p&gt;

&lt;p&gt;E quando falamos de dimensionamento, temos 2 tipos conhecidos: vertical e horizontal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimensionamento Vertical&lt;/strong&gt; (Vertical Scaling)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57d9ygvhx9k15ut4sih6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57d9ygvhx9k15ut4sih6.png" alt="Vertical Scaling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em linhas gerais, quando falamos em "escalar verticalmente", significa que vamos aumentar os recursos do servidor para aguentar mais requisições. Mas é praticamente a mesma arquitetura que vimos no modelo tradicional.&lt;/p&gt;

&lt;p&gt;Está estourando a memória? Aumenta a memória!&lt;/p&gt;

&lt;p&gt;Está travando os processos? Aumenta os núcleos do processador!&lt;/p&gt;

&lt;p&gt;Não preciso nem dizer que esse tipo de solução não vai resolver todos os nossos problemas, né? Já pensou se seu servidor já está com 32 núcleos e 128 GB de memória e ainda continua estourando memória e travando os processos? Se a gente continuar escalando verticalmente, a conta vai sair muito cara e só resolverá temporariamente até precisar escalar novamente, e por aí vai!&lt;/p&gt;

&lt;p&gt;Além disso, o dimensionamento vertical nos traz outro problema: não é tolerante à falhas! Se o servidor cair, a aplicação irá fora do ar até que alguém resolva o problema.&lt;/p&gt;

&lt;p&gt;Com esse problemas, vamos ao outro tipo de dimensionamento: o horizontal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimensionamento Horizontal&lt;/strong&gt; (Horizontal Scaling)&lt;/p&gt;

&lt;p&gt;Os problemas citados anteriormente podem ser resolvidos agora. Afinal, como poderemos aceitar milhares/milhões de requsições sem afetar nossa infra?&lt;/p&gt;

&lt;p&gt;Resposta curta: instâncias!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti9fc5ib8s56zh0ott3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti9fc5ib8s56zh0ott3a.png" alt="Horizontal Scaling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tanto para o servidor, como para o banco de dados, podemos criar instâncias que irão receber o tráfego de acordo com a demanda.&lt;/p&gt;

&lt;p&gt;No banco de dados, quando temos excesso de tráfego corremos o risco de derrubar o banco e ficar com a aplicação dando erro de conexão. Afinal, o banco não está mais lá, né?&lt;/p&gt;

&lt;p&gt;Para isso, usamos a estratégia do &lt;em&gt;source/replica&lt;/em&gt; (termo usado pela MySQL para substituir o obsoleto termo &lt;em&gt;master/slave&lt;/em&gt;. Se você quer entender melhor essa mudança, pode conferir &lt;a href="https://en.wikipedia.org/wiki/Master/slave_(technology)" rel="noopener noreferrer"&gt;nessa página&lt;/a&gt; do Wikipedia).&lt;/p&gt;

&lt;p&gt;Essa estratégia consiste, basicamente, em replicar o banco de dados e quando o original (&lt;em&gt;source&lt;/em&gt;) cair, promovemos a cópia (&lt;em&gt;replica&lt;/em&gt;) para ser utilizada.&lt;/p&gt;

&lt;p&gt;No servidor, quando começamos a ter os problemas de memória e quedas que mencionei anteriormente, ao invés de aumentar os recursos, criamos uma nova "cópia". Sendo assim, conforme o tráfego vai aumentando, as novas requisições vão sendo direcionadas para as outras instâncias.&lt;/p&gt;

&lt;p&gt;Podemos fazer esse direcionamento de duas formas: utilizando a estratégia &lt;em&gt;round robin&lt;/em&gt; onde cada nova requisição vai sendo direcionada para uma nova instância, e quando chegar na última volta para a primeira e assim sucessivamente. Ou podemos criar filtros no serviço de cloud utilizado para só direcionar para a próxima instância quando a capacidade estiver acima de 80% por exemplo.&lt;/p&gt;

&lt;p&gt;Mas quem é o responsável por direcionar as requisições para as instâncias? O famoso balanceador de carga!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Balanceador de Carga&lt;/strong&gt; (Load Balancer)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F268tikn4cbixmw4cf8x0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F268tikn4cbixmw4cf8x0.png" alt="Load Balancer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O balanceador é quem direciona as requisições para as instâncias de acordo com as regras definidas (&lt;em&gt;round robin&lt;/em&gt; ou de acordo com a sobrecarga). Ele funciona como uma camada intermediária entre o cliente e o servidor. E ele usa os IP's das instâcias para fazer esse processo de roteamento.&lt;/p&gt;

&lt;p&gt;Usando o balanceador de carga nós podemos ter o mesmo problema de não ser tolerante à falhas, e caso ele caia, nossa aplicação não conseguirá ser acessada, mesmo que os servidores e o banco de dados estejam funcionando perfeitamente. Em casos como esse, podemos ter um balanceador como backup.&lt;/p&gt;

&lt;p&gt;Bom, os problemas de sobrecarga de requisições e tolerância à falhas foram resolvidos até aqui. Mas, como essas instâncias são criadas?&lt;/p&gt;

&lt;p&gt;Uma estratégia é criar alertas. Posso criar um que, toda vez que a minha instância estiver usando mais de 80%, recebo uma notificação no meu celular. Aí vou lá e, manualmente, crio mais uma instância.&lt;/p&gt;

&lt;p&gt;Resolve? Sim! Mas aí temos mais dois problemas: dependência da intervenção humana, e desperdício de recursos.&lt;/p&gt;

&lt;p&gt;Intervenção humana: nem sempre a pessoa responsável pode estar disponível.&lt;/p&gt;

&lt;p&gt;Desperdício de recursos: você vai lá e cria uma nova instância por causa da sobrecarga de requisições, mas e quando o tráfego baixar? Você vai ficar com duas instâncias, sendo que naquele momento bastava apenas uma. E isso custa muito dinheiro! 😅&lt;/p&gt;

&lt;p&gt;A solução aqui é o dimensionamento automatizado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimensionamento Automatizado&lt;/strong&gt; (Auto Scaling)&lt;/p&gt;

&lt;p&gt;O nome é bem auto-explicativo. Podemos criar alguns filtros para provisionar e destruir as instâncias de acordo com a necessidade.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue4vf88mol5vdp22hxfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue4vf88mol5vdp22hxfs.png" alt="Auto Scaling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem podemos ver que existem grupos de auto scaling. Esses grupos devem conter um nome e uma capacidade &lt;strong&gt;mínima&lt;/strong&gt; e &lt;strong&gt;máxima&lt;/strong&gt; de instâncias que devem ser provisionadas. Você também pode especificar a capacidade &lt;strong&gt;desejada&lt;/strong&gt;, que é o número de instâncias que o grupo deve ter por padrão.&lt;/p&gt;

&lt;p&gt;Se você não especificar uma capacidade desejada, a capacidade mínima será o padrão.&lt;/p&gt;

&lt;p&gt;Bom, um problema a menos agora que temos tudo automatizado.&lt;/p&gt;

&lt;p&gt;Quando uma pessoa usuária acessa nossa aplicação ela é direcionada para a instância X. Nessa instância, ela se autentica e acessa a área para usuários autenticados. Quando clicar para ir à outra página, esse pessoa recebe o erro que essa é uma área para pessoas autenticadas, e direciona para o login.&lt;/p&gt;

&lt;p&gt;Ué? O que aconteceu aqui? Ela não acabou de se autenticar? Por que está pedindo para se autenticar novamente?&lt;/p&gt;

&lt;p&gt;Quando trabalhamos com mais de uma instância temos o problema de perda de sessão entre uma instância e outra. Porque sessões são armazenadas na própria instância e não tem como compartilhá-las entre instâncias.&lt;/p&gt;

&lt;p&gt;A pessoa do exemplo acima, se logou na instância X. Quando ela clicou para ir à outra página, ela foi direcionada para a instância Y, mas a sessão de autenticação dela estava apenas na instância X.&lt;/p&gt;

&lt;p&gt;E aí? Como resolver isso?&lt;/p&gt;

&lt;p&gt;A solução para esse problema tem nome: camada de cache.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Camada de Cache&lt;/strong&gt; (Cache Layer)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l8bpzkq3namp3nnrl4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l8bpzkq3namp3nnrl4q.png" alt="Cache Layer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A camada de cache é responsável por armazenar as sessões e compartilhá-las entre as instâncias, evitando o problema que vimos acima.&lt;/p&gt;

&lt;p&gt;Existem algumas ferramentas que fazem esse papel. Na imagem acima eu usei o logo do Redis que é uma das mais mais conhecidas (na realidade o &lt;a href="https://en.wikipedia.org/wiki/Redis" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; é um banco de dados do tipo &lt;em&gt;key-value&lt;/em&gt; que armazena os dados na memória &lt;em&gt;RAM&lt;/em&gt; do servidor, e que acaba sendo usado como ferramenta de cache por conta dessa principal característica).&lt;/p&gt;

&lt;p&gt;Além de armazenar e compartilhar sessões, a camada de cache também ajuda bastante em outro problema muito recorrente quando estamos escalando a aplicação: fazer consultas no banco de dados custa dinheiro, e se você ficar fazendo consultas constantes que poderiam ser evitadas, sua conta no final do mês vai sair bem carinha! 😱&lt;/p&gt;

&lt;p&gt;Então, na camada de cache, podemos armazenar informações que não irão se alterar com muita frequência. Por exemplo, podemos armazenar os artigos recomendados para aquela pessoa de acordo com os que ela leu. Se em todas as páginas que essa pessoa visitar fossemos fazer uma consulta no banco... já sabe né? 💸&lt;/p&gt;

&lt;p&gt;Então, podemos criar um script para quando essa pessoa acessar nossa aplicação pela primeira vez no dia, vamos buscar no banco (para pegar dados atualizados), senão, vamos buscar na camada de cache.&lt;/p&gt;

</description>
      <category>architecture</category>
    </item>
    <item>
      <title>Princípios SOLID: o que são e como aplicá-los no PHP/Laravel (Parte 05 - Inversão de Dependência)</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 17 Mar 2021 22:17:07 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-05-inversao-de-dependencia-3o6e</link>
      <guid>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-05-inversao-de-dependencia-3o6e</guid>
      <description>&lt;p&gt;Dando continuidade à série de artigos sobre princípios SOLID, trago hoje o quinto e último dos princípios.&lt;/p&gt;

&lt;h1&gt;
  
  
  Dependency Inversion Principle
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;(Princípio da Inversão de Dependência)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entidades devem depender de abstrações e não de algo concreto. Isso significa que módulos de alto nível não podem depender de módulos de baixo nível, e sim de abstrações.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como eu citei na parte 04 "abstração é o coração da orientação a objetos. Em PHP, nós conseguimos alcançar um nível de abstração utilizando interfaces e classes abstratas". Ou seja, assim como na parte 04 nós vamos aplicar o nosso exemplo de &lt;code&gt;Employees&lt;/code&gt; e &lt;code&gt;Contractor&lt;/code&gt; usando interfaces.&lt;/p&gt;

&lt;p&gt;Quando trabalhamos com arquitetura em camadas (que no nosso caso é as camadas &lt;em&gt;Controller&lt;/em&gt;, &lt;em&gt;Service&lt;/em&gt;, &lt;em&gt;Repository&lt;/em&gt; e &lt;em&gt;Model&lt;/em&gt;) o ideal é que possamos seguir o fluxo da requisição a partir do &lt;em&gt;Controller&lt;/em&gt;, e que as camadas mais externas não saibam nada do que acontece nas camadas mais internas.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;p&gt;O &lt;em&gt;Controller&lt;/em&gt; não pode depender diretamente do &lt;em&gt;Service&lt;/em&gt;, assim como o &lt;em&gt;Service&lt;/em&gt; não pode depender da camada de &lt;em&gt;Repository&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Mas por quê?&lt;/p&gt;

&lt;p&gt;Pois dessa forma essas camadas estariam dependendo de implementações concretas. Ou seja, se eu mudar alguma coisa no meu &lt;em&gt;Service&lt;/em&gt;, pode impactar diretamente no &lt;em&gt;Controller&lt;/em&gt; e acabar "quebrando" a aplicação. Isso aumenta o acoplamento entre as classes, o que é uma má prática.&lt;/p&gt;

&lt;p&gt;E como resolver isso?&lt;/p&gt;

&lt;p&gt;Com a inversão de dependência!&lt;/p&gt;

&lt;p&gt;Na parte 04, criei 2 interfaces com o objetivo de deixá-las segregadas, cada uma com suas particularidades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ContractorInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcWorkedHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$hours&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para poder fazer a inversão de dependência, eu preciso injetar a interface do &lt;em&gt;Service&lt;/em&gt; no &lt;em&gt;Controller&lt;/em&gt;. Mas como fazer isso se temos duas interfaces?&lt;/p&gt;

&lt;p&gt;A resposta é simples: herança!&lt;/p&gt;

&lt;p&gt;Eu vou criar uma interface, e as duas interfaces criadas anteriormente (&lt;code&gt;UserInterface&lt;/code&gt; e &lt;code&gt;ContractorInterface&lt;/code&gt;) irão estendê-la.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ServiceInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ContractorInterface&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcWorkedHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$hours&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, conseguimos concentrar toda essa camada de abstração em um único ponto.&lt;/p&gt;

&lt;p&gt;Agora, vamos ao &lt;em&gt;Controller&lt;/em&gt; e vamos injetar essa interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRegistrationController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ServiceInterface&lt;/span&gt; &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Percebam que mesmo o nosso atributo seja nomeado como &lt;code&gt;$userService&lt;/code&gt;, ele é do tipo &lt;code&gt;ServiceInterface&lt;/code&gt;. E dessa forma evitamos um forte acoplamento entre as camadas concretas, deixando todo serviço a cargo da abstração, que no nosso caso é a &lt;code&gt;ServiceInterface&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Fica aqui o desafio: tente fazer o mesmo processo entre as camadas de &lt;em&gt;Service&lt;/em&gt; e &lt;em&gt;Repository&lt;/em&gt;. :)&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado dessa série de artigos sobre SOLID, e em breve trarei novos conteúdos.&lt;/p&gt;

&lt;p&gt;Fui!&lt;/p&gt;

</description>
      <category>php</category>
      <category>solid</category>
      <category>architecture</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Princípios SOLID: o que são e como aplicá-los no PHP/Laravel (Parte 04 - Segregação de Interface)</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Thu, 12 Nov 2020 19:22:29 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-04-segregacao-de-interface-4gid</link>
      <guid>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-04-segregacao-de-interface-4gid</guid>
      <description>&lt;p&gt;Depois de um longo hiato, estou retomando a série dos príncipios SOLID, trazendo o quarto dos princípios.&lt;/p&gt;

&lt;h1&gt;
  
  
  Interface Segregation Principle
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;(Princípio da Segregação de Interface)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma classe não deve ser forçada a implementar interfaces que não irá utilizar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Abstração é o coração da orientação a objetos. Em PHP, nós conseguimos alcançar um nível de abstração utilizando interfaces e classes abstratas.&lt;/p&gt;

&lt;p&gt;Mas, antes, vamos dar um passo atrás: o que é interface?&lt;/p&gt;

&lt;p&gt;Interface é um conjuntos de abstrações que todas as classes que a implementam deve seguir. Cada método adicionado na interface é uma assinatura, e a partir do momento que uma classe a implementa, esta fica obrigada a adicionar todas as assinaturas previamente criadas na interface.&lt;/p&gt;

&lt;p&gt;Partindo deste princípio, parece óbvio que uma classe não deva ser forçada a implementar algo que não irá usar. Mas nesse artigo, você verá que este princípio é muito fácil de violar.&lt;/p&gt;

&lt;p&gt;Seguindo o nosso exemplo de &lt;em&gt;Employees&lt;/em&gt; e &lt;em&gt;Contractors&lt;/em&gt;, até o &lt;a href="https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-03-substituicao-de-liskov-2m9n"&gt;terceiro post da série&lt;/a&gt; eu criei uma classe chamada &lt;code&gt;UserService&lt;/code&gt; que injeta os &lt;em&gt;repositories&lt;/em&gt; para os dois tipos de usuário.&lt;/p&gt;

&lt;p&gt;Vamos fazer uma pequena alteração, a partir de agora será um &lt;em&gt;service&lt;/em&gt; para cada tipo de usuário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ContractorRepository&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa maneira eu terei duas classes que irão implementar a mesma interface &lt;code&gt;UserInterface&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcWorkedHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$hours&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interface criada com a assinatura do método &lt;code&gt;register&lt;/code&gt; (que foi criado nos posts anteriores), e agora adicionei o método &lt;code&gt;calcWorkedHours&lt;/code&gt; que será um método útil para o usuário do tipo &lt;em&gt;Contractor&lt;/em&gt; onde as horas dele serão calculadas para gerar o pagamento no fim do mês.&lt;/p&gt;

&lt;p&gt;Vamos implementar a interface nos dois &lt;em&gt;services&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeService&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorService&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcWorkedHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$hours&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa maneira nós vamos ter um erro na classe &lt;code&gt;EmployeeService&lt;/code&gt; pois ela implementa a &lt;code&gt;UserInterface&lt;/code&gt; mas não usa o método &lt;code&gt;calcWorkedHours&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Uma maneira errada de resolver isso seria implementar o método, mas sem nenhuma implementação dentro do escopo.&lt;/p&gt;

&lt;p&gt;A maneira correta seria criar duas interfaces e implementá-las onde for necessário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ContractorInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcWorkedHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$hours&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E após criar as duas interfaces, as classes já poderiam escolher quem implementar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeService&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorService&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ContractorInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcWorkedHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$hours&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementação do código&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa maneira, não obrigamos nenhuma classe a implementar algo que não irá utilizar. Sendo assim, não violamos o princípio da segregação de interface. :)&lt;/p&gt;

&lt;p&gt;Quando tentamos entender apenas a teoria dos princípios, parecem bem mais complicados do que realmente são.&lt;/p&gt;

&lt;p&gt;No próximo, e último, artigo da série vou falar sobre o Dependency Inversion Principle (Princípio da Inversão de Dependência).&lt;/p&gt;

&lt;p&gt;Dúvidas e feedbacks são sempre bem-vindos.&lt;/p&gt;

</description>
      <category>php</category>
      <category>solid</category>
      <category>architecture</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Retomando os posts e geração de conteúdo</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Thu, 12 Nov 2020 18:20:32 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/retomando-os-posts-e-geracao-de-conteudo-3iog</link>
      <guid>https://dev.to/lucascavalcante/retomando-os-posts-e-geracao-de-conteudo-3iog</guid>
      <description>&lt;p&gt;Olá, pessoal!&lt;/p&gt;

&lt;p&gt;Passei um tempo sem postar nada, mas nas últimas semanas retomei o engajamento e criei:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um canal no youtube: &lt;a href="https://www.youtube.com/lucascavalcante81"&gt;https://www.youtube.com/lucascavalcante81&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Um site: &lt;a href="http://lucascavalcante.com"&gt;http://lucascavalcante.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Além disso, aumentei minha frequência de postagens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linkedin: &lt;a href="https://www.linkedin.com/in/lucascavalcante"&gt;https://www.linkedin.com/in/lucascavalcante&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href="https://twitter.com/lucascgomes"&gt;https://twitter.com/lucascgomes&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E agora vou retomar meus posts aqui no dev.to!&lt;/p&gt;

&lt;p&gt;Podem me adicionar nas redes e se inscrevam no meu canal pois os conteúdos nem sempre serão os mesmos.&lt;/p&gt;

&lt;p&gt;Grande abraço! 🤙&lt;/p&gt;

</description>
      <category>youtube</category>
      <category>dev</category>
      <category>content</category>
    </item>
    <item>
      <title>4 maneiras de criar componentes no React</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 17 Jun 2020 22:59:13 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/4-maneiras-de-criar-componentes-no-react-53b3</link>
      <guid>https://dev.to/lucascavalcante/4-maneiras-de-criar-componentes-no-react-53b3</guid>
      <description>&lt;p&gt;Durante a quarentena eu fiz um post no meu Linkedin divulgando o "April Free Month" da &lt;a href="https://www.pluralsight.com"&gt;Pluralsight&lt;/a&gt;. Eles ofereceram todos os cursos das plataforma de forma gratuita durante o mês de Abril.&lt;/p&gt;

&lt;p&gt;Eu aproveitei a oportunidade para fazer a trilha de React. Sempre tive contatos básicos com React, fazendo pequenas alterações, mas nunca me aprofundei na arquitetura.&lt;/p&gt;

&lt;p&gt;E digo com todas as letras que valeu muito a pena. Fiz 5 cursos de React do básico ao avançado, e todos muitos bons. (principalmente os do Cory House)&lt;/p&gt;

&lt;p&gt;Desde então o que tenho feito para fixar o aprendizado: estou criando uma aplicação usando React no front (logo mais vou divulgar), e decidi criar conteúdo.&lt;/p&gt;

&lt;p&gt;Portanto esse é o primeiro artigo sobre React que estou escrevendo.&lt;/p&gt;

&lt;p&gt;Vamos lá!&lt;/p&gt;

&lt;p&gt;Como dito, podemos criar os componentes de 4 diferente formas.&lt;/p&gt;

&lt;p&gt;Para todos os exemplos, vamos fazer um botão que incremente o contador.&lt;/p&gt;

&lt;h2&gt;
  
  
  ES6 Class Component
&lt;/h2&gt;

&lt;p&gt;Esse era o modo mais usado antes da versão 16.8 do React. Pois era o que melhor trabalhava com ciclos de vida do componente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um dos problemas deste formato era o problema de escopo, sempre que criamos uma função, temos que criar um &lt;code&gt;bind&lt;/code&gt; para esta função como ajuste de escopo. E além disso, tinha o uso constante da palavra-chave &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Você pode ver o exemplo &lt;a href="https://codepen.io/lucascavalcante81/pen/vYLyJbJ"&gt;neste link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  CreateReactClass Component
&lt;/h2&gt;

&lt;p&gt;Este maneira está em desuso nos dias de hoje por conta da complexidade e quantidade de código que temos que escrever. Ela se assemelha à forma como criávamos objetos no ES5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createReactClass&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getDefaultProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initialCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;getInitialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initialCount&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste formato também usamos a palavra-chave &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Você pode ver o exemplo &lt;a href="https://codepen.io/lucascavalcante81/pen/wvMoqym"&gt;neste link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functional Component
&lt;/h2&gt;

&lt;p&gt;Este é o formato mais usado atualmente (após o lançamento da versão 16.8), pois é o que melhor trabalha com os Hooks, evitando o uso do ciclo de vida do componente, além de evitar a palavra-chave &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Além disso, existe a proposta que as classes do React deixem de existir em um futuro próximo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo é perceptível como tivemos que escrever menos código. Aqui, usamos o hook &lt;code&gt;useState&lt;/code&gt; que trabalha o controle de estado dos objetos.&lt;/p&gt;

&lt;p&gt;Você pode ver o exemplo &lt;a href="https://codepen.io/lucascavalcante81/pen/vYLyZgq"&gt;neste link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arrow Function Component
&lt;/h2&gt;

&lt;p&gt;Este formato é bastante parecido com o anterior, e é bastante usado para criar componentes apenas com JSX. Por conta disso, alterei um pouco o exemplo, adicionando 2 componentes que renderizam os elementos HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
        &lt;span class="na"&gt;whenClicked&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"+1"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whenClicked&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode ver o exemplo &lt;a href="https://codepen.io/lucascavalcante81/pen/abdBybr"&gt;neste link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;E aí, o que achou?&lt;/p&gt;

&lt;p&gt;Qualquer sugestão e/ou feedback sempre serão muito bem-vindos.&lt;/p&gt;

&lt;p&gt;Até o próximo artigo! ✋&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Princípios SOLID: o que são e como aplicá-los no PHP/Laravel (Parte 03 - Substituição de Liskov)</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Mon, 15 Jun 2020 22:56:37 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-03-substituicao-de-liskov-2m9n</link>
      <guid>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-03-substituicao-de-liskov-2m9n</guid>
      <description>&lt;p&gt;Dando continuidade à série de artigos sobre princípios SOLID, hoje vou falar sobre o terceiro dos princípios.&lt;/p&gt;

&lt;h1&gt;
  
  
  Liskov Substitution Principle
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;(Princípio da Substituição de Liskov)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma classe derivada deve ser substituída por sua classe base.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este princípio tem este nome porque foi introduzido por &lt;a href="https://pt.wikipedia.org/wiki/Barbara_Liskov"&gt;Barbara Liskov&lt;/a&gt; em sua apresentação "&lt;a href="https://klevas.mif.vu.lt/~plukas/resources/OODPrinciples/Liskov1987.pdf"&gt;Data Abstraction&lt;/a&gt;" em 1987. Alguns anos mais tarde, ela publicou um artigo, junto com Jeanette Wing, onde elas definiram o princípio como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Seja Φ(x) uma provável propriedade sobre objetos x do tipo T. Então Φ(y) deve ser verdadeira para objetos y do tipo S, em que S é um subtipo de T.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uma definição um tanto quanto complexa, não é mesmo? Normal, quando se trata de um artigo científico. Vamos simplificar e ver como isso se aplica na prática.&lt;/p&gt;

&lt;p&gt;Continuando o nosso exemplo de &lt;em&gt;Employees&lt;/em&gt; e &lt;em&gt;Contractors&lt;/em&gt;, no &lt;a href="https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-01-responsabilidade-unica-3mjj"&gt;primeiro artigo dessa série&lt;/a&gt; eu criei 2 &lt;em&gt;repositories&lt;/em&gt; para ambos os perfis de usuário, e os injetei como dependência no &lt;code&gt;UserService&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;ContractorRepository&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'employee'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;employeeRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'contractor'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;a href="https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-02-aberto-fechado-4ddp"&gt;segundo artigo da série&lt;/a&gt;, eu criei um arquivo &lt;code&gt;BaseRepository&lt;/code&gt; que seria a classe pai de &lt;code&gt;EmployeeRepository&lt;/code&gt; e &lt;code&gt;ContractorRepository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;É muito simples aplicar a substituição de Liskov.&lt;/p&gt;

&lt;p&gt;Primeiro vamos criar um &lt;em&gt;repository&lt;/em&gt; intermediário entre a classe pai e as classes filhas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// seu código&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// seu código&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// seu código&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// seu código&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, a &lt;code&gt;BaseRepository&lt;/code&gt; continua sendo "base" para outros &lt;em&gt;repositories&lt;/em&gt; também, e a &lt;code&gt;UserRepository&lt;/code&gt; vira a classe pai das outras duas.&lt;/p&gt;

&lt;p&gt;Agora vamos fazer uma pequena alteração no classe &lt;code&gt;UserService&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;ContractorRepository&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;checkUserType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'employee'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;employeeRepository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'contractor'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Renomeei o método &lt;code&gt;register()&lt;/code&gt; para &lt;code&gt;checkUserType()&lt;/code&gt; onde continua sendo feita a validação do tipo de usuário. Mas, ao invés de chamar diretamente o &lt;em&gt;repository&lt;/em&gt;, agora chama outro método dentro desta mesma classe, que por sua vez, agora se chama &lt;code&gt;register()&lt;/code&gt; e recebe como parâmetro o &lt;em&gt;array&lt;/em&gt; &lt;code&gt;$attributes&lt;/code&gt; e uma instância de &lt;code&gt;UserRepository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Independentemente de qual dos &lt;em&gt;repositories&lt;/em&gt; for passado como parâmetro, ambos são do tipo &lt;code&gt;UserRepository&lt;/code&gt; e quando for chamado o método &lt;code&gt;save()&lt;/code&gt;, irá chamar de acordo com o que foi passado.&lt;/p&gt;

&lt;p&gt;Dessa forma, nós temos a chamada para o &lt;em&gt;repository&lt;/em&gt; de uma forma mais centralizada, e mantendo o mesmo tipo de objeto na passagem do parâmetro.&lt;/p&gt;

&lt;p&gt;Espero que tenha ficado claro para você. Caso contrário, comente aí sua dúvida.&lt;/p&gt;

&lt;p&gt;E aí, gostou? No próximo artigo da série vou falar sobre o Interface Segregation Principle (Princípio da Segregação de Interface)&lt;/p&gt;

&lt;p&gt;Dúvidas e feedbacks são sempre bem-vindos.&lt;/p&gt;

</description>
      <category>php</category>
      <category>solid</category>
      <category>architecture</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Princípios SOLID: o que são e como aplicá-los no PHP/Laravel (Parte 02 - Aberto-fechado)</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 27 May 2020 23:19:38 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-02-aberto-fechado-4ddp</link>
      <guid>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-02-aberto-fechado-4ddp</guid>
      <description>&lt;p&gt;Dando continuidade à série de artigos sobre princípios SOLID, hoje vou falar sobre o segundo dos princípios.&lt;/p&gt;

&lt;h1&gt;
  
  
  Open-closed Principle
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;(Princípio Aberto-fechado)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Objetos ou entidades devem ser abertas para extensão, mas fechadas para modificação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em outras palavras, se eu tenho uma classe genérica que atende a diversos tipos de perfis, ao invés de sair fazer condicionais para cada caso, podemos criar especializações dessa classe, e em cada uma delas eu coloco o que atende aquele perfil.&lt;/p&gt;

&lt;p&gt;Vamos continuar o exemplo que eu usei no artigo anterior, onde nós temos 2 tipos de &lt;code&gt;User&lt;/code&gt;, o &lt;code&gt;Employee&lt;/code&gt; e o &lt;code&gt;Contractor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Você pode ver &lt;a href="https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-01-responsabilidade-unica-3mjj"&gt;aqui&lt;/a&gt; que eu criei 2 &lt;em&gt;Repositories&lt;/em&gt;, um para cada tipo de usuário, e em ambas eu criei o método &lt;code&gt;save()&lt;/code&gt; executando exatamente a mesma coisa. (no final do artigo eu expliquei que usei dessa maneira para facilitar o entendimento da separação de responsabilidades)&lt;/p&gt;

&lt;p&gt;Então, vamos melhorar esse código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="nv"&gt;$obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findByColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criei uma classe &lt;code&gt;BaseRepository&lt;/code&gt; que como o próprio nome diz, serve como base para classes especialistas, contendo os métodos que são genéricos a todas as classes que irão estendê-la.&lt;/p&gt;

&lt;p&gt;Vamos criar as classes filhas (ou especialistas).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Employee&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Contractor&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se as classes &lt;code&gt;EmployeeRepository&lt;/code&gt; e &lt;code&gt;ContractorRepository&lt;/code&gt; não tiverem nenhuma especificidade, basta criá-las apenas com o construtor chamando a classe pai que todos os métodos irão funcionar. Na camada de &lt;em&gt;Service&lt;/em&gt; quando formos fazer a injeção de dependência, injetamos a classe especialista.&lt;/p&gt;

&lt;p&gt;Mas utilizando alguns princípios da orientação a objetos, vamos fazer algo específico para cada uma delas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Employee&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$except&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereNotIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$except&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Contractor&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$hoursPerWeek&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'hours_per_week'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$hoursPerWeek&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na classe &lt;code&gt;EmployeeRepository&lt;/code&gt; eu fiz uma sobreposição do método &lt;code&gt;all()&lt;/code&gt; onde quase tudo é igual à classe pai (nome, parâmetros, retorno) exceto a implementação.&lt;/p&gt;

&lt;p&gt;Na classe &lt;code&gt;ContractorRepository&lt;/code&gt; eu fiz uma sobrecarga do método &lt;code&gt;save()&lt;/code&gt; onde o nome do método é o mesmo da classe pai, mas a quantidade e/ou tipo dos parâmetros é diferente.&lt;/p&gt;

&lt;p&gt;Dessa forma consegui deixar ambas as classes mais especializadas sem interferir na classe pai, ou perder suas características.&lt;/p&gt;

&lt;p&gt;Espero que tenha gostado. No próximo artigo da série vou falar sobre o &lt;em&gt;Liskov Substitution Principle&lt;/em&gt; (Princípio da Substituição de Liskov)&lt;/p&gt;

&lt;p&gt;Dúvidas e feedbacks são sempre bem-vindos.&lt;/p&gt;

</description>
      <category>php</category>
      <category>solid</category>
      <category>architecture</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Princípios SOLID: o que são e como aplicá-los no PHP/Laravel (Parte 01 - Responsabilidade Única)</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Thu, 21 May 2020 23:00:01 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-01-responsabilidade-unica-3mjj</link>
      <guid>https://dev.to/lucascavalcante/principios-solid-o-que-sao-e-como-aplica-los-no-php-laravel-parte-01-responsabilidade-unica-3mjj</guid>
      <description>&lt;p&gt;Hoje vou abordar um dos temas que mais me interessa dentro do mundo do desenvolvimento de software: escrever códigos melhores.&lt;/p&gt;

&lt;p&gt;Dentro deste tema costuma-se falar de arquitetura de software, padrões de projeto, design de software, etc.&lt;/p&gt;

&lt;p&gt;Nesta série de artigos vou abordar o SOLID que é um princípio de design de software orientado a objeto (OOD). Basicamente, SOLID é um acrônimo para:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;S - Single Responsibility Principle
O - Open-closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D - Dependency Inversion Principle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos entender como funciona cada um deles e exemplicar usando o PHP. Mais especificamente o Laravel, por ser um &lt;em&gt;framework&lt;/em&gt; que adota o MVC por padrão e, com o crescimento da aplicação, tende a ficar com o código/estrutura bem bagunçados se não organizar desde o começo.&lt;/p&gt;

&lt;p&gt;Então, neste primeiro artigo vamos abordar o primeiro dos princípios de forma detalhada.&lt;/p&gt;

&lt;h1&gt;
  
  
  Single Responsibility Principle
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;(Princípio da Responsabilidade Única)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma classe deve ter uma e apenas uma razão para mudança, significando que uma classe deve ter apenas uma responsabilidade. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este é o primeiro, mais simples, e mais importante princípio, pois parte da premissa que toda classe deve ter apenas 1 objetivo quando se trata do fluxo de uma requisição do software.&lt;/p&gt;

&lt;p&gt;Vamos dar uma olhada no exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRegistrationController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'employee'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;saveEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'contractor'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;saveContractor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user.register'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;saveEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'employees'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="cm"&gt;/* Dados do funcionário aqui... */&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;saveContractor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'employees'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="cm"&gt;/* Dados do terceirizado aqui... */&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta classe acima viola o princípio da responsabilidade única pelos motivos a seguir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mistura responsabilidades. Um &lt;em&gt;Controller&lt;/em&gt; deve ser responsável por apenas gerenciar &lt;em&gt;requests&lt;/em&gt; e &lt;em&gt;responses&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Regra de negócio de ser aplicada em uma camada separada, como a camada de &lt;em&gt;Service&lt;/em&gt;, por exemplo. (que não tem como padrão no Laravel, mas podemos criá-la manualmente)&lt;/li&gt;
&lt;li&gt;Operações com o banco de dados também devem estar em outra camada. No Laravel, por padrão, usamos o &lt;em&gt;Model&lt;/em&gt;. Mas no neste artigo vou usar a camada de &lt;em&gt;Repository&lt;/em&gt;. (mesmo caso do &lt;em&gt;Service&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos corrigir a classe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRegistrationController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserService&lt;/span&gt; &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$userService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user.register'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui deixamos o &lt;em&gt;Controller&lt;/em&gt; isolado com a sua única responsabilidade: gerenciar a &lt;em&gt;request&lt;/em&gt; e a &lt;em&gt;response&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;No Laravel, para podermos adicionar uma camada de comunicação com a classe atual, nós usamos a injeção de dependência nativa do &lt;em&gt;framework&lt;/em&gt;. Basta adicionar a classe desejada como parâmetro no construtor e atribuí-la em uma propriedade da classe. E eu fiz isso adicionando a classe &lt;code&gt;UserService&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vamos entender agora a classe &lt;code&gt;UserService&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;EmployeeRepository&lt;/span&gt; &lt;span class="nv"&gt;$employeeRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;ContractorRepository&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$contractorRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'employee'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;employeeRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'contractor'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractorRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;em&gt;Service&lt;/em&gt; é o local onde colocamos toda a regra de negócio, como é o caso do condicional que usamos para identificar o tipo de usuário.&lt;/p&gt;

&lt;p&gt;Aqui também usamos a injeção de dependência, mas importamos 2 classes. Exatamente os &lt;em&gt;Repositories&lt;/em&gt; dos tipos de usuário. Como o &lt;em&gt;Model&lt;/em&gt; é a representação da tabela do banco dentro da aplicação, e o &lt;em&gt;Repository&lt;/em&gt; é reponsável pela operação de banco de cada &lt;em&gt;Model&lt;/em&gt;, nada mais coerente mantê-los separados.&lt;/p&gt;

&lt;p&gt;Vamos entender agora os &lt;em&gt;Repositories&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeRespository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Employee&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractorRespository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Employee&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$contractor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;contractor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em ambos os &lt;em&gt;Repositories&lt;/em&gt; utilizamos a mesma estrutura: injeção de dependência com o respectivos &lt;em&gt;Models&lt;/em&gt;, e um método &lt;code&gt;save()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dessa maneira, separamos as responsabilidades em camadas, deixando o código mais legível e com uma arquitetura mais correta.&lt;/p&gt;

&lt;p&gt;No próximo artigo vou abordar o segundo princípio: Open-closed Principle (Princípio Aberto-fechado).&lt;/p&gt;

&lt;p&gt;Espero que você tenha gostado. Dúvidas e feedbacks são sempre muito bem vindos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS:&lt;/em&gt; Se você quiser adicionar &lt;em&gt;Services&lt;/em&gt; e &lt;em&gt;Repositories&lt;/em&gt; na sua aplicação Laravel, é só criar as pastas &lt;code&gt;app/Services&lt;/code&gt; e &lt;code&gt;app/Repositories&lt;/code&gt; e adicionar suas classes manualmente.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PPS:&lt;/em&gt; Neste exemplo abordei apenas o essencial para explicá-lo, deixando de fora &lt;em&gt;imports&lt;/em&gt;, &lt;em&gt;returns&lt;/em&gt;, &lt;em&gt;validators&lt;/em&gt;, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PPPS:&lt;/em&gt; Eu sei que o ideal seria ter um &lt;em&gt;Model&lt;/em&gt; &lt;code&gt;User&lt;/code&gt; e estender para &lt;code&gt;Employee&lt;/code&gt; e &lt;code&gt;Contractor&lt;/code&gt;. Mas para o exemplo ficar mais claro, deixei-os separados mesmo.&lt;/p&gt;

</description>
      <category>php</category>
      <category>solid</category>
      <category>architecture</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Como usar map, filter e reduce no PHP</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 13 May 2020 04:55:43 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/como-usar-map-filter-e-reduce-no-php-189o</link>
      <guid>https://dev.to/lucascavalcante/como-usar-map-filter-e-reduce-no-php-189o</guid>
      <description>&lt;p&gt;No artigo anterior, eu falei sobre o uso de &lt;em&gt;arrow functions&lt;/em&gt; dentro do PHP. Você pode lê-lo &lt;a href="https://dev.to/lucascavalcante/facilitando-o-entendimento-da-arrow-function-no-php-9a2"&gt;neste link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hoje, seguindo com a aplicação de conceitos funcionais no PHP, vamos falar sobre 3 funções amplamente utlizadas quando precisamos percorrer um array e, se fossemos usar um loop tradicional, teríamos um pouco mais de trabalho. Estou falando do &lt;code&gt;array_map&lt;/code&gt;, &lt;code&gt;array_filter&lt;/code&gt; e o &lt;code&gt;array_reduce&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para começar, vamos usar um array que será aplicado em todos os exemplos deste artigo. Um array com os &lt;strong&gt;Top 3&lt;/strong&gt; filmes que mais arrecadaram na história do cinema. Vamos ter o título do filme, nota no IMDB, faturamento nos Estados Unidos, e faturamento no Brasil.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$filmes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'titulo'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Vingadores: Ultimato'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'imdb'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;8.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;858300000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;85660000&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'titulo'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Avatar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'imdb'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;7.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;760500000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;58210000&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'titulo'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Titanic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'imdb'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;7.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;659360000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;70460000&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  array_map
&lt;/h3&gt;

&lt;p&gt;A função &lt;code&gt;array_map&lt;/code&gt; tem como objetivo percorrer todo o array e &lt;strong&gt;mapear&lt;/strong&gt; cada um dos itens processando-os com o que é pedido, e gerando um novo array com os novos valores.&lt;/p&gt;

&lt;p&gt;No nosso exemplo, vamos supor que o valor total das arrecadações são valores brutos, e que nós vamos descontar os impostos para mostrar o valor líquido. Vamos usar os valores fictícios de 16% para o Brasil e 6% para os Estados Unidos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$filmesDepoisDosImpostos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.06&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$filmes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmesDepoisDosImpostos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode perceber que a função &lt;code&gt;array_map&lt;/code&gt; recebe 2 parâmetros: o primeiro é a função onde o mapeamento é feito, e o segundo é o array que irá fornecer os dados para serem mapeados.&lt;/p&gt;

&lt;h3&gt;
  
  
  array_filter
&lt;/h3&gt;

&lt;p&gt;A função &lt;code&gt;array_filter&lt;/code&gt; tem como objetivo &lt;strong&gt;filtrar&lt;/strong&gt; os itens do array que atendam a uma condição estipulada dentro da função, e gerando um novo array apenas com os itens filtrados.&lt;/p&gt;

&lt;p&gt;Por exemplo, eu quero filtrar pelos filmes que tenham a nota no IMDB abaixo de 8.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$filmesNotaMenorQueOito&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'imdb'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmesNotaMenorQueOito&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse caso aqui, os parâmetros se invertem em relação ao &lt;code&gt;array_map&lt;/code&gt;. O primeiro parâmetro é o array que servirá como base para a filtragem, e o segundo é a função que irá estipular a condição para o filtro.&lt;/p&gt;

&lt;p&gt;Se você reparar na saída do código, o novo array manteve a chave original dos itens do array original. Isso pode facilitar se você quiser chamar o array original usando as mesmas chaves.&lt;/p&gt;

&lt;h3&gt;
  
  
  array_reduce
&lt;/h3&gt;

&lt;p&gt;A função &lt;code&gt;array_reduce&lt;/code&gt; tem como objetivo &lt;strong&gt;reduzir&lt;/strong&gt; o array a um único valor utilizando alguma operação aritmética para tal.&lt;/p&gt;

&lt;p&gt;Neste exemplo, eu quero somar o faturamento no Brasil dos 3 filmes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$totalFaturamentoBR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$total&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$totalFaturamentoBR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, temos 3 parâmetros. O primeiro é o array original que servirá como base para a operação aritmética, o segundo é a função que irá processar o cálculo, e o terceiro (opcional) servirá como valor inicial da operação. No nosso caso, como ele está 0(zero) não faria diferença se nós o removessemos. Mas vamos supor que além desse faturamento, fossemos adicionar o valor arrecadado desses mesmos filmes com streaming. Colocariamos esse valor no terceiro parâmetro.&lt;/p&gt;

&lt;p&gt;Achou fácil? Espero que eu tenha ajudado a elucidar suas dúvidas.&lt;/p&gt;




&lt;p&gt;Para finalizar, gostaria de refazer 2 dos exemplos acima utilizando maneiras de deixar o código mais legível e clean.&lt;/p&gt;

&lt;h3&gt;
  
  
  Função externa
&lt;/h3&gt;

&lt;p&gt;O primeiro exemplo será com o &lt;code&gt;array_map&lt;/code&gt; e será usando uma função que foi declarada fora do seu escopo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;aplicarImposto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_us'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.06&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'faturamento_br'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$filmesDepoisDosImpostos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"aplicarImposto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$filmes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmesDepoisDosImpostos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criamos a função &lt;code&gt;aplicarImposto&lt;/code&gt; com o mesmo formato e conteúdo da versão anterior. Dentro do &lt;code&gt;array_map&lt;/code&gt;, chamamos a função como uma string, e o parâmetro é passado de forma implícita. Visualmente, fica mais fácil de entender o código, mas tudo é questão de costume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrow function
&lt;/h3&gt;

&lt;p&gt;No artigo anterior falei sobre &lt;em&gt;arrow function&lt;/em&gt;. A boa notícia é que podemos usá-la em conjunto com essas funções (quando o contexto permite, é claro). Lembrando que &lt;em&gt;arrow function&lt;/em&gt; só irá funcionar a partir da versão 7.4 da linguagem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$filmesNotaMenorQueOito&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$filme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'imdb'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filmesNotaMenorQueOito&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conseguimos reduzir a 1 linha o exemplo anterior do &lt;code&gt;array_filter&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;E aí, o que achou? Espero que tenha gostado.&lt;/p&gt;

&lt;p&gt;É sempre bom lembrar, dúvidas e feedbacks são sempre muito bem vindos.&lt;/p&gt;

</description>
      <category>php</category>
      <category>functional</category>
    </item>
    <item>
      <title>Facilitando o entendimento da arrow function no PHP</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Tue, 12 May 2020 03:01:54 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/facilitando-o-entendimento-da-arrow-function-no-php-9a2</link>
      <guid>https://dev.to/lucascavalcante/facilitando-o-entendimento-da-arrow-function-no-php-9a2</guid>
      <description>&lt;p&gt;Se você já estudou um pouco sobre programação funcional, provavelmente já ouviu falar sobre a função que nomeia este artigo. E além disso, se estudou Javascript, possivelmente já estudou muito sobre esse conceito.&lt;/p&gt;

&lt;p&gt;Trago neste artigo uma dica rápida de como aplicar este conceito tão popular na programação funcional (amplamente popularizado pelo Javascript) dentro do PHP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrow function
&lt;/h3&gt;

&lt;p&gt;As &lt;em&gt;arrow functions&lt;/em&gt; foram introduzidas no PHP a partir da versão 7.4 da linguagem, e tem como principais missões dar produtividade ao desenvolvedor e facilitar o trabalho com escopo.&lt;/p&gt;

&lt;p&gt;Vamos ver um exemplo de código sem usar &lt;em&gt;arrow function&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;18.63&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcularJuros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$emprestimo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$taxa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$emprestimo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taxa&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calcularJuros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos supor que essa taxa é fixa e não precisa ser passada como parâmetro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;18.63&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calcularJuros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$emprestimo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$emprestimo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calcularJuros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse caso, vamos receber um erro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Undefined variable: taxaDeJuros
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porque a variável &lt;code&gt;$taxaDeJuros&lt;/code&gt; foi declarada fora da função &lt;code&gt;calcularJuros&lt;/code&gt; e por conta do escopo, ela não é enxergada dentro da função. Aí que entra a &lt;em&gt;arrow function&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Antes, vamos ver o mesmo exemplo de código com uma função anônima:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;18.63&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$jurosCalculados&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$emprestimo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$emprestimo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jurosCalculados&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bom, resolvemos em parte o nosso problema. O &lt;code&gt;use&lt;/code&gt; nos permite "herdar" variáveis do escopo pai. Não precisamos passar como parâmetro na função, mas ainda assim precisamos referenciar.&lt;/p&gt;

&lt;p&gt;Agora, o mesmo exemplo de código usando &lt;em&gt;arrow function&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;18.63&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$jurosCalculados&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$emprestimo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$emprestimo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taxaDeJuros&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jurosCalculados&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$valorDoEmprestimo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Muito mais conciso, não é? Mas o que mudou? Vamos enumerar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Redução da palavra &lt;em&gt;function&lt;/em&gt; para apenas &lt;em&gt;fn&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Substituição do par de chaves &lt;code&gt;{ }&lt;/code&gt; pela &lt;em&gt;arrow&lt;/em&gt; &lt;code&gt;=&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Supressão do &lt;code&gt;return&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;E, finalmente, não foi preciso referenciar a variável &lt;code&gt;$taxaDeJuros&lt;/code&gt; em lugar nenhum. Ela simplesmente foi reconhecida por ser do escopo pai.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fácil, né?&lt;/p&gt;

&lt;p&gt;Se ficou alguma dúvida ou gostaria de dar um feedback, deixa um comentário. :)&lt;/p&gt;

&lt;p&gt;No próximo artigo vou trazer outros conceitos da programação funcional usando as funções &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; e &lt;code&gt;reduce&lt;/code&gt; no PHP.&lt;/p&gt;

</description>
      <category>php</category>
      <category>functional</category>
    </item>
    <item>
      <title>Trabalho remoto no exterior #3 - Speaking English</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 07 Aug 2019 13:56:59 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-3-speaking-english-4bp4</link>
      <guid>https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-3-speaking-english-4bp4</guid>
      <description>&lt;p&gt;Olá, esse é o terceiro post da série "Trabalho Remoto" (leia o primeiro e o segundo &lt;a href="https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-1-onde-procurar-de7"&gt;aqui&lt;/a&gt; e &lt;a href="https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-2-code-challenges-4m5g"&gt;aqui&lt;/a&gt; respectivamente), e hoje vou compartilhar minha experiência com o aprendizado do inglês.&lt;/p&gt;

&lt;p&gt;Como 95% dos brasileiros da minha geração, eu não aprendi inglês na minha infância/adolescência. O ensino de idiomas no currículo escolar obrigatório sempre foi precário (verbo &lt;em&gt;to be ad eternum&lt;/em&gt;), e as escolas de idiomas sempre foram caríssimas.&lt;/p&gt;

&lt;p&gt;Na vida adulta ainda demorei para "acordar" e começar a estudar inglês. Só comecei a fazê-lo depois dos 30.&lt;/p&gt;

&lt;p&gt;No desespero de aprender, ainda cheguei a fazer &lt;strong&gt;UMA ÚNICA&lt;/strong&gt; aula em uma escola de idiomas. Quando a professora começou a aula pedindo para todo mundo repetir em voz alta &lt;em&gt;"How are you?"&lt;/em&gt; e &lt;em&gt;"I'm fine, thanks"&lt;/em&gt; umas 200 vezes, já percebi imediatamente que estava no lugar errado. Terminei a aula e já fui pedindo o cancelamento na recepção.&lt;/p&gt;

&lt;p&gt;Então, vou listar abaixo o caminho que eu trilhei e que &lt;em&gt;PARA MIM&lt;/em&gt; deu certo. Imagino que cada um vá se adaptar melhor a um determinado formato para seu estilo de aprendizado.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Aulas Particulares&lt;/strong&gt;: quando eu era bem &lt;em&gt;newbie&lt;/em&gt; ainda, procurei um professor particular pois ele poderia adaptar o formato da aula à minha necessidade. Peguei a indicação com um amigo que passou um tempo no Canadá, e antes de ir fez aulas com esse professor. Indico bastante, pois nas primeiras aulas além de entender sua motivação, ele vai vendo o seu nível, e sempre tenta arrancar mais do que você pode dar. Às vezes desmotiva, parece que você não está evoluindo, mas é exatamente o contrário. Caso você tenha interesse, manda mensagem que eu indico com o maior prazer. (ele é de Fortaleza, mas dá aulas por Skype também)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://pt.duolingo.com"&gt;Duolingo&lt;/a&gt;: como a maioria das pessoas, depois de um tempo fazendo as aulas, e achando que já tinha um nível bom o suficiente, parei com as mesmas. E nisso fiquei alguns anos estudando por conta própria (Youtube, livros, música, comunidades, etc), mas como não havia uma metodologia envolvida, era sempre muito desordenado meu aprendizado. O que me ajudou a manter um contato diário com o idioma e não esquecer coisas importante foi o aplicativo Duolingo. Ele é totalmente gratuito e tem uma estratégia de gamificação que realmente te vicia. Com ele, você treina &lt;em&gt;reading&lt;/em&gt;, &lt;em&gt;writing&lt;/em&gt;, &lt;em&gt;listening&lt;/em&gt; e &lt;em&gt;speaking&lt;/em&gt;. Além de ter um fórum para perguntar e responder a outros usuários.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cambly.com/invite/lucas686"&gt;Cambly&lt;/a&gt;: é uma plataforma para aprendizado do inglês com falantes nativos do idioma. Foi aqui onde realmente consegui "desbloquear" meu inglês. No começo é difícil, admito. Você pensa em desistir algumas vezes. A minha estratégia inicial foi agendar professores que também falassem português, pois se eu travasse, teria uma válvula de escape. Depois que peguei um pouco mais de confiança fui conversando com outros professores e, aos poucos, fui agendando com professores que só falavam inglês. Eu havia assinado o pacote de 1 ano, mas só fiz regularmente aulas durante 6 meses. Depois desse período fazia apenas aulas esporádicas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existem outras plataformas similares ao Cambly (&lt;a href="https://www.italki.com/?hl=pt"&gt;iTalki&lt;/a&gt;, &lt;a href="https://pt-br.verbling.com"&gt;Verbling&lt;/a&gt;), mas na época peguei um cupom de 50% de desconto e ficou fácil decidir. :)&lt;/p&gt;

&lt;p&gt;Depois disso, já fiz diversas entrevistas em inglês. Não sou fluente, e acho que só é fluente quem mora fora um tempo, mas falo o suficiente para manter uma conversação. E até hoje me engancho no &lt;em&gt;phrasal verbs&lt;/em&gt;, mas isso não evita que eu consiga me comunicar.&lt;/p&gt;

&lt;p&gt;Hoje trabalho alocado em uma empresa em Austin (ô sotaque carregado desse povo do Texas), e isso me ajuda ainda mais a ir corrigindo meu erros.&lt;/p&gt;

</description>
      <category>remote</category>
      <category>devlife</category>
    </item>
    <item>
      <title>Trabalho remoto no exterior #2 - Code challenges</title>
      <dc:creator>Lucas Cavalcante</dc:creator>
      <pubDate>Wed, 03 Jul 2019 14:13:38 +0000</pubDate>
      <link>https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-2-code-challenges-4m5g</link>
      <guid>https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-2-code-challenges-4m5g</guid>
      <description>&lt;p&gt;Olá, esse é o segundo post da série "Trabalho Remoto" (leia o primeiro &lt;a href="https://dev.to/lucascavalcante/trabalho-remoto-no-exterior-1-onde-procurar-de7"&gt;aqui&lt;/a&gt;), e dessa vez vou trazer algumas dicas relacionadas aos sites de &lt;strong&gt;code challenge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Como falei no post anterior, em 2017 comecei a fazer entrevistas em inglês para tentar trabalhos no exterior, fossem eles remotos ou presenciais. E na maioria dessas entrevistas, quando eu conseguia passar para o teste técnico, recebia um e-mail com um link para um site onde o teste seria validado de forma automática e com um tempo pré-determinado para finalização. Também conhecidos como code challenges.&lt;/p&gt;

&lt;p&gt;Esse tipo de teste se diferencia um pouco dos demais pela automação que mencionei acima, e também por exigir um pouco mais de conhecimento na parte de conceitos, como por exemplo: estrutura de dados, resolução de problemas, sistemas distribuídos, algoritmos, matemática, etc.&lt;/p&gt;

&lt;p&gt;Para quem é acostumado apenas com o dia a dia de um software mexendo com requests, responses, ORM e afins, vai penar bastante como eu penei. Apesar de ter estudado muitos desses temas na faculdade, não aplico com frequência no dia a dia e o conhecimento acaba escapando com o tempo.&lt;/p&gt;

&lt;p&gt;Alguns destes testes são bem pragmáticos, do tipo "faça isso" e se compilar, passou. Já outros mandam um breafing, vocẽ tem que criar uma feature, criar testes unitários, e no final a plataforma ainda rodar os próprios testes para verificar a assertividade do código. (e depois de passar em todos esses testes, a empresa ainda te retorna dizendo que você não foi aprovado para a próxima fase, vai entender)&lt;/p&gt;

&lt;p&gt;Bom, com o tempo a gente vai pegando o jeito e melhorando nosso rendimento nesses challenges. Mas, claro, precisamos estudar e pegar dicas que irão nos ajudar nesse processo. Então, vou listar abaixo o meu processo de aprendizado para essa finalidade:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.hackerrank.com/domains/tutorials/30-days-of-code" rel="noopener noreferrer"&gt;30 Days of Code - Hackerrank&lt;/a&gt;: o Hackerrank é uma dessas plataformas utilizadas pelas empresas para avaliar seu conhecimento através dos code challenges. Mas, um dos grandes diferenciais dela é que você tem à disposição uma lista de challenges para fazer na hora que você quiser. São organizados por linguagem, conceito, nível de dificuldade, etc. E para começar do zero, recomendo demais o &lt;strong&gt;30 Days of Code&lt;/strong&gt; que vai explicando desde um simples "Hello World" até temas mais complexos como filas, pilhas, árvores binárias, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://app.codility.com/programmers/lessons/1-iterations/" rel="noopener noreferrer"&gt;Codility&lt;/a&gt;:  o Codility tem o mesmo propósito do anterior, mas sua parte de aprendizado é um pouco menor, além de ter um foco bem forte em &lt;strong&gt;algoritmos&lt;/strong&gt;. Nos exercícios a gente encontra o algoritmo de Euclides, Fibonacci, Crivo de Eratóstenes, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Livro &lt;a href="https://www.youtube.com/watch?v=4-A07R_B8sU" rel="noopener noreferrer"&gt;Estrutura de Dados e Algoritmos em Javascript&lt;/a&gt;: esse livro é, de longe, a melhor &lt;strong&gt;referência do assunto em língua portuguesa&lt;/strong&gt;. Apesar de ser focado em uma linguagem (Javascript), a autora aborda o tema de uma forma tão ditática e simples, que mesmo quem não conhece Javascript, terá facilidade com o conteúdo aqui apresentado.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcnzjzr01o31nn10u9rv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcnzjzr01o31nn10u9rv.jpg" width="292" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essas foram as dicas de hoje. Se você conhecer mais alguma plataforma e/ou livro que possa ajudar nessa jornada, compartilhe conosco. :)&lt;/p&gt;

</description>
      <category>remote</category>
      <category>devlife</category>
    </item>
  </channel>
</rss>
