logo

Princípios SOLID Java

Em Java, Princípios SÓLIDOS são uma abordagem orientada a objetos aplicada ao projeto de estrutura de software. É conceituado por Roberto C. Martin (também conhecido como Tio Bob). Esses cinco princípios mudaram o mundo da programação orientada a objetos e também mudaram a forma de escrever software. Também garante que o software seja modular, fácil de entender, depurar e refatorar. Nesta seção, discutiremos Princípios SÓLIDOS em Java com exemplo adequado .

A palavra SOLID é um acrônimo para:

  • Princípio de Responsabilidade Única (SRP)
  • Princípio Aberto-Fechado (OCP)
  • Princípio de Substituição de Liskov (LSP)
  • Princípio de segregação de interface (ISP)
  • Princípio de Inversão de Dependência (DIP)
Princípios SÓLIDOS Java

Vamos explicar os princípios um por um em detalhes.

Princípio de Responsabilidade Única

O princípio da responsabilidade única afirma que cada classe Java deve executar uma única funcionalidade . A implementação de múltiplas funcionalidades em uma única classe faz um mashup do código e se alguma modificação for necessária pode afetar toda a classe. Ele precisa o código e o código pode ser facilmente mantido. Vamos entender o princípio da responsabilidade única através de um exemplo.

Suponha, Estudante é uma classe que possui três métodos, a saber printDetails(), calcularPercentage(), e addAluno(). Conseqüentemente, a classe Aluno tem três responsabilidades: imprimir os detalhes dos alunos, calcular porcentagens e banco de dados. Ao utilizar o princípio da responsabilidade única, podemos separar estas funcionalidades em três classes distintas para cumprir o objetivo do princípio.

Aluno.java

 public class Student { public void printDetails(); { //functionality of the method } pubic void calculatePercentage(); { //functionality of the method } public void addStudent(); { //functionality of the method } } 

O trecho de código acima viola o princípio da responsabilidade única. Para atingir o objetivo do princípio, devemos implementar uma classe separada que execute apenas uma única funcionalidade.

Aluno.java

 public class Student { public void addStudent(); { //functionality of the method } } 

PrintStudentDetails.java

 public class PrintStudentDetails { public void printDetails(); { //functionality of the method } } 

Porcentagem.java

 public class Percentage { public void calculatePercentage(); { //functionality of the method } } 

Conseqüentemente, alcançamos o objetivo do princípio da responsabilidade única, separando a funcionalidade em três classes distintas.

Princípio Aberto-Fechado

A aplicação ou módulo entidade os métodos, funções, variáveis, etc. O princípio aberto-fechado afirma que de acordo com novos requisitos o módulo deve estar aberto para extensão, mas fechado para modificação. A extensão nos permite implementar novas funcionalidades ao módulo. Vamos entender o princípio através de um exemplo.

Suponha, Informações do veículo é uma classe e tem o método número do veículo() que retorna o número do veículo.

VeículoInfo.java

urfi javed
 public class VehicleInfo { public double vehicleNumber(Vehicle vcl) { if (vcl instanceof Car) { return vcl.getNumber(); if (vcl instanceof Bike) { return vcl.getNumber(); } } 

Se quisermos adicionar outra subclasse chamada Truck, simplesmente adicionamos mais uma instrução if que viola o princípio aberto-fechado. A única maneira de adicionar a subclasse e atingir o objetivo principal substituindo o número do veículo() método, como mostramos abaixo.

VeículoInfo.java

 public class VehicleInfo { public double vehicleNumber() { //functionality } } public class Car extends VehicleInfo { public double vehicleNumber() { return this.getValue(); } public class Car extends Truck { public double vehicleNumber() { return this.getValue(); } 

Da mesma forma, podemos adicionar mais veículos criando outra subclasse estendendo-se da classe de veículos. a abordagem não afetaria a aplicação existente.

Princípio da Substituição de Liskov

O Princípio da Substituição de Liskov (LSP) foi introduzido por Bárbara Liskov . Aplica-se à herança de tal forma que o classes derivadas devem ser completamente substituíveis por suas classes base . Em outras palavras, se a classe A for um subtipo da classe B, então deveremos ser capazes de substituir B por A sem interromper o comportamento do programa.

Estende o princípio open-close e também foca no comportamento de uma superclasse e seus subtipos. Devemos projetar as classes para preservar a propriedade, a menos que tenhamos uma forte razão para fazer o contrário. Vamos entender o princípio através de um exemplo.

bash para loop 1 a 10

Aluno.java

 public class Student { private double height; private double weight; public void setHeight(double h) { height = h; } public void setWeight(double w) { weight= w; } ... } public class StudentBMI extends Student { public void setHeight(double h) { super.setHeight(h); super.setWeight(w); } public void setWeight(double h) { super.setHeight(h); super.setWeight(w); } } 

As classes acima violaram o princípio de substituição de Liskov porque a classe StudentBMI tem restrições extras, ou seja, altura e peso que devem ser iguais. Portanto, a classe Student (classe base) não pode ser substituída pela classe StudentBMI (classe derivada).

Portanto, substituir a classe Student pela classe StudentBMI pode resultar em comportamento inesperado.

Princípio de segregação de interface

O princípio afirma que as interfaces maiores se dividem em interfaces menores. Porque as classes de implementação usam apenas os métodos necessários. Não devemos forçar o cliente a usar métodos que ele não deseja.

O objetivo do princípio de segregação de interfaces é semelhante ao princípio de responsabilidade única. Vamos entender o princípio através de um exemplo.

Princípios SÓLIDOS Java

Suponha que criamos uma interface chamada Conversão tendo três métodos intToDouble(), intToChar(), e charToString() .

 public interface Conversion { public void intToDouble(); public void intToChar(); public void charToString(); } 

A interface acima possui três métodos. Se quisermos usar apenas um método intToChar(), não temos escolha para implementar o método único. Para superar o problema, o princípio nos permite dividir a interface em três interfaces distintas.

 public interface ConvertIntToDouble { public void intToDouble(); } public interface ConvertIntToChar { public void intToChar(); } public interface ConvertCharToString { public void charToString(); } 

Agora podemos usar apenas o método necessário. Suponha que queremos converter o número inteiro em duplo e o caractere em string, então usaremos apenas os métodos intToDouble() e charToString().

 public class DataTypeConversion implements ConvertIntToDouble, ConvertCharToString { public void intToDouble() { //conversion logic } public void charToString() { //conversion logic } } 

Princípio de Inversão de Dependência

O princípio afirma que devemos usar abstração (classes e interfaces abstratas) em vez de implementações concretas. Os módulos de alto nível não devem depender do módulo de baixo nível, mas ambos devem depender da abstração. Porque a abstração não depende do detalhe, mas o detalhe depende da abstração. Ele desacopla o software. Vamos entender o princípio através de um exemplo.

 public class WindowsMachine { //functionality } 

Vale a pena, caso não tenhamos teclado e mouse para funcionar no Windows. Para resolver este problema, criamos um construtor da classe e adicionamos as instâncias do teclado e do monitor. Depois de adicionar as instâncias, a classe terá a seguinte aparência:

 public class WindowsMachine { public final keyboard; public final monitor; public WindowsMachine() { monitor = new monitor(); //instance of monitor class keyboard = new keyboard(); //instance of keyboard class } } 

Agora podemos trabalhar na máquina Windows com a ajuda de teclado e mouse. Mas ainda enfrentamos o problema. Porque unimos fortemente as três classes usando a nova palavra-chave. É difícil testar a máquina Windows da classe.

Para tornar o código fracamente acoplado, desacoplamos o WindowsMachine do teclado usando a interface Keyboard e esta palavra-chave.

Teclado.java

 public interface Keyboard { //functionality } 

WindowsMachine.java

 public class WindowsMachine { private final Keyboard keyboard; private final Monitor monitor; public WindowsMachine(Keyboard keyboard, Monitor monitor) { this.keyboard = keyboard; this.monitor = monitor; } } 

No código acima, usamos a injeção de dependência para adicionar a dependência do teclado na classe WindowsMachine. Portanto, dissociamos as classes.

Princípios SÓLIDOS Java

Por que devemos usar princípios SOLID?

  • Reduz as dependências para que um bloco de código possa ser alterado sem afetar os outros blocos de código.
  • Os princípios pretendiam tornar o design mais fácil e compreensível.
  • Ao usar os princípios, o sistema é passível de manutenção, testável, escalonável e reutilizável.
  • Evita o mau design do software.

Da próxima vez que você projetar software, tenha esses cinco princípios em mente. Ao aplicar esses princípios, o código será muito mais claro, testável e dispensável.