S.O.L.I.D. com Java na prática: Single Responsability Principle (Parte 1/5)
- #Java
Aproveitando os ensinamentos do curso Aprenda sobre S.O.L.I.D. com Java e o gancho desse artigo publicado recentemente pelo Klênisson Ribeiro, o objetivo deste artigo é mostrar na prática como uma classe com várias responsabilidades poderia ser refatorada seguindo o primeiro princípio do S.O.L.I.D.: o Single Responsability Principle, o qual determina que uma classe deve ter uma única responsabilidade no software.
Observe a classe Order e perceba quantas e quais responsabilidades ela possui.
//file Order.java
public class Order {
private List<Product> products = new ArrayList<>();
public void addProduct(Product product) {
products.add(product);
}
public void removeProduct(Product product) {
products.remove(product);
}
public BigDecimal calculateTotal() {
return products.stream()
.map(Product::getValue)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
public List<Order> searchOrders() {
//return the list from the database
}
public void saveOrder(Order order) {
//save order on the database
}
public void sendEmail(Order order, String email) {
//send email
}
public void printOrder(Order order) {
//print the order
}
}
Ela administra ações que vão além da lista de Produtos, sendo, por exemplo, responsável também por buscar a lista de ordens na base de dados, enviar email, imprimir ordem de compra. Para evitar que essa classe seja uma "God Class", podemos distribuir essas responsabilidades criando novas classes.
Abaixo é possível ver como o código poderia ficar se o Single Responsability Principle fosse seguido:
1. A classe Order tem a responsabilidade de administrar somente o que tem relação com a ordem de compra/venda.
//file Order.java
public class Order {
private List<Product> products = new ArrayList<>();
public void addProduct(Product product) {
products.add(product);
}
public void removeProduct(Product product) {
products.remove(product);
}
public BigDecimal calculateTotal() {
return products.stream()
.map(Product::getValue)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
2. A classe OrderRepository tem a responsabilidade de administrar tudo o que tem relação com a base de dados.
//file OrderRepository.java
public class OrderRepository {
public List<Order> searchOrders() {
//return the list from the database
}
public void saveOrder(Order order) {
//save order on the database
}
}
3. A classe OrderMail tem a responsabilidade de administrar o envio de emails.
//file OrderMail.java
public class OrderMail {
public void sendEmail(Order order, String email) {
//code to send email
}
}
4. A classe OrderPrint tem a responsabilidade de administrar a impressão de ordens.
//file OrderPrint.java
public class OrderPrint {
public void printOrder(Order order) {
//code to print the order
}
}
Com a refatoração e seguindo o primeiro princípio do S.O.L.I.D., conseguimos deixar o código mais claro e também mais fácil de se manter e testar.