Olá, pessoal, boas-vindas à Alura. Meu nome é Vinícius Dias e eu vou guiar vocês nesse treinamento de padrões de projetos estruturais utilizando PHP.
Nessa classe de padrões vamos ver alguns padrões, algumas formas de desenvolver que farão com que consigamos montar objetos e classes em estruturas maiores, mas mantendo isso flexível, extensível e principalmente manutenível.
Ou seja, não vamos estragar nosso código ao unir classes para formar estruturas maiores. Veremos como montar estruturas de classe bem interessantes.
Vamos começar pelo Adapter. Veremos como ter uma implementação que faz requisições HTTP utilizando componentes diferentes, utilizando cURL
, file_get_contents
contentes, o que for; isso não importa para nossa regra de negócio.
Veremos como gerar um relatório bastante interessante onde podemos salvar um orçamento ou um pedido em XML, em ZIP ou qualquer outro formato, organizando essa estrutura de forma que nossas classes não cresçam para sempre.
Veremos como representar nossos objetos, como são nossos orçamentos e itens de orçamento como uma árvore, e conseguiremos percorrer por toda essa árvore até pegar o valor total desse orçamento. Vamos aprender como adicionar comportamento em tempo de execução utilizando o Decorator.
Vamos ver sobre o Facade, que é um padrão bastante polêmico que hoje em dia seu nome tem sido citado bastante, embora nem sempre tenha sido aplicado da forma mais pura, vamos dizer assim. É um padrão onde fornecemos uma API mais simples para uma parte de um sistema mais complexo.
Veremos como poupar memória com o Flyweight e porque isso nem sempre é uma boa ideia. E veremos como interceptar acesso a objetos utilizando Proxy. Enfim, veremos bastantes padrões de projeto nesse treinamento, então já pega sua xícara de café e vem para o próximo vídeo para já começarmos a colocar a mão na massa.
Já te adianto que caso fique alguma dúvida durante esse treinamento você pode ficar à vontade. Não hesite, abra uma dúvida aqui no fórum da Alura. Eu tento responder pessoalmente sempre que eu posso, mas quando eu não consigo a nossa comunidade é bastante solícita e nossas alunas, alunos e moderadores estão sempre prontos e dispostos a ajudar. Espero que você aproveite bastante e, mais uma vez, te espero no próximo vídeo para colocarmos a mão na massa.
Bem-vindos de volta e vamos dar uma olhada no nosso projeto. Caso você não tenha feito nosso treinamento de padrões de projeto comportamentais, recomendo que você faça, porque construímos esse projeto e já aprendemos vários padrões de projeto. E agora daremos continuidade no mesmo projeto, aprendendo os padrões estruturais.
Então temos uma classe de orçamento, que foi onde tudo começou. E nessa classe de orçamento temos “quantidade de itens; valor; o estado atual”, então temos o padrão state sendo aplicado, bastante coisa.
E temos descontos sendo aplicados, impostos sendo aplicados, vários impostos, vários descontos possíveis, temos ações ao gerar um pedido. Para isso temos obviamente um pedido, então bastante coisa já aconteceu.
Só que o que queremos fazer agora é pegar um orçamento, e depois que ele for finalizado precisamos chamar uma API para registrar esse orçamento. Porque nessa API algumas regras de negócio acontecem, o que não importa para essa aplicação, mas sabemos que precisamos chamar essa API.
Então vou criar uma nova classe para chamar essa API de “registro de orçamento”. Vou colocar na raiz mesmo. Como eu já comentei no treinamento anterior, eu não estou organizando as pastas direito como poderia para não perdermos tempo pensando na arquitetura e podermos focar nos padrões.
Então temos a classe RegistroOrcamento
. Eu vou criar uma nova função chamada registrar
, que recebe um orçamento e não devolve nada: public function registrar(Orcamento $orcamento): void
.
Então eu preciso chamar uma API de registro. E enquanto eu chamo essa API eu preciso enviar os dados do orçamento.
Então vamos implementar isso. Como eu vou enviar os dados do orçamento nessa chamada de API de registro? Como eu chamo uma API utilizando PHP? Existem várias formas. A mais simples: eu poderia fazer um file_get_contents(filename: 'http://api.registrar.orcamento');
.
Assim eu consigo chamar essa API, mas por padrão essa requisição vai ser do verbo GET, e o que estamos fazendo teria que ser uma requisição do verbo POST, do HTTP. Se você não está entendendo isso, existem cursos de HTTP muito bons na Alura, mas esse não é o foco do treinamento.
Mas a questão é: por padrão essa requisição não é o suficiente. Então eu teria que trabalhar com contextos de stream para definir o corpo da mensagem, o verbo. Eu não vou trabalhar com isso. Nós temos um treinamento de streams também, que fala sobre isso, mas eu acho isso um pouco complexo.
Então eu posso usar, por exemplo, o cURL
. Eu sei que com curl_init
eu inicializo um objeto do cURL
, e eu posso passar os dados do post. Só que eu não me lembro de cabeça como trabalhar com cURL. A API dele, as funções são um pouco complexas de lembrar. Então eu poderia, por exemplo, utilizar o Guzzle, que é uma biblioteca que podemos instalar com o Composer.
Então repare que existem várias formas de implementar e isso é um detalhe de infraestrutura. Ele não deveria estar junto com essa minha classe RegistroOrcamento
. Essa minha classe chama uma API. Agora, como essa requisição HTTP será feita por baixo dos panos não me importa.
Então o que eu quero fazer é ter uma classe específica, seja lá qual ela for, para realizar uma requisição HTTP genérica; e essa classe de registro de orçamento vai utilizar essa outra classe que faz uma requisição HTTP para realizar a requisição em si.
Então o que eu quero é separar as responsabilidades para, independente de qual for a implementação, seja com file_get_contents
, com cURL
, com Guzzle, pegar esse adaptador de uma requisição HTTP e utilizar no meu registro de orçamento. É isso que faremos no próximo vídeo.
Bem-vindos de volta. Como eu comentei, precisamos criar essa classe específica que vai adaptar algum detalhe de infraestrutura, alguma forma de fazer uma requisição HTTP para uma interface comum, para o meu registro de orçamento não se importar com como isso vai ser chamado.
Então para isso eu vou criar uma nova pasta que vou chamar de “Http”, não precisa ter um nome muito mais claro do que isso.
E primeiro eu preciso criar essa interface, o contrato que será atendido. Vou chamar de “HttpAdapter”, porque é o adaptador de como fazer uma chamada HTTP.
Eu só vou criar o método que eu preciso, que é public funcion post(string $url, array $data = []): void;
. É só isso que eu preciso por enquanto, ele não vai retornar nada.
Você poderia, obviamente, criar de forma mais genérica, onde ele devolveria resposta e esse tipo de coisa. Mas para o nosso caso isso já é totalmente suficiente.
Agora no meu registro de orçamento eu vou precisar no meu “Construtor” receber algum HTTP Adapter: public function _construct(HttpAdapter $http)
. Vou criar uma propriedade.
Lembrando que se você não estiver utilizando PHP Storm, você pode só criar essa propriedade privada private HttpAdapter $http;
e inicializar o que receber do “Construtor”.
Mas utilizando o PHP Storm é só dar “Alt + Enter” e “Initialize field”, que ele já cria a propriedade para nós. Então criei. Tenho algum adaptador de requisição HTTP, então agora posso fazer $this->http->post(url ‘http://api.registrar.orcamento’ [
.
E dentro eu mando os dados desse orçamento, que tem o estado atual, quantidade de itens e valor: [‘valor’ => $orcamento->valor, ‘quantidadeItens’ => $orcamento->quantidadeItens
.
E como eu disse, só vamos registrar um orçamento quando ele já estiver finalizado. Então eu posso até verificar: if (!$orcamento->estadoAtual instanceof Finalizado)
. Se não for desse estado posso lançar uma exceção: throw new \DomainException(message: ‘Apenas orçamentos finalizados podem ser registrados na API’);
.
Então vamos recapitular o que fizemos. Nós criamos uma interface de algum adaptador HTTP. Ou seja, pode ser com file_get_contents
, pode ser com cURL
, com Guzzle, com React PHP, com qualquer biblioteca que faça requisições HTTP.
Então como essa interface criada para atender os nossos objetivos, para atender o que o meu registro de orçamento espera, eu recebo agora alguma implementação dessa interface. Recebendo essa implementação, eu consigo fazer o registro do meu orçamento.
Só que essa classe é responsável pela regra de negócio de registrar. Então ela pode ter suas regras, suas verificações, e utiliza alguma implementação dessa interface para realizar a ação em si.
Então já temos um “Adapter”. Vamos criar uma implementação fictícia. Eu poderia ter, por exemplo, um “CurlHttpAdapter”.
Como eu falei, eu não me lembro exatamente como utilizar o cURL
de cabeça, eu teria que pesquisar. Então, vou criar uma implementação fictícia. Eu teria um recurso do cURL
, retornado pelo curl_init
para a URL definida: $curl = curl_init($url);
.
Eu sei que o cURL vai ter um setopt
, e dentro eu passo várias opções, como CURLOPT_POST
, e passo os dados: curl_setopt($curl, option:CURLOPT_POST, $data);
.
Vou passar todas as opções que eu teria que passar, e no final eu faria um curl_exec($curl);
. Eu executaria essa requisição.
Eu tenho uma implementação totalmente válida. E se eu quiser testar isso, se eu quiser fazer um registro de orçamento, vou criar um arquivo chamado “registro-orcamento”. Obviamente isso não vai funcionar na prática porque não temos essa API. Mas eu só vou mostrar que o código funciona. Então require ‘vendor/autoload.php’;
. Eu preciso de um registro de orçamento: $registroOrcamento = new RegistroOrcamento();
.
Talvez você não esteja vendo, mas o PHP Storm já está deixando isso um pouco mais claro, informando que você precisa de um parâmetro que é um HTTP Adapter. Então eu posso muito bem passar o CurlHttpAdapter
.
E pronto, eu posso agora com meu registro de orçamento registrar algum orçamento. Só que agora o cURL
está ficando um pouco lento, preciso de uma implementação assíncrona, então vou utilizar o React PHP. Veremos no próximo vídeo como isso fica fácil.
O curso Design Patterns em PHP: padrões estruturais possui 116 minutos de vídeos, em um total de 63 atividades. Gostou? Conheça nossos outros cursos de PHP em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.