Olá! Meu nome é Guilherme e trabalho com tecnologia há mais de 7 anos, em diferentes empresas, desde startups até grandes companhias. Já atuei como engenheiro de dados, engenheiro de software, líder técnico e, atualmente, estou como arquiteto de soluções.
Audiodescrição: Guilherme é uma pessoa parda com cabelos escuros e olhos castanhos. À sua direita, há uma luz refletindo azul com uma lousa, além de uma representação do funk pop entre a briga do Naruto e do Sasuke. À sua esquerda, está sua cama e um teclado musical.
No curso, iremos abordar como o SOLID funciona e como podemos colocá-lo em prática em nossos projetos. Iremos analisar letra por letra, entendendo como as abstrações são a chave para construir um projeto robusto.
A engenharia de software, ao contrário de outras engenharias que são mais rígidas, é mais volátil. O software pode ser comparado a um organismo vivo, que muda constantemente. As abstrações e fundamentos de engenharia de software, como o SOLID, nos ajudam a construir algo mais duradouro, que está preparado para as mudanças que ocorrerão ao longo do tempo.
Para nos apoiar, vamos explorar esse projeto na prática, abordando o carrinho de compras de um e-commerce, para que possamos entender como realmente funciona e como podemos implementar em nosso dia a dia. Além dos vídeos, teremos atividades e o fórum para eventuais dúvidas.
Vamos aprender mais sobre engenharia de software e seus fundamentos? Estamos aguardando vocês!
Já imaginamos ter que participar de uma partida de futebol e realizar um cruzamento e cabeceio ao mesmo tempo? Ou, ainda pior, adquirir um veículo que possui apenas um único pedal, onde um toque significa acelerar e dois toques significam frear? Imagine o caos que isso causaria. Não existe atacante que também seja goleiro. Esses exemplos são claros, mas continuamos desenvolvendo códigos extremamente complexos, com inúmeras responsabilidades concentradas em um único local.
Se ainda não enfrentamos esse tipo de código ou problema, é provável que o façamos em nossa carreira, pois é bastante comum ao construir um software. Muitas vezes, começamos a atribuir tarefas a um único local, onde tudo se originou. Assim, surge o que chamamos de "classe Deus", que possui inúmeras responsabilidades e é gigantesca. No entanto, o grande problema não é o tamanho ou a quantidade de linhas do código, mas sim o que ele se propõe a fazer.
Imagine que estamos construindo uma plataforma para uma concessionária online. Inicialmente, o veículo possui placa, registro, descrição, cor, modelo, entre outros aspectos simples. No entanto, novas funcionalidades surgem. O gerente de produto nos apresenta novos requisitos, como verificar quantos veículos estão em estoque, qual é o preço, o custo de logística para transportar o carro até o cliente, quantas multas o carro possui, se há IPVA atrasado, entre outras responsabilidades. Isso pode gerar dúvidas.
Quando iniciamos um projeto, podemos concentrar tudo em um único local, em uma única classe. Com o tempo, essa classe começa a perder sua origem e propósito. Embora o domínio ainda seja o veículo, e a descrição e o preço estejam diretamente relacionados a ele, os débitos veiculares estão vinculados à placa e ao registro, mas não necessariamente precisam estar no mesmo local.
Esse tipo de problema dificulta a manutenção. Quando precisamos alterar débitos veiculares, o veículo pode deixar de aparecer na tela do e-commerce.
Onde está o problema? Como podemos resolver esse tipo de questão? Surge então o conceito de Single Responsibility, que afirma que uma única responsabilidade deve ser atribuída a uma classe. No livro Clean Architecture, essa abordagem é apresentada de forma um pouco diferente, sugerindo que uma classe deve ter um único ator para modificá-la. Por exemplo, se estamos falando de um veículo, a classe deveria ser responsável apenas por aspectos relacionados ao veículo, como descrição, renascimento, placa, modelo, ano, quilometragem, entre outros.
Se surgir uma nova responsabilidade, mesmo que esteja relacionada ou próxima à classe existente, ela deveria ser separada em uma nova classe. Um exemplo disso são os débitos veiculares. Podemos ter débitos que alteram a placa, como DPVAT, IPVA, multas e afins. Cada um desses tipos pode estar ativo ou inativo, com sua própria responsabilidade e lógica.
Perceba que não estamos falando de ter uma única responsabilidade no sentido de ter uma única função. No caso dos débitos, temos multas e IPVA, que são teoricamente diferentes, mas ambos são valores que descontamos do que vamos cobrar do veículo. Mesmo que sejam débitos diferentes, eles estão no mesmo lugar, pois não se trata de ter uma única responsabilidade nesse sentido, mas sim de convergir para uma única mudança. Se estamos alterando um local para mais de um ator, isso não deveria ocorrer.
O Single Responsibility nos ajuda a separar nosso projeto. No próximo vídeo, veremos isso na prática, aplicando em um software que nasce grande, com várias responsabilidades, e decidindo corretamente onde cada parte do projeto deve ficar. Vamos focar na prática, aplicando em um carrinho de compras, onde encontraremos um software com inúmeras responsabilidades e o quebraremos em partes menores. Escolheremos corretamente onde cada funcionalidade deve ficar, identificando os microdomínios e subdomínios dentro do nosso domínio.
Para isso, utilizaremos um e-commerce fictício e escolheremos especificamente um microserviço de carrinho como nosso domínio de trabalho. Iremos montar as classes corretas para eles, com suas respectivas responsabilidades. Nos encontramos no próximo vídeo.
Agora vamos discutir como aplicar o princípio da Responsabilidade Única na prática. Este é o nosso projeto de carrinho, que começa com a criação do arquivo main.py
na raiz do projeto. Vamos abri-lo. Nele, encontramos duas classes que serão utilizadas ao longo do projeto, e vamos dividi-las em partes menores.
Temos uma classe que representa os produtos a serem adicionados ao carrinho, contendo nome, preço, tipo e descrição, que será adicionada posteriormente. Além disso, temos a classe carrinho, que possui algumas funcionalidades.
Para começar, vamos definir a estrutura básica do nosso projeto. Primeiro, criamos uma lista que funcionará como nosso banco de dados fictício:
database = []
Agora, vamos criar a classe Produto
. Inicialmente, definimos o método __init__
para inicializar a classe com os atributos básicos: nome
, preco
e tipo
.
class Produto:
def __init__(self, nome, preco, tipo):
self.nome = nome
self.preco = preco
self.tipo = tipo
Em seguida, definimos a classe Carrinho
, que terá funcionalidades como adicionar e remover produtos, calcular descontos, finalizar compras e notificar clientes.
class Carrinho:
def __init__(self):
self.items = []
self.total = 0
O método adicionar
permite inserir novos produtos no carrinho, realizando um append
na lista de itens e atualizando o total.
def adicionar(self, produto):
self.items.append(produto)
self.total += produto.preco
if produto.tipo == 'perecivel':
print("Adicionar embalagem especial")
elif produto.tipo == 'digital':
print("Gerar link de download")
else:
print("Produto adicionado ao carrinho")
O método remover
verifica se o produto está no carrinho e o remove, atualizando o total.
def remover(self, produto):
if produto in self.items:
self.items.remove(produto)
self.total -= produto.preco
print(f"{produto.nome} removido do carrinho.")
else:
print(f"{produto.nome} não está no carrinho.")
Podemos calcular descontos aplicando cupons específicos, como BLACKFRIDAY
ou NATAL
.
def calcular_desconto(self, cupom):
if cupom == 'BLACKFRIDAY':
self.total *= 0.5
elif cupom == 'NATAL':
self.total *= 0.9
else:
print("Cupom inválido")
O método finalizar_compra
exibe o total a pagar, salva os itens no banco de dados e envia uma confirmação por e-mail.
def finalizar_compra(self):
print(f"Total a pagar: R${self.total}")
self.salvar_database()
print("Email enviado com confirmação!")
Este método salva os itens do carrinho no banco de dados fictício.
def salvar_database(self):
database.append(self.items)
print("Itens do carrinho salvos no banco")
Podemos enviar notificações para o cliente via SMS, e-mail ou WhatsApp.
def send_sms(self, mensagem):
print(mensagem)
def send_email(self, mensagem):
print(mensagem)
def send_whatsapp(self, mensagem):
print(mensagem)
def notificar_cliente(self, itens, total, canal):
message = f"Seus {itens}, estão a caminho, já debitamos R${total} do seu cartão"
if canal == "sms":
self.send_sms(message)
elif canal == "email":
self.send_email(message)
elif canal == "whatsapp":
self.send_whatsapp(message)
else:
raise TypeError("modelo ainda não suportado")
Agora, vamos aprimorar a classe Produto
adicionando novos atributos e métodos. Vamos criar um método __init__
mais completo, que inclui SKU
, preço
, descrição
e quantidade de estoque
.
class Produto:
def __init__(self, sku, preco, descricao, qtd_estoque):
self._sku = sku
self._preco = preco
self._descricao = descricao
self._qtd_estoque = qtd_estoque
Vamos criar métodos para acessar os atributos de forma segura.
def get_preco(self):
return self._preco
def get_estoque(self):
if self._qtd_estoque > 0:
result = True
else:
result = False
return result
def get_product(self):
return {
"sku": self._sku,
"preco": self._preco,
"descricao": self._descricao,
"qtd_estoque": self._qtd_estoque
}
Com essas melhorias, nosso projeto está mais robusto. No próximo vídeo, trabalharemos na classe carrinho, onde começaremos a detalhar suas funcionalidades, identificando quais devem ou não ser implementadas.
O curso Princípios SOLID com Python: construindo códigos eficientes e escaláveis possui 223 minutos de vídeos, em um total de 63 atividades. Gostou? Conheça nossos outros cursos de Python 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
Matricule-se no plano PLUS e garanta:
Mobile, Programação, Front-end, DevOps, UX & Design, Marketing Digital, Data Science, Inovação & Gestão, Inteligência Artificial
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ê participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas á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.
Para estudantes ultra comprometidos atingirem seu objetivo mais rápido.
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.
Conecte-se ao mercado com mentoria personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.