https://flocus.io/minimalist-pomodoro-timer
Escreva suas anotações aqui
Solid é composto de cinco princípios de projeto, que possue o objetivo de fazer programas mais compreensíveis, flexíveis e sustentáveis, sendo boas práticas que garantem diversos benefícios
”S” Single Responsibility Principle (SRP)
O Princípio de responsabilidade única define que uma classe deve ter apenas uma razão para mudar
Esse principio diz que uma classe, componente, entidade e até mesmo funções devem ter uma única responsabilidade, onde para cada responsabilidade do seu sistema, você tem uma entidade que sabe apenas fazer aquilo na que é especializada.
”Quais são os beneficios de programar dessa forma?”
Com entidades independentes e isoladas, você consegue reaproveitar o código com mais facilidade, refatorar mais facilmente, facilita a implementação de testes automatizados e gera menos bugs. Por ser isolado permite a resolução de bugs de forma mais fácil e específica, sem alterar outras funcionalidades no seu código.
Como cada responsabilidade vai estar isolada, você precisa se concentrar apenas naquele pedaço de código, podendo evoluir no passo a passo constante até terminar tudo.
“Como saber onde começa e termina a responsabilidade de um componente?”
Uma boa prática é tentar colocar no nome de uma função ou componente a respesctiva responsabilidade dele no seu sistema. Caso o nome fique muito grande, ou seja com muitas responsabilidades, é um ponto onde deve ser feito a separação (na analogia de roupas, seriam duas máquinadas diferente, separando a clara das coloridas)
Exemplo Ruim
class Task {
constructor(private description: string, private user: User) {}
completeTask() {
if (this.user.isLoggedIn()) {
// Lógica para marcar a tarefa como concluída
}
}
getUser(): User {
return this.user;
}
}
Exemplo Bom
class Task {
constructor(private description: string, private user: User) {}
completeTask() {
if (this.user.isLoggedIn()) {
// Lógica para marcar a tarefa como concluída
}
}
}
class UserAuth {
constructor(private user: User) {}
isLoggedIn(): boolean {
// Lógica para verificar se o usuário está logado
}
}
class User {
// Implementação da classe User
}
“O” Open-Closed Principle (OCP)
Princípio aberto/fechado, onde os objetos devem estar disponíveis para extensão, mas fechados para modificação
Esse princípio tem como definição a ideia de que, usuários podem adicionar novas funcionalidades sem mudar o código já existente
Utilizando o exemplo do robô, a versão errada indica que:
Para cada novo requisito que o sistema receba, tem que ser modificado a entidade, ou para cada cada situação diferente que essa entidade se encontre, tenha que mudar seu comportamento interno com algum if, gerando um novo caminho dentro do código, gerando uma bola de neve, onde para cada novo requisito que seja implementado, vai surgir uma nova condicional e cada vez mais vai ficar confuso a compreensão e manutenção do código. Visualizar da forma onde para cada tipo de função nova que entrar, você vai ter que além de implemetar ele, implementar e modificar o componente base, o que acaba “manchando” outros componentes
“Como resolver isso?”
Ao utilizar o nível certo de abstração correto, o componente base não precisa saber os campos específicos das outras funcionalidades.Se todos os objetos que você jogar respeitarem essa mesma interface, a classe base nunca mais vai precisar ser modificada quando forem implementados novos métodos
“Analógia de Plugins”
Um bom exemplo de como funciona o OCP, são como quando você instala extensões no seu navegador, onde você traz novas funcionalidades para ele, porém não altera nada no código fonte do seu navegador. Onde o navegador está "Open” para estender novas funcionalidades e o binário está “Closed”
“L” Liskov Substitution Principle
Princípio de substituição de Liskov: Uma subclassse deve ser substituível por sua superclasse
O princípio ele defende que se temos uma classe e através dela criarmos uma subclasse utilizando herança, onde o objeto ou instância resultante dessa subclasse consiga substituir a classe pai. Respeitar o príncipio de liskov força seu programa a ter abstrações no nível certo, o que garante maior consistência.
Esse príncipio vai te forçar a pensar o que realmente a classe pai deveria fornecer de comum com as outras sub classes
“I” Interface Segregation Principle (ISP)
Prinicípio de segregação de interface, uma classe não deve ser obrigada a implementar métodos e interfaces que não serão utilizadas
Esse príncipio diz que clientes não devem depender de métodos que eles não utilizam, onde cada interface vai estar segregada e separada, permitindo que as interfaces executem a função na qual eles tem acesso e possam executar
“D” Dependency Inversion Principle (DIP)
Princípio de inversão de dependência, dependa de abstrações e não de implementações
Um módulo não deve depender de detalhes de implementação de outro módulo diretamente, deve existir uma adpatação (interface), entre eles.