diff --git a/src/Desafio3/loja/envio/EnvioCorreios.java b/src/Desafio3/loja/envio/EnvioCorreios.java new file mode 100644 index 0000000..aa29b20 --- /dev/null +++ b/src/Desafio3/loja/envio/EnvioCorreios.java @@ -0,0 +1,18 @@ +package Desafio3.loja.envio; + +import Desafio3.loja.interfaces.CalculadorFrete; +import Desafio3.loja.interfaces.ServicoEnvio; +import Desafio3.loja.model.Pedido; + +public class EnvioCorreios implements ServicoEnvio, CalculadorFrete { + @Override + public boolean enviarPedido(Pedido pedido) { + System.out.println("Enviando pedido " + pedido.getId() + " via Correios"); + return true; + } + + @Override + public double calcularFrete(String cep) { + return 15.0; + } +} diff --git a/src/Desafio3/loja/envio/EnvioDrone.java b/src/Desafio3/loja/envio/EnvioDrone.java new file mode 100644 index 0000000..2883a09 --- /dev/null +++ b/src/Desafio3/loja/envio/EnvioDrone.java @@ -0,0 +1,17 @@ +package Desafio3.loja.envio; + +import Desafio3.loja.interfaces.CalculadorFrete; +import Desafio3.loja.interfaces.ServicoEnvio; +import Desafio3.loja.model.Pedido; + +public class EnvioDrone implements ServicoEnvio, CalculadorFrete { + @Override + public boolean enviarPedido(Pedido pedido) { + System.out.println("Enviando pedido " + pedido.getId() + " via Drone"); + return true; + } + + public double calcularFrete(String cep) { + return 50.0; + } +} diff --git a/src/Desafio3/loja/envio/EnvioTransportadora.java b/src/Desafio3/loja/envio/EnvioTransportadora.java new file mode 100644 index 0000000..c39a4c7 --- /dev/null +++ b/src/Desafio3/loja/envio/EnvioTransportadora.java @@ -0,0 +1,18 @@ +package Desafio3.loja.envio; + +import Desafio3.loja.interfaces.CalculadorFrete; +import Desafio3.loja.interfaces.ServicoEnvio; +import Desafio3.loja.model.Pedido; + +public class EnvioTransportadora implements ServicoEnvio, CalculadorFrete { + @Override + public boolean enviarPedido(Pedido pedido) { + System.out.println("Enviando pedido " + pedido.getId() + " via Transportadora"); + return true; + } + + @Override + public double calcularFrete(String cep) { + return cep.startsWith("0") ? 20.0 : 25.0; + } +} diff --git a/src/Desafio3/loja/interfaces/CalculadorDesconto.java b/src/Desafio3/loja/interfaces/CalculadorDesconto.java new file mode 100644 index 0000000..de4e584 --- /dev/null +++ b/src/Desafio3/loja/interfaces/CalculadorDesconto.java @@ -0,0 +1,5 @@ +package Desafio3.loja.interfaces; + +public interface CalculadorDesconto { + double calcularDesconto(double valor); +} diff --git a/src/Desafio3/loja/interfaces/CalculadorFrete.java b/src/Desafio3/loja/interfaces/CalculadorFrete.java new file mode 100644 index 0000000..ea0e295 --- /dev/null +++ b/src/Desafio3/loja/interfaces/CalculadorFrete.java @@ -0,0 +1,5 @@ +package Desafio3.loja.interfaces; + +public interface CalculadorFrete { + double calcularFrete(String cep); +} diff --git a/src/Desafio3/loja/interfaces/NotificadorCliente.java b/src/Desafio3/loja/interfaces/NotificadorCliente.java new file mode 100644 index 0000000..ce374af --- /dev/null +++ b/src/Desafio3/loja/interfaces/NotificadorCliente.java @@ -0,0 +1,5 @@ +package Desafio3.loja.interfaces; + +public interface NotificadorCliente { + void notificarCliente(String mensagem); +} diff --git a/src/Desafio3/loja/interfaces/ProcessadorPagamento.java b/src/Desafio3/loja/interfaces/ProcessadorPagamento.java new file mode 100644 index 0000000..c8b8a91 --- /dev/null +++ b/src/Desafio3/loja/interfaces/ProcessadorPagamento.java @@ -0,0 +1,5 @@ +package Desafio3.loja.interfaces; + +public interface ProcessadorPagamento { + boolean processarPagamento(double valor); +} diff --git a/src/Desafio3/loja/interfaces/ServicoEnvio.java b/src/Desafio3/loja/interfaces/ServicoEnvio.java new file mode 100644 index 0000000..9559fd0 --- /dev/null +++ b/src/Desafio3/loja/interfaces/ServicoEnvio.java @@ -0,0 +1,7 @@ +package Desafio3.loja.interfaces; + +import Desafio3.loja.model.Pedido; + +public interface ServicoEnvio { + boolean enviarPedido(Pedido pedido); +} diff --git a/src/Desafio3/loja/main/SistemaLojaOnline.java b/src/Desafio3/loja/main/SistemaLojaOnline.java new file mode 100644 index 0000000..57efd37 --- /dev/null +++ b/src/Desafio3/loja/main/SistemaLojaOnline.java @@ -0,0 +1,80 @@ +package Desafio3.loja.main; + +import Desafio3.loja.envio.EnvioCorreios; +import Desafio3.loja.envio.EnvioTransportadora; +import Desafio3.loja.model.Pedido; +import Desafio3.loja.notificacao.NotificadorEmail; +import Desafio3.loja.notificacao.NotificadorSMS; +import Desafio3.loja.notificacao.NotificadorWhatsApp; +import Desafio3.loja.pagamento.PagamentoBoleto; +import Desafio3.loja.pagamento.PagamentoCartaoCredito; +import Desafio3.loja.pagamento.PagamentoPix; +import Desafio3.loja.service.GerenciadorPedidos; + +import java.util.List; + +public class SistemaLojaOnline { + public static void main(String[] args) { + System.out.println("=== SISTEMA DE GERENCIAMENTO DE PEDIDOS - APLICANDO SOLID ==="); + + System.out.println("CENÁRIO 1: CARTÃO + CORREIOS + EMAIL"); + + GerenciadorPedidos gerenciador1 = new GerenciadorPedidos( + new PagamentoCartaoCredito(), + new EnvioCorreios(), + new NotificadorEmail(), + new EnvioCorreios() + ); + + List itens1 = List.of("Notebook", "Mouse", "Teclado"); + Pedido pedido1 = new Pedido("001", itens1, 2500.0, "01234-567"); + + gerenciador1.criarPedidos(pedido1); + gerenciador1.enviarPedido("001"); + gerenciador1.listarPedidos(); + + System.out.println("\nCENÁRIO 2: PIX + TRANSPORTADORA + WHATSAPP"); + + GerenciadorPedidos gerenciador2 = new GerenciadorPedidos( + new PagamentoPix(), + new EnvioTransportadora(), + new NotificadorWhatsApp(), + new EnvioTransportadora() + ); + + List itens2 = List.of("Smartphone", "Capinha", "Carregador"); + Pedido pedido2 = new Pedido("002", itens2, 1200.0, "12345-678"); + + gerenciador2.criarPedidos(pedido2); + gerenciador2.enviarPedido("002"); + gerenciador2.listarPedidos(); + + System.out.println("\n CENÁRIO 3: BOLETO + CORREIOS + SMS "); + + GerenciadorPedidos gerenciador3 = new GerenciadorPedidos( + new PagamentoBoleto(), + new EnvioCorreios(), + new NotificadorSMS(), + new EnvioCorreios() + ); + List itens3 = List.of("Livro Java", "Curso Online"); + Pedido pedido3 = new Pedido("003", itens3, 150.0, "87654-321"); + + gerenciador3.criarPedidos(pedido3); + gerenciador3.enviarPedido("003"); + gerenciador3.listarPedidos(); + + + System.out.println("\n DEMONSTRANDO EXTENSIBILIDADE (OCP): "); + System.out.println("Novos métodos de pagamento podem ser adicionados sem modificar código existente"); + System.out.println("Novos serviços de envio podem ser implementados independentemente"); + System.out.println("Novos tipos de de notificação são plug-and-play"); + + System.out.println("\n PRINCÍPIOS SOLID APLICADOS: "); + System.out.println("SRP: Cada Classe tem uma responsabilidade específica"); + System.out.println("OCP: Sistema aberto para extensão, fechado para modificação"); + System.out.println("LSP: Implementações podem ser substituídas sem quebrar o sistema"); + System.out.println("ISP: Interfaces pequenas e focadas"); + System.out.println("DIP: Dependemos de abstrações, não de implementações"); + } +} diff --git a/src/Desafio3/loja/model/Pedido.java b/src/Desafio3/loja/model/Pedido.java new file mode 100644 index 0000000..ae68710 --- /dev/null +++ b/src/Desafio3/loja/model/Pedido.java @@ -0,0 +1,57 @@ +package Desafio3.loja.model; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +public class Pedido { + private String id; + private List itens; + private double valorTotal; + private String status; + private LocalDateTime dataHora; + private String cepDestino; + + public Pedido(String id, List itens, double valorTotal, String cepDestino) { + this.id = id; + this.itens = new ArrayList<>(itens); + this.valorTotal = valorTotal; + this.status = "CRIADO"; + this.dataHora = LocalDateTime.now(); + this.cepDestino = cepDestino; + } + + public String getId() { + return id; + } + + public List getItens() { + return itens; + } + + public double getValorTotal() { + return valorTotal; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public LocalDateTime getDataHora() { + return dataHora; + } + + public String getCepDestino() { + return cepDestino; + } + + @Override + public String toString() { + return String.format("Pedido{id='%s', itens=%s, valor=%.2f, status='%s'}", + id, itens, valorTotal, status); + } +} diff --git a/src/Desafio3/loja/notificacao/NotificadorEmail.java b/src/Desafio3/loja/notificacao/NotificadorEmail.java new file mode 100644 index 0000000..90a8a9d --- /dev/null +++ b/src/Desafio3/loja/notificacao/NotificadorEmail.java @@ -0,0 +1,10 @@ +package Desafio3.loja.notificacao; + +import Desafio3.loja.interfaces.NotificadorCliente; + +public class NotificadorEmail implements NotificadorCliente { + @Override + public void notificarCliente(String mensagem) { + System.out.println("Email enviado: " + mensagem); + } +} diff --git a/src/Desafio3/loja/notificacao/NotificadorPush.java b/src/Desafio3/loja/notificacao/NotificadorPush.java new file mode 100644 index 0000000..2f1e6b8 --- /dev/null +++ b/src/Desafio3/loja/notificacao/NotificadorPush.java @@ -0,0 +1,10 @@ +package Desafio3.loja.notificacao; + +import Desafio3.loja.interfaces.NotificadorCliente; + +public class NotificadorPush implements NotificadorCliente { + @Override + public void notificarCliente(String mensagem) { + System.out.println("Push Notification: " + mensagem); + } +} diff --git a/src/Desafio3/loja/notificacao/NotificadorSMS.java b/src/Desafio3/loja/notificacao/NotificadorSMS.java new file mode 100644 index 0000000..5b096f1 --- /dev/null +++ b/src/Desafio3/loja/notificacao/NotificadorSMS.java @@ -0,0 +1,10 @@ +package Desafio3.loja.notificacao; + +import Desafio3.loja.interfaces.NotificadorCliente; + +public class NotificadorSMS implements NotificadorCliente { + @Override + public void notificarCliente(String mensagem) { + System.out.println("SMS enviado: " + mensagem); + } +} diff --git a/src/Desafio3/loja/notificacao/NotificadorWhatsApp.java b/src/Desafio3/loja/notificacao/NotificadorWhatsApp.java new file mode 100644 index 0000000..7f9ec6b --- /dev/null +++ b/src/Desafio3/loja/notificacao/NotificadorWhatsApp.java @@ -0,0 +1,10 @@ +package Desafio3.loja.notificacao; + +import Desafio3.loja.interfaces.NotificadorCliente; + +public class NotificadorWhatsApp implements NotificadorCliente { + @Override + public void notificarCliente(String mensagem) { + System.out.println("Whatsapp enviado: " + mensagem); + } +} diff --git a/src/Desafio3/loja/pagamento/PagamentoBoleto.java b/src/Desafio3/loja/pagamento/PagamentoBoleto.java new file mode 100644 index 0000000..1c68cb4 --- /dev/null +++ b/src/Desafio3/loja/pagamento/PagamentoBoleto.java @@ -0,0 +1,17 @@ +package Desafio3.loja.pagamento; + +import Desafio3.loja.interfaces.CalculadorDesconto; +import Desafio3.loja.interfaces.ProcessadorPagamento; + +public class PagamentoBoleto implements ProcessadorPagamento, CalculadorDesconto { + @Override + public boolean processarPagamento(double valor) { + System.out.println("Gerando Boleto para pagamento: R$" + valor); + return true; + } + + @Override + public double calcularDesconto(double valor) { + return valor * 0.03; + } +} diff --git a/src/Desafio3/loja/pagamento/PagamentoCartaoCredito.java b/src/Desafio3/loja/pagamento/PagamentoCartaoCredito.java new file mode 100644 index 0000000..9a2594a --- /dev/null +++ b/src/Desafio3/loja/pagamento/PagamentoCartaoCredito.java @@ -0,0 +1,17 @@ +package Desafio3.loja.pagamento; + +import Desafio3.loja.interfaces.CalculadorDesconto; +import Desafio3.loja.interfaces.ProcessadorPagamento; + +public class PagamentoCartaoCredito implements ProcessadorPagamento, CalculadorDesconto { + @Override + public boolean processarPagamento(double valor) { + System.out.println("Processando pagamento cartão de credito: R$ " + valor); + return valor > 0; + } + + @Override + public double calcularDesconto(double valor) { + return valor * 0.02; + } +} diff --git a/src/Desafio3/loja/pagamento/PagamentoCriptomoeda.java b/src/Desafio3/loja/pagamento/PagamentoCriptomoeda.java new file mode 100644 index 0000000..e7e380d --- /dev/null +++ b/src/Desafio3/loja/pagamento/PagamentoCriptomoeda.java @@ -0,0 +1,18 @@ +package Desafio3.loja.pagamento; + +import Desafio3.loja.interfaces.CalculadorDesconto; +import Desafio3.loja.interfaces.ProcessadorPagamento; + +public class PagamentoCriptomoeda implements ProcessadorPagamento, CalculadorDesconto { + @Override + public boolean processarPagamento(double valor) { + System.out.println("Processando pagamento em criptomoeda: R$ " + valor); + return true; + + } + + @Override + public double calcularDesconto(double valor) { + return valor * 0.08; + } +} diff --git a/src/Desafio3/loja/pagamento/PagamentoPix.java b/src/Desafio3/loja/pagamento/PagamentoPix.java new file mode 100644 index 0000000..bcee201 --- /dev/null +++ b/src/Desafio3/loja/pagamento/PagamentoPix.java @@ -0,0 +1,17 @@ +package Desafio3.loja.pagamento; + +import Desafio3.loja.interfaces.CalculadorDesconto; +import Desafio3.loja.interfaces.ProcessadorPagamento; + +public class PagamentoPix implements ProcessadorPagamento, CalculadorDesconto { + @Override + public boolean processarPagamento(double valor) { + System.out.println("Processando pagamento via PIX: R$ " + valor); + return valor > 0; + } + + @Override + public double calcularDesconto(double valor) { + return valor * 0.05; + } +} diff --git a/src/Desafio3/loja/service/GerenciadorPedidos.java b/src/Desafio3/loja/service/GerenciadorPedidos.java new file mode 100644 index 0000000..af9f5b3 --- /dev/null +++ b/src/Desafio3/loja/service/GerenciadorPedidos.java @@ -0,0 +1,81 @@ +package Desafio3.loja.service; + +import Desafio3.loja.interfaces.*; +import Desafio3.loja.model.Pedido; + +import java.util.ArrayList; +import java.util.List; + +public class GerenciadorPedidos { + private final ProcessadorPagamento processadorPagamento; + private final ServicoEnvio servicoEnvio; + private final NotificadorCliente notificador; + private final CalculadorFrete calculadorFrete; + private final List pedidos; + + public GerenciadorPedidos(ProcessadorPagamento processadorPagamento, + ServicoEnvio servicoEnvio, + NotificadorCliente notificador, + CalculadorFrete calculadorFrete) { + this.processadorPagamento = processadorPagamento; + this.servicoEnvio = servicoEnvio; + this.notificador = notificador; + this.calculadorFrete = calculadorFrete; + this.pedidos = new ArrayList<>(); + } + + public boolean criarPedidos(Pedido pedido) { + System.out.println("\n=== CRIANDO PEDIDOS ==="); + + double frete = calculadorFrete.calcularFrete(pedido.getCepDestino()); + double valorComFrete = pedido.getValorTotal() + frete; + + double desconto = 0; + if (processadorPagamento instanceof CalculadorDesconto) { + desconto = ((CalculadorDesconto) processadorPagamento).calcularDesconto(valorComFrete); + } + + double valorFinal = valorComFrete - desconto; + + System.out.println("Valor original: R$ " + pedido.getValorTotal()); + System.out.println("Frete: R$ " + frete); + System.out.println("Desconto: R$ " + desconto); + System.out.println("Valor final: R$ " + valorFinal); + + if (processadorPagamento.processarPagamento(valorFinal)) { + pedido.setStatus("PAGO"); + pedidos.add(pedido); + + notificador.notificarCliente("Pedido " + pedido.getId() + " confirmado!"); + return true; + } + return false; + } + + public boolean enviarPedido(String idPedido) { + System.out.println("\n=== ENVIANDO PEDIDO ==="); + + Pedido pedido = buscarPedido(idPedido); + if (pedido != null && "PAGO".equals(pedido.getStatus())) { + if (servicoEnvio.enviarPedido(pedido)) { + pedido.setStatus("ENVIADO"); + notificador.notificarCliente("Pedido " + idPedido + " foi enviado!"); + return true; + } + + } + return false; + } + + private Pedido buscarPedido(String id) { + return pedidos.stream() + .filter(p -> p.getId().equals(id)) + .findFirst() + .orElse(null); + } + + public void listarPedidos() { + System.out.println("\n=== LISTA DE PEDIDOS ==="); + pedidos.forEach(System.out::println); + } +} diff --git a/src/Exercicio1/EnviadorRelatorio.java b/src/Exercicio1/EnviadorRelatorio.java new file mode 100644 index 0000000..7608508 --- /dev/null +++ b/src/Exercicio1/EnviadorRelatorio.java @@ -0,0 +1,16 @@ +package Exercicio1; + +class EnviadorRelatorio { + private final ServicoEmail servicoEmail; + private final FormatadorRelatorio formatador; + + public EnviadorRelatorio(ServicoEmail servicoEmail, FormatadorRelatorio formatador) { + this.servicoEmail = servicoEmail; + this.formatador = formatador; + } + + public boolean enviarRelatorioPorEmail(String relatorio, String destinatario, String assunto) { + String conteudoFormatado = formatador.formatarParaEmail(relatorio); + return servicoEmail.enviarEmail(destinatario, assunto, conteudoFormatado); + } +} diff --git a/src/Exercicio1/ExemploSRP.java b/src/Exercicio1/ExemploSRP.java new file mode 100644 index 0000000..665254d --- /dev/null +++ b/src/Exercicio1/ExemploSRP.java @@ -0,0 +1,52 @@ +package Exercicio1; + +public class ExemploSRP { + public static void main(String[] args) { + System.out.println("EXEMPLO VIOLANDO SRP:"); + System.out.println("=".repeat(50)); + + RelatorioViolaSRP relatorioRuim = new RelatorioViolaSRP(); + relatorioRuim.adicionarDado("Venda 1: R$ 150,00"); + relatorioRuim.adicionarDado("Venda 2: R$ 300,00"); + relatorioRuim.adicionarDado("Venda 3: R$ 75,00"); + + relatorioRuim.enviarPorEmail("cliente@email.com", "Relatório Mensal"); + + System.out.println("\n" + "=".repeat(50)); + System.out.println("EXEMPLO APLICANDO SRP:"); + System.out.println("=".repeat(50)); + + GeradorRelatorio gerador = new GeradorRelatorio(); + gerador.adicionarDado("Venda 1: R$ 150,00"); + gerador.adicionarDado("Venda 2: R$ 300,00"); + gerador.adicionarDado("Venda 3: R$ 75,00"); + + ServicoEmail servicoEmail = new ServicoEmail(); + FormatadorRelatorio formatador = new FormatadorRelatorio(); + EnviadorRelatorio enviador = new EnviadorRelatorio(servicoEmail, formatador); + + String relatorio = gerador.gerarRelatorio(); + System.out.println("Relatório gerado:"); + System.out.println(relatorio); + + System.out.println("\n VANTAGENS DO SRP:"); + System.out.println(" Cada classe tem uma única razão para mudar"); + System.out.println(" Código mais fácil de testar"); + System.out.println(" Maior reutilização"); + System.out.println(" manutenção mais simples"); + System.out.println(" baixo acoplamento"); + + System.out.println("\nDEMONSTRANDO FLEXIBILIDADE:"); + + String relatorioTXTO = formatador.formatarParaTXT(relatorio); + System.out.println(" Relatório salvo em TXT"); + + servicoEmail.enviarEmail("admin@loja.com", "Sistema Online", "Sistema funcionando normalmente"); + + System.out.println("\n Cada componente pode evoluir separadamente:"); + System.out.println("- GeradorRelatorio: adicionar novos tipos de relatório"); + System.out.println("- ServicoEmail: melhorar protocolo de envio"); + System.out.println("- FormatadorRelatorio: suportar novos formatos"); + System.out.println("- EnviadorRelatorio: adicionar retry, logs, etc."); + } +} diff --git a/src/Exercicio1/FormatadorRelatorio.java b/src/Exercicio1/FormatadorRelatorio.java new file mode 100644 index 0000000..05242e4 --- /dev/null +++ b/src/Exercicio1/FormatadorRelatorio.java @@ -0,0 +1,15 @@ +package Exercicio1; + +public class FormatadorRelatorio { + public String formatarParaEmail(String relatorio) { + return "
" + relatorio + "
"; + } + + public String formatarParaPDF(String relatorio) { + return "PDF_HEADER\n" + relatorio + "\nPDF_FOOTER"; + } + + public String formatarParaTXT(String relatorio) { + return relatorio; + } +} diff --git a/src/Exercicio1/GeradorRelatorio.java b/src/Exercicio1/GeradorRelatorio.java new file mode 100644 index 0000000..1d18942 --- /dev/null +++ b/src/Exercicio1/GeradorRelatorio.java @@ -0,0 +1,36 @@ +package Exercicio1; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +public class GeradorRelatorio { + private List dados; + + public GeradorRelatorio() { + this.dados = new ArrayList<>(); + } + + public String gerarRelatorio() { + StringBuilder relatorio = new StringBuilder(); + relatorio.append("=== RELATÓRIO DE VENDAS ===\n"); + relatorio.append("Data: ").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"))).append("\n"); + relatorio.append("Total de registros: ").append(dados.size()).append("\n\n"); + + for (String item : dados) { + relatorio.append("- ").append(item).append("\n"); + } + + return relatorio.toString(); + } + + public void adicionarDado(String dado) { + dados.add(dado); + } + + public List getDados() { + return new ArrayList<>(dados); + } +} diff --git a/src/Exercicio1/RelatorioViolaSRP.java b/src/Exercicio1/RelatorioViolaSRP.java new file mode 100644 index 0000000..ef3ef99 --- /dev/null +++ b/src/Exercicio1/RelatorioViolaSRP.java @@ -0,0 +1,48 @@ +package Exercicio1; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +public class RelatorioViolaSRP { + private List dados; + + public RelatorioViolaSRP() { + this.dados = new ArrayList<>(); + } + + public String gerarRelatorio() { + StringBuilder relatorio = new StringBuilder(); + relatorio.append("=== RELATÓRIO DE VENDAS ===\n"); + relatorio.append("Data: ").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"))).append("\n"); + relatorio.append("Total de vendas: ").append(dados.size()).append("\n"); + + for (String item : dados) { + relatorio.append("- ").append(item).append("\n"); + } + + return relatorio.toString(); + } + + public boolean enviarPorEmail(String destinatario, String assunto) { + String conteudo = gerarRelatorio(); + + System.out.println("Conectando ao servidor SMTP..."); + System.out.println("Enviando email para: " + destinatario); + System.out.println("Assunto: " + assunto); + System.out.println("Conteúdo: " + conteudo); + System.out.println("Email enviado com sucesso!"); + + return true; + } + + public boolean validarEmail(String email) { + return email != null && email.contains("@"); + } + + public void adicionarDado(String dado) { + dados.add(dado); + } +} diff --git a/src/Exercicio1/ServicoEmail.java b/src/Exercicio1/ServicoEmail.java new file mode 100644 index 0000000..a401825 --- /dev/null +++ b/src/Exercicio1/ServicoEmail.java @@ -0,0 +1,21 @@ +package Exercicio1; + +class ServicoEmail { + public boolean enviarEmail(String destinatario, String assunto, String conteudo) { + if (!validarEmail(destinatario)) { + System.out.println("X Email inválido: " + destinatario); + return false; + } + + System.out.println("Conectando ao servidor SMTP..."); + System.out.println("Enviando email para: " + destinatario); + System.out.println("Assunto: " + assunto); + System.out.println("Email enviado com sucesso!"); + + return true; + } + + private boolean validarEmail(String email) { + return email != null && email.contains("@"); + } +} diff --git a/src/Exercicio2/CalculadorDesconto.java b/src/Exercicio2/CalculadorDesconto.java new file mode 100644 index 0000000..97660b2 --- /dev/null +++ b/src/Exercicio2/CalculadorDesconto.java @@ -0,0 +1,6 @@ +package Exercicio2; + +public interface CalculadorDesconto { + double calcular(double valor); + String getTipo(); +} diff --git a/src/Exercicio2/CalculadorDescontoViolaOCP.java b/src/Exercicio2/CalculadorDescontoViolaOCP.java new file mode 100644 index 0000000..2b46bfc --- /dev/null +++ b/src/Exercicio2/CalculadorDescontoViolaOCP.java @@ -0,0 +1,18 @@ +package Exercicio2; + +class CalculadorDescontoViolaOCP { + public double calcularDesconto(double valor, String tipoDesconto) { + switch (tipoDesconto) { + case "FIXO": + return 10.0; + case "PERCENTUAL": + return valor * 0.05; + case "PROGRESSIVO": + if (valor > 500) return valor * 0.15; + else if (valor > 200) return valor * 0.10; + else return valor * 0.05; + default: + return 0.0; + } + } +} diff --git a/src/Exercicio2/DescontoBlackFriday.java b/src/Exercicio2/DescontoBlackFriday.java new file mode 100644 index 0000000..c6fe23d --- /dev/null +++ b/src/Exercicio2/DescontoBlackFriday.java @@ -0,0 +1,13 @@ +package Exercicio2; + +public class DescontoBlackFriday implements CalculadorDesconto{ + @Override + public double calcular(double valor) { + return valor * 0.30; + } + + @Override + public String getTipo() { + return "Desconto Black Friday: 30%"; + } +} diff --git a/src/Exercicio2/DescontoFidelidade.java b/src/Exercicio2/DescontoFidelidade.java new file mode 100644 index 0000000..5d9a9a4 --- /dev/null +++ b/src/Exercicio2/DescontoFidelidade.java @@ -0,0 +1,21 @@ +package Exercicio2; + +class DescontoFidelidade implements CalculadorDesconto{ + private final int pontosCliente; + + public DescontoFidelidade(int pontosCliente) { + this.pontosCliente = pontosCliente; + } + + @Override + public double calcular(double valor) { + double descontoPontos = pontosCliente * 0.10; + return Math.min(descontoPontos, valor * 0.25); + } + + @Override + public String getTipo() { + return "Desconto Fidelidade: " + pontosCliente + "pontos"; + } + +} diff --git a/src/Exercicio2/DescontoFixo.java b/src/Exercicio2/DescontoFixo.java new file mode 100644 index 0000000..c6ef704 --- /dev/null +++ b/src/Exercicio2/DescontoFixo.java @@ -0,0 +1,19 @@ +package Exercicio2; + +class DescontoFixo implements CalculadorDesconto { + private final double valorFixo; + + public DescontoFixo(double valorFixo) { + this.valorFixo = valorFixo; + } + + @Override + public double calcular(double valor) { + return valorFixo; + } + + @Override + public String getTipo() { + return "Desconto Fixo: R$ " + valorFixo; + } +} diff --git a/src/Exercicio2/DescontoPercentual.java b/src/Exercicio2/DescontoPercentual.java new file mode 100644 index 0000000..99b7aa3 --- /dev/null +++ b/src/Exercicio2/DescontoPercentual.java @@ -0,0 +1,19 @@ +package Exercicio2; + +public class DescontoPercentual implements CalculadorDesconto{ + private final double percentual; + + public DescontoPercentual(double percentual) { + this.percentual = percentual; + } + + @Override + public double calcular(double valor) { + return valor * (percentual / 100); + } + + @Override + public String getTipo() { + return "Desconto Percentual: " + percentual + "%"; + } +} diff --git a/src/Exercicio2/DescontoPrimeiroCliente.java b/src/Exercicio2/DescontoPrimeiroCliente.java new file mode 100644 index 0000000..209db70 --- /dev/null +++ b/src/Exercicio2/DescontoPrimeiroCliente.java @@ -0,0 +1,13 @@ +package Exercicio2; + +class DescontoPrimeiroCliente implements CalculadorDesconto{ + @Override + public double calcular(double valor) { + return Math.min(valor * 0.20, 50.0); + } + + @Override + public String getTipo() { + return "Desconto Primeiro Cliente: 20% (max: R$ 50)"; + } +} diff --git a/src/Exercicio2/DescontoProgressivo.java b/src/Exercicio2/DescontoProgressivo.java new file mode 100644 index 0000000..1cb67fc --- /dev/null +++ b/src/Exercicio2/DescontoProgressivo.java @@ -0,0 +1,15 @@ +package Exercicio2; + +public class DescontoProgressivo implements CalculadorDesconto{ + @Override + public double calcular(double valor) { + if (valor > 500) return valor * 0.15; + else if (valor > 200) return valor * 0.10; + else return valor * 0.05; + } + + @Override + public String getTipo() { + return "Desconto Progressivo (5%, 10%, 15%)"; + } +} diff --git a/src/Exercicio2/ExercicioOCP.java b/src/Exercicio2/ExercicioOCP.java new file mode 100644 index 0000000..f91fec3 --- /dev/null +++ b/src/Exercicio2/ExercicioOCP.java @@ -0,0 +1,53 @@ +package Exercicio2; + +public class ExercicioOCP { + public static void main(String[] args) { + System.out.println(" EXEMPLO VIOLANDO OCP:"); + System.out.println("=".repeat(50)); + + CalculadorDescontoViolaOCP calculadorRuim = new CalculadorDescontoViolaOCP(); + double valor = 300.0; + + System.out.println("Para adicionar novo tipo de desconto, precisa modificar a classe existente!"); + System.out.println("Desconto Fixo: R$ " + calculadorRuim.calcularDesconto(valor, "FIXO")); + System.out.println("Desconto Percentual: R$ " + calculadorRuim.calcularDesconto(valor, "PERCENTUAL")); + + System.out.println("\nAPLICANDO OCP:"); + System.out.println("=".repeat(50)); + + SistemaDesconto sistema = new SistemaDesconto(); + double valorCompra = 300.0; + + System.out.println("Simulando Compra de: R$ " + valorCompra); + System.out.println(); + + sistema.aplicarDesconto(valorCompra, new DescontoFixo(15.0)); + + sistema.aplicarDesconto(valorCompra, new DescontoPercentual(10)); + + sistema.aplicarDesconto(valorCompra, new DescontoProgressivo()); + + sistema.aplicarDesconto(valorCompra, new DescontoBlackFriday()); + + sistema.aplicarDesconto(valorCompra, new DescontoPrimeiroCliente()); + + sistema.aplicarDesconto(valorCompra, new DescontoFidelidade(150)); + + System.out.println("SIMULANDO DIFERENTES CENÁRIOS:"); + + double[] valoresCompra = {50.0, 150.0, 300, 350.0, 600.0}; + CalculadorDesconto descontoProgressivo = new DescontoProgressivo(); + + for (double val : valoresCompra) { + System.out.println("Compra R$ " + val + " -> Desconto: R$ " + + String.format("%.2f", descontoProgressivo.calcular(val))); + } + + System.out.println("\n PRÓXIMAS EXTENSÕES POSSÍVEIS (sem modificar nada!):"); + System.out.println("- DescontoCupom"); + System.out.println("- DescontoPorCategoria"); + System.out.println("- DescontoIdoso"); + System.out.println("- DescontoEstudante"); + System.out.println("- DescontoLiquidacao"); + } +} diff --git a/src/Exercicio2/SistemaDesconto.java b/src/Exercicio2/SistemaDesconto.java new file mode 100644 index 0000000..4e0455a --- /dev/null +++ b/src/Exercicio2/SistemaDesconto.java @@ -0,0 +1,15 @@ +package Exercicio2; + +class SistemaDesconto { + public void aplicarDesconto(double valorOriginal, CalculadorDesconto calculadora) { + double desconto = calculadora.calcular(valorOriginal); + double valorFinal = valorOriginal - desconto; + + System.out.println("Valor original: R$ " + String.format("%.2f", valorOriginal)); + System.out.println("Tipo: R$ " + calculadora.getTipo()); + System.out.println("Desconto: R$ " + String.format("%.2f", desconto)); + System.out.println("Valor final: R$ " + String.format("%.2f", valorFinal)); + System.out.println("Economia: R$ " + String.format("%.1f", (desconto/valorOriginal) * 100) + "%"); + System.out.println("-".repeat(50)); + } +} diff --git a/src/Exercicio3/DemonstradorProblema.java b/src/Exercicio3/DemonstradorProblema.java new file mode 100644 index 0000000..9e866d0 --- /dev/null +++ b/src/Exercicio3/DemonstradorProblema.java @@ -0,0 +1,36 @@ +package Exercicio3; + +public class DemonstradorProblema { + public static void demonstrarProblema() { + System.out.println("=".repeat(60)); + System.out.println("DEMONSTRAÇÃO DO PROBLEMA - VIOLAÇAO DO LSP"); + System.out.println("=".repeat(60)); + + System.out.println("\n --- Testando comportamento inconsistente ---"); + + System.out.println("\n1. Testando com Retângulo normal:"); + Retangulo ret = new Retangulo(3, 4); + testarComportamento(ret); + + System.out.println("\n2. Testando com Quadrado (Violação do LSP):"); + Retangulo quad = new QuadradoProblematico(3); + testarComportamento(quad); + + System.out.println("\n PROBLEMA: O nosso código produz comportamentos diferentes!"); + System.out.println("Isso viola o Princípio da Substituição de Liskov."); + } + + private static void testarComportamento(Retangulo retangulo) { + System.out.println("Estado inicial: " + retangulo); + + retangulo.setAltura(10); + System.out.println("Após setLargura(10): " + retangulo); + + retangulo.setAltura(5); + System.out.println("Após setAltura(5): " + retangulo); + + if (retangulo.getLargura() != 10 || retangulo.getAltura() != 5) { + System.out.println("VIOLAÇÃO!: Comportamento inesperado detectado!"); + } + } +} diff --git a/src/Exercicio3/ExercicioLSP.java b/src/Exercicio3/ExercicioLSP.java new file mode 100644 index 0000000..28e56f8 --- /dev/null +++ b/src/Exercicio3/ExercicioLSP.java @@ -0,0 +1,83 @@ +package Exercicio3; + +public class ExercicioLSP { + public static void main(String[] args) { + DemonstradorProblema.demonstrarProblema(); + + demonstrarSolucoes(); + + analisarLSP(); + } + + private static void demonstrarSolucoes() { + System.out.println("\n" + "=".repeat(60)); + System.out.println("SOLUÇOES EM CONFORMIDADE COM O LSP"); + System.out.println("=".repeat(60)); + + System.out.println("\n--- Solução 1: Classes Indepedentes ---"); + Forma[] formas = { + new RetanguloLSP(4,6), + new QuadradoLSP(5), + new RetanguloLSP(3,8) + }; + + for (Forma forma : formas) { + System.out.println(forma); + System.out.println("Perimetro: " + forma.perimetro()); + System.out.println("=".repeat(30)); + } + + System.out.println("\n--- Solução 2: Objetos Imutáveis ---"); + FormaImutavel ret = new RetanguloImutavel(4,6); + FormaImutavel quad = new QuadradoImutavel(5); + + System.out.println("Original: " + ret); + RetanguloImutavel novoRet = ((RetanguloImutavel) ret).comLargura(8); + System.out.println("Novo retângulo: " + novoRet); + + System.out.println("Original: " + quad); + QuadradoImutavel novoQuad = ((QuadradoImutavel) quad).comLado(7); + System.out.println("Novo quadrado: " + novoQuad); + } + + private static void analisarLSP() { + System.out.println("\n" + "=".repeat(60)); + System.out.println("ANÁLISE DO PRINCÍPIO LSP"); + System.out.println("=".repeat(60)); + + System.out.println("\nPROBLEMAS NA IMPLEMENTAÇÃO INICIAL:"); + System.out.println("* Quebra de invariantes: Quadrado modifica comportamentos dos setters"); + System.out.println("* Comportamento Inesperado: Alterar uma dimensão afeta ambas"); + System.out.println("* Violação de Contratos: Código que espera Retângulo falha"); + + System.out.println("\n SOLUÇÕES IMPLEMENTADAS:"); + System.out.println("* Classes independentes: Evita problemas de herança"); + System.out.println("* Objetos Imutáveis: Elimina problemas de estado"); + System.out.println("* Interfaces Claras: Contratos bem definidos"); + + System.out.println("\nLSP RESPEITADO:"); + System.out.println("Substituibilidade mantida"); + System.out.println("Comportamento previsível"); + System.out.println("Contratos preservados"); + System.out.println("Polimorfismo funcional"); + + System.out.println("\n--- Teste de conformidade LSP ---"); + testeLSP(); + } + + private static void testeLSP() { + Forma[] formas = { + new RetanguloLSP(4,6), + new QuadradoLSP(4) + }; + + double areaTotal = 0; + for (Forma forma : formas) { + areaTotal += forma.area(); + System.out.println("Processando: " + forma); + } + + System.out.printf("Área Total: %.1f%n", areaTotal); + System.out.println("Polimorfismo funcionando corretamente!"); + } +} diff --git a/src/Exercicio3/Forma.java b/src/Exercicio3/Forma.java new file mode 100644 index 0000000..6fc1b04 --- /dev/null +++ b/src/Exercicio3/Forma.java @@ -0,0 +1,7 @@ +package Exercicio3; + +interface Forma { + double area(); + double perimetro(); + String getDescricao(); +} diff --git a/src/Exercicio3/FormaImutavel.java b/src/Exercicio3/FormaImutavel.java new file mode 100644 index 0000000..0855df8 --- /dev/null +++ b/src/Exercicio3/FormaImutavel.java @@ -0,0 +1,12 @@ +package Exercicio3; + +abstract class FormaImutavel { + public abstract double area(); + public abstract double perimetro(); + public abstract String getDescricao(); + + @Override + public String toString() { + return String.format("%s, Área: %.1f", getDescricao(), area()); + } +} diff --git a/src/Exercicio3/QuadradoImutavel.java b/src/Exercicio3/QuadradoImutavel.java new file mode 100644 index 0000000..9e7a4ba --- /dev/null +++ b/src/Exercicio3/QuadradoImutavel.java @@ -0,0 +1,34 @@ +package Exercicio3; + +class QuadradoImutavel extends FormaImutavel { + private final double lado; + + public QuadradoImutavel(double lado) { + if (lado <= 0) { + throw new IllegalArgumentException("Lado deve ser positivo."); + } + this.lado = lado; + } + + public double getLado() { + return lado; + } + + public QuadradoImutavel comLado(double novoLado) { + return new QuadradoImutavel(novoLado); + } + + @Override + public double area() { + return lado * lado; + } + + @Override + public double perimetro() { + return 4 * lado; + } + @Override + public String getDescricao() { + return String.format("Quadrado: %.1fx%.1f", lado, lado); + } +} diff --git a/src/Exercicio3/QuadradoLSP.java b/src/Exercicio3/QuadradoLSP.java new file mode 100644 index 0000000..59b060d --- /dev/null +++ b/src/Exercicio3/QuadradoLSP.java @@ -0,0 +1,44 @@ +package Exercicio3; + +class QuadradoLSP implements Forma{ + private double lado; + + public QuadradoLSP(double lado) { + if (lado <= 0) { + throw new IllegalArgumentException("Lado deve ser positivo."); + } + this.lado = lado; + } + + public double getLado() { + return lado; + } + + public void setLado(double lado) { + + if (lado <= 0) { + throw new IllegalArgumentException("Lado deve ser positivo."); + } + this.lado = lado; + } + + @Override + public double area() { + return lado * lado; + } + + @Override + public double perimetro() { + return 4 * lado; + } + + @Override + public String getDescricao() { + return String.format("Quadrado: %.1fx%.1f", lado, lado); + } + + @Override + public String toString() { + return String.format("%s, Área: %.1f", getDescricao(), area()); + } +} diff --git a/src/Exercicio3/QuadradoProblematico.java b/src/Exercicio3/QuadradoProblematico.java new file mode 100644 index 0000000..f5f453e --- /dev/null +++ b/src/Exercicio3/QuadradoProblematico.java @@ -0,0 +1,25 @@ +package Exercicio3; + +class QuadradoProblematico extends Retangulo { + public QuadradoProblematico(double lado) { + super(lado, lado); + } + + @Override + public void setLargura(double largura) { + this.largura = altura; + this.altura = largura; + } + + @Override + public void setAltura(double altura) { + this.largura = altura; + this.altura = altura; + } + + @Override + public String toString() { + return String.format("Quadrado: %.1fx%.1f, Área: %.1f", + largura,altura,area()); + } +} diff --git a/src/Exercicio3/Retangulo.java b/src/Exercicio3/Retangulo.java new file mode 100644 index 0000000..6e09bb6 --- /dev/null +++ b/src/Exercicio3/Retangulo.java @@ -0,0 +1,37 @@ +package Exercicio3; + +public class Retangulo { + protected double largura; + protected double altura; + + public Retangulo(double largura, double altura) { + this.largura = largura; + this.altura = altura; + } + + public double getLargura() { + return largura; + } + + public void setLargura(double largura) { + this.largura = largura; + } + + public double getAltura() { + return altura; + } + + public void setAltura(double altura) { + this.altura = altura; + } + + public double area() { + return largura * altura; + } + + @Override + public String toString() { + return String.format("Retângulo: %.1f x %.1f, Área: %.1f", + largura, altura, area()); + } +} diff --git a/src/Exercicio3/RetanguloImutavel.java b/src/Exercicio3/RetanguloImutavel.java new file mode 100644 index 0000000..c20e305 --- /dev/null +++ b/src/Exercicio3/RetanguloImutavel.java @@ -0,0 +1,46 @@ +package Exercicio3; + +public class RetanguloImutavel extends FormaImutavel { + private final double largura; + private final double altura; + + public RetanguloImutavel(double largura, double altura) { + + if (largura <= 0 || altura <= 0) { + throw new IllegalArgumentException("Dimensões devem ser positivas."); + } + this.largura = largura; + this.altura = altura; + } + + public double getLargura() { + return largura; + } + + public double getAltura() { + return altura; + } + + public RetanguloImutavel comLargura(double novaLargura) { + return new RetanguloImutavel(novaLargura, this.altura); + } + + public RetanguloImutavel comAltura(double novaAltura) { + return new RetanguloImutavel(this.largura, novaAltura); + } + + @Override + public double area() { + return largura * altura; + } + + @Override + public double perimetro() { + return 2 * (largura + altura); + } + + @Override + public String getDescricao() { + return String.format("Retângulo: %.1fx%.1f", largura, altura); + } +} diff --git a/src/Exercicio3/RetanguloLSP.java b/src/Exercicio3/RetanguloLSP.java new file mode 100644 index 0000000..62644be --- /dev/null +++ b/src/Exercicio3/RetanguloLSP.java @@ -0,0 +1,57 @@ +package Exercicio3; + +class RetanguloLSP implements Forma { + private double largura; + private double altura; + + public RetanguloLSP(double largura, double altura) { + if (largura <= 0 || altura <= 0) { + throw new IllegalArgumentException("Dimensões devem ser positivas."); + } + + this.largura = largura; + this.altura = altura; + } + + public void setLargura(double largura) { + if (largura <= 0) { + throw new IllegalArgumentException("Largura deve ser positiva."); + } + this.largura = largura; + } + + public void setAltura(double altura) { + if (altura <= 0) { + throw new IllegalArgumentException("Altura deve ser positiva."); + } + this.altura = altura; + } + + public double getLargura() { + return largura; + } + + public double getAltura() { + return altura; + } + + @Override + public double area() { + return largura * altura; + } + + @Override + public double perimetro() { + return 2 * (largura + altura); + } + + @Override + public String getDescricao() { + return String.format("Retângulo: %.1fx%.1f", largura, altura); + } + + @Override + public String toString() { + return String.format("%s, Área: %.1f", getDescricao(), area()); + } +} diff --git a/src/Exercicio4/Desenvolvedor.java b/src/Exercicio4/Desenvolvedor.java new file mode 100644 index 0000000..bf64565 --- /dev/null +++ b/src/Exercicio4/Desenvolvedor.java @@ -0,0 +1,29 @@ +package Exercicio4; + +class Desenvolvedor implements Trabalhador, Estudante, Programador{ + private String nome; + + public Desenvolvedor(String nome) { + this.nome = nome; + } + + @Override + public void trabalhar() { + System.out.println(nome + " está trabalhando no desenvolvimento"); + } + + @Override + public void estudar() { + System.out.println(nome + " está estudando novas tecnologias"); + } + + @Override + public void programar() { + System.out.println(nome + " está programando"); + } + + @Override + public String toString() { + return "Desenvolvedor: " + nome; + } +} diff --git a/src/Exercicio4/Estagiario.java b/src/Exercicio4/Estagiario.java new file mode 100644 index 0000000..fdb63c0 --- /dev/null +++ b/src/Exercicio4/Estagiario.java @@ -0,0 +1,23 @@ +package Exercicio4; + +class Estagiario implements Trabalhador, Estudante { + private String nome; + + public Estagiario(String nome) { + this.nome = nome; + } + + @Override + public void trabalhar() { + System.out.println(nome + " está fazendo tarefas de estágio"); + } + + public void estudar() { + System.out.println(nome + " está estudando para aprender"); + } + + @Override + public String toString() { + return "Estagiario: " + nome; + } +} diff --git a/src/Exercicio4/Estudante.java b/src/Exercicio4/Estudante.java new file mode 100644 index 0000000..657efcb --- /dev/null +++ b/src/Exercicio4/Estudante.java @@ -0,0 +1,5 @@ +package Exercicio4; + +interface Estudante { + void estudar(); +} diff --git a/src/Exercicio4/ExercicioISP.java b/src/Exercicio4/ExercicioISP.java new file mode 100644 index 0000000..1e2684a --- /dev/null +++ b/src/Exercicio4/ExercicioISP.java @@ -0,0 +1,75 @@ +package Exercicio4; + +public class ExercicioISP { + public static void main(String[] args) { + demonstrarProblema(); + demonstrarSolucao(); + analisarISP(); + + } + + private static void demonstrarProblema() { + System.out.println("\n" + "=".repeat(60)); + System.out.println("PROBLEMA - VIOLAÇÃO DO ISP"); + System.out.println("=".repeat(60)); + + System.out.println("\nProblema: Interface 'TrabalhadorProblematico' força implementações desnecessárias"); + + try { + OperarioProblematico operario = new OperarioProblematico(); + operario.trabalhar(); + operario.programar(); + } catch (UnsupportedOperationException e) { + System.out.println("Erro: " + e.getMessage()); + } + + System.out.println("\nISP Violado: Clientes forçados a depender de métodos que não usam!"); + } + + private static void demonstrarSolucao() { + System.out.println("\n" + "=".repeat(60)); + System.out.println("SOLUÇÃO - CONFORMIDADE COM ISP"); + System.out.println("=".repeat(60)); + + Operario operario = new Operario("João"); + Desenvolvedor dev = new Desenvolvedor("Maria"); + Estagiario estagiario = new Estagiario("Pedro"); + Techlead techlead = new Techlead("Ana"); + + Trabalhador[] todosTrabalhadores = {operario, dev, estagiario, techlead}; + GerenciadorTrabalho.organizarTrabalho(todosTrabalhadores); + + Estudante[] estudantes = {dev, estagiario, techlead}; + GerenciadorTrabalho.organizarEstudos(estudantes); + + Programador[] programadores = {dev, techlead}; + GerenciadorTrabalho.organizarProgramacao(programadores); + + Professor[] professores = {techlead}; + GerenciadorTrabalho.organizarEnsino(professores); + } + + private static void analisarISP() { + System.out.println("\n" + "=".repeat(60)); + System.out.println("ANÁLISE DO ISP"); + System.out.println("=".repeat(60)); + + System.out.println("\n Principio ISP:"); + System.out.println("\"Clientes não devem ser forçados a depender de interfaces que não usam\""); + + System.out.println("\nPROBLEMAS DA IMPLEMENTAÇÃO INICIAL:"); + System.out.println("* Interface muito grande (4 métodos)"); + System.out.println("* Classes forçadas a implementar métodos irrelevantes"); + System.out.println("* Acoplamento desnecessário"); + System.out.println("* Código frágil (exceções em runtime)"); + + System.out.println("\nBENEFÍCIOS DA SOLUÇÃO ISP:"); + System.out.println("* Interfaces pequenas focadas"); + System.out.println("* Baixo acoplamento"); + System.out.println("* Alta coesão"); + System.out.println("* Flexibilidade na implementação"); + System.out.println("* Facilita manutenção e testes"); + + System.out.println("\nISP APLICADO COM SUCESSO!"); + } +} diff --git a/src/Exercicio4/GerenciadorTrabalho.java b/src/Exercicio4/GerenciadorTrabalho.java new file mode 100644 index 0000000..0a03662 --- /dev/null +++ b/src/Exercicio4/GerenciadorTrabalho.java @@ -0,0 +1,33 @@ +package Exercicio4; + +class GerenciadorTrabalho { + public static void organizarTrabalho(Trabalhador[] trabalhadores) { + System.out.println("--- Organizando trabalho para todos ---"); + for (Trabalhador trabalhador : trabalhadores) { + System.out.print(trabalhador + " --> "); + trabalhador.trabalhar(); + } + } + + public static void organizarEstudos(Estudante[] estudantes) { + System.out.println("\n--- Organizando estudos ---"); + for (Estudante estudante : estudantes) { + estudante.estudar(); + } + } + + public static void organizarProgramacao(Programador[] programadores) { + System.out.println("\n--- Organizando programação ---"); + for (Programador programador : programadores) { + programador.programar(); + } + } + + public static void organizarEnsino(Professor[] professors) { + System.out.println("\n--- Organizando ensino ---"); + for (Professor professor : professors) { + professor.ensinar(); + } + + } +} diff --git a/src/Exercicio4/Operario.java b/src/Exercicio4/Operario.java new file mode 100644 index 0000000..78e1f26 --- /dev/null +++ b/src/Exercicio4/Operario.java @@ -0,0 +1,19 @@ +package Exercicio4; + +class Operario implements Trabalhador{ + private String nome; + + public Operario(String nome) { + this.nome = nome; + } + + @Override + public void trabalhar() { + System.out.println(nome + " está trabalhando na linha de produção"); + } + + @Override + public String toString() { + return "Operario: " + nome; + } +} diff --git a/src/Exercicio4/OperarioProblematico.java b/src/Exercicio4/OperarioProblematico.java new file mode 100644 index 0000000..2bb9d22 --- /dev/null +++ b/src/Exercicio4/OperarioProblematico.java @@ -0,0 +1,23 @@ +package Exercicio4; + +class OperarioProblematico implements TrabalhadorProblemático { + @Override + public void trabalhar() { + System.out.println("Operário trabalhando na fábrica "); + } + + @Override + public void estudar() { + throw new UnsupportedOperationException("Operário não estuda durante o trabalho."); + } + + @Override + public void programar() { + throw new UnsupportedOperationException("Operário não programa"); + } + + @Override + public void ensinar() { + throw new UnsupportedOperationException("Operário não ensina"); + } +} diff --git a/src/Exercicio4/Professor.java b/src/Exercicio4/Professor.java new file mode 100644 index 0000000..9b1b9c9 --- /dev/null +++ b/src/Exercicio4/Professor.java @@ -0,0 +1,5 @@ +package Exercicio4; + +interface Professor { + void ensinar(); +} diff --git a/src/Exercicio4/Programador.java b/src/Exercicio4/Programador.java new file mode 100644 index 0000000..4946d8f --- /dev/null +++ b/src/Exercicio4/Programador.java @@ -0,0 +1,5 @@ +package Exercicio4; + +interface Programador { + void programar(); +} diff --git a/src/Exercicio4/ProgramadorProblematico.java b/src/Exercicio4/ProgramadorProblematico.java new file mode 100644 index 0000000..f5005c5 --- /dev/null +++ b/src/Exercicio4/ProgramadorProblematico.java @@ -0,0 +1,23 @@ +package Exercicio4; + +class ProgramadorProblematico implements TrabalhadorProblemático { + @Override + public void trabalhar() { + System.out.println("Programador desenvolvendo Software"); + } + + @Override + public void estudar() { + System.out.println("Programador estudando novas tecnologias"); + } + + @Override + public void programar() { + System.out.println("Programador codificando"); + } + + @Override + public void ensinar() { + throw new UnsupportedOperationException ("Este programador não ensina"); + } +} diff --git a/src/Exercicio4/Techlead.java b/src/Exercicio4/Techlead.java new file mode 100644 index 0000000..8e3d9d0 --- /dev/null +++ b/src/Exercicio4/Techlead.java @@ -0,0 +1,34 @@ +package Exercicio4; + +class Techlead implements Trabalhador, Estudante, Programador, Professor { + private String nome; + + public Techlead(String nome) { + this.nome = nome; + } + + @Override + public void trabalhar() { + System.out.println(nome + " está liderando a equipe técnica"); + } + + @Override + public void estudar() { + System.out.println(nome + " está estudando arquiteturas avançadas"); + } + + @Override + public void programar() { + System.out.println(nome + " está fazendo code review e prototipando"); + } + + @Override + public void ensinar() { + System.out.println(nome + " está mentorando desenvolvedores junior"); + } + + @Override + public String toString() { + return "Techlead: " + nome; + } +} diff --git a/src/Exercicio4/Trabalhador.java b/src/Exercicio4/Trabalhador.java new file mode 100644 index 0000000..2946d8e --- /dev/null +++ b/src/Exercicio4/Trabalhador.java @@ -0,0 +1,5 @@ +package Exercicio4; + +public interface Trabalhador { + void trabalhar(); +} diff --git "a/src/Exercicio4/TrabalhadorProblem\303\241tico.java" "b/src/Exercicio4/TrabalhadorProblem\303\241tico.java" new file mode 100644 index 0000000..220d592 --- /dev/null +++ "b/src/Exercicio4/TrabalhadorProblem\303\241tico.java" @@ -0,0 +1,8 @@ +package Exercicio4; + +interface TrabalhadorProblemático { + void trabalhar(); + void estudar(); + void programar(); + void ensinar(); +} diff --git a/src/Exercicio5/EmailService.java b/src/Exercicio5/EmailService.java new file mode 100644 index 0000000..2e0ed97 --- /dev/null +++ b/src/Exercicio5/EmailService.java @@ -0,0 +1,10 @@ +package Exercicio5; + +class EmailService { + public void enviarEmail(String destinatario, String assunto, String mensagem) { + System.out.println("Enviando email para " + destinatario); + System.out.println("Assunto: " + assunto); + System.out.println("Mensagem: " + mensagem); + System.out.println("Email enviado com sucesso!\n"); + } +} diff --git a/src/Exercicio5/EmailServiceRefatorado.java b/src/Exercicio5/EmailServiceRefatorado.java new file mode 100644 index 0000000..a54206b --- /dev/null +++ b/src/Exercicio5/EmailServiceRefatorado.java @@ -0,0 +1,11 @@ +package Exercicio5; + +class EmailServiceRefatorado implements IServicoNotificacao { + @Override + public void enviar(String destinatario, String assunto, String mensagem) { + System.out.println("Enviando email para " + destinatario); + System.out.println("Assunto " + assunto); + System.out.println("Mensagem " + mensagem); + System.out.println("E-mail enviado com sucesso!\n"); + } +} diff --git a/src/Exercicio5/IServicoNotificacao.java b/src/Exercicio5/IServicoNotificacao.java new file mode 100644 index 0000000..b9b2ada --- /dev/null +++ b/src/Exercicio5/IServicoNotificacao.java @@ -0,0 +1,5 @@ +package Exercicio5; + +interface IServicoNotificacao { + void enviar(String destinatario, String assunto, String mensagem); +} diff --git a/src/Exercicio5/Main.java b/src/Exercicio5/Main.java new file mode 100644 index 0000000..5ee7f75 --- /dev/null +++ b/src/Exercicio5/Main.java @@ -0,0 +1,113 @@ +package Exercicio5; + +public class Main { + public static void main(String[] args) { + demonstrarViolacaoDIP(); + demonstrarDIPCorreto(); + demonstrarTestes(); + demonstrarFactory(); + } + + private static void demonstrarViolacaoDIP() { + System.out.println("=".repeat(50)); + System.out.println("🚫 EXEMPLO VIOLANDO O DIP"); + System.out.println("=".repeat(50)); + + NotificadorProblematico notificador = new NotificadorProblematico(); + notificador.notificar("usuario@exemplo.com", "Bem-vindo ao sistema!"); + + System.out.println("❌ Problemas:"); + System.out.println("- Notificador está acoplado ao EmailService"); + System.out.println("- Difícil de testar (dependência hard-coded)"); + System.out.println("- Impossível trocar o tipo de notificação"); + System.out.println("- Violação do princípio aberto/fechado\n"); + } + + private static void demonstrarDIPCorreto() { + System.out.println("=".repeat(50)); + System.out.println("✅ EXEMPLO SEGUINDO O DIP"); + System.out.println("=".repeat(50)); + + // Criando diferentes serviços + IServicoNotificacao emailService = new EmailServiceRefatorado(); + IServicoNotificacao smsService = new SMSService(); + IServicoNotificacao pushService = new PushNotificationService(); + IServicoNotificacao slackService = new SlackService(); + + // Usando com email + System.out.println("📧 Usando EmailService:"); + Notificador notificadorEmail = new Notificador(emailService); + notificadorEmail.notificar("usuario@exemplo.com", "Bem-vindo ao sistema!"); + + // Usando com SMS + System.out.println("📱 Usando SMSService:"); + Notificador notificadorSMS = new Notificador(smsService); + notificadorSMS.notificar("+55119999-9999", "Código de verificação: 123456"); + + // Usando com Push Notification + System.out.println("🔔 Usando PushNotificationService:"); + Notificador notificadorPush = new Notificador(pushService); + notificadorPush.notificar("user_id_123", "Nova mensagem recebida!"); + + // Usando com Slack + System.out.println("💬 Usando SlackService:"); + Notificador notificadorSlack = new Notificador(slackService); + notificadorSlack.notificar("@usuario", "Reunião em 15 minutos!"); + + // Demonstrando troca de serviço em tempo de execução + System.out.println("🔄 Trocando serviço em tempo de execução:"); + notificadorEmail.trocarServico(smsService); + notificadorEmail.notificar("+55119999-8888", "Serviço trocado dinamicamente!"); + + System.out.println("✅ Vantagens do DIP:"); + System.out.println("- Baixo acoplamento entre classes"); + System.out.println("- Fácil de testar com mocks"); + System.out.println("- Flexível para adicionar novos tipos de notificação"); + System.out.println("- Segue o princípio aberto/fechado"); + System.out.println("- Inversão de controle implementada\n"); + } + + private static void demonstrarTestes() { + System.out.println("=".repeat(50)); + System.out.println("🧪 EXEMPLO DE TESTE UNITÁRIO"); + System.out.println("=".repeat(50)); + + MockNotificationService mockService = new MockNotificationService(); + Notificador notificador = new Notificador(mockService); + + // Executar a ação + notificador.notificar("teste@exemplo.com", "Mensagem de teste"); + + // Verificar o resultado + if (mockService.isFoiChamado()) { + System.out.println("✅ Teste passou!"); + System.out.println("📧 Destinatário: " + mockService.getUltimoDestinatario()); + System.out.println("📋 Assunto: " + mockService.getUltimoAssunto()); + System.out.println("💬 Mensagem: " + mockService.getUltimaMensagem()); + } else { + System.out.println("❌ Teste falhou!"); + } + System.out.println(); + } + + private static void demonstrarFactory() { + System.out.println("=".repeat(50)); + System.out.println("🏭 USANDO FACTORY PATTERN COM DIP"); + System.out.println("=".repeat(50)); + + // Criando notificadores usando factory + IServicoNotificacao emailService = NotificationServiceFactory.criarServico(TipoNotificacao.EMAIL); + IServicoNotificacao smsService = NotificationServiceFactory.criarServico(TipoNotificacao.SMS); + + Notificador notificadorFactory1 = new Notificador(emailService); + Notificador notificadorFactory2 = new Notificador(smsService); + + notificadorFactory1.notificar("factory@exemplo.com", "Criado via Factory!"); + notificadorFactory2.notificar("+5511888888888", "SMS via Factory!"); + + System.out.println("✅ Factory Pattern + DIP:"); + System.out.println("- Criação centralizada de objetos"); + System.out.println("- Ainda seguindo o DIP"); + System.out.println("- Código mais limpo e organizadao"); + } +} diff --git a/src/Exercicio5/MockNotificationService.java b/src/Exercicio5/MockNotificationService.java new file mode 100644 index 0000000..bc376bb --- /dev/null +++ b/src/Exercicio5/MockNotificationService.java @@ -0,0 +1,33 @@ +package Exercicio5; + +class MockNotificationService implements IServicoNotificacao{ + private String ultimoDestinatario; + private String ultimoAssunto; + private String ultimaMensagem; + private boolean foiChamado = false; + + @Override + public void enviar(String destinatario, String assunto, String mensagem) { + this.ultimoDestinatario = destinatario; + this.ultimoAssunto = assunto; + this.ultimaMensagem = mensagem; + this.foiChamado = true; + System.out.println("MOCK: Notificação capturada para teste"); + } + + public String getUltimoDestinatario() { + return ultimoDestinatario; + } + + public String getUltimoAssunto() { + return ultimoAssunto; + } + + public String getUltimaMensagem() { + return ultimaMensagem; + } + + public boolean isFoiChamado() { + return foiChamado; + } +} diff --git a/src/Exercicio5/Notificador.java b/src/Exercicio5/Notificador.java new file mode 100644 index 0000000..452051d --- /dev/null +++ b/src/Exercicio5/Notificador.java @@ -0,0 +1,17 @@ +package Exercicio5; + +class Notificador { + private IServicoNotificacao servicoNotificacao; + + public Notificador(IServicoNotificacao servicoNotificacao) { + this.servicoNotificacao = servicoNotificacao; + } + + public void notificar(String destinatario ,String mensagem) { + servicoNotificacao.enviar(destinatario, "Notificação", mensagem); + } + + public void trocarServico(IServicoNotificacao novoServico) { + this.servicoNotificacao = novoServico; + } +} diff --git a/src/Exercicio5/NotificadorProblematico.java b/src/Exercicio5/NotificadorProblematico.java new file mode 100644 index 0000000..f8f8ae8 --- /dev/null +++ b/src/Exercicio5/NotificadorProblematico.java @@ -0,0 +1,13 @@ +package Exercicio5; + +class NotificadorProblematico { + private EmailService emailService; + + public NotificadorProblematico() { + this.emailService = new EmailService(); + } + + public void notificar(String destinatario ,String mensagem) { + emailService.enviarEmail(destinatario, "Notificação", mensagem); + } +} diff --git a/src/Exercicio5/NotificationServiceFactory.java b/src/Exercicio5/NotificationServiceFactory.java new file mode 100644 index 0000000..ccce7ba --- /dev/null +++ b/src/Exercicio5/NotificationServiceFactory.java @@ -0,0 +1,18 @@ +package Exercicio5; + +class NotificationServiceFactory { + public static IServicoNotificacao criarServico(TipoNotificacao tipo) { + switch (tipo) { + case EMAIL: + return new EmailServiceRefatorado(); + case SMS: + return new SMSService(); + case PUSH: + return new PushNotificationService(); + case SLACK: + return new SlackService(); + default: + throw new IllegalArgumentException("Tipo de notificação não suportado" + tipo); + } + } +} diff --git a/src/Exercicio5/PushNotificationService.java b/src/Exercicio5/PushNotificationService.java new file mode 100644 index 0000000..ed264e4 --- /dev/null +++ b/src/Exercicio5/PushNotificationService.java @@ -0,0 +1,11 @@ +package Exercicio5; + +class PushNotificationService implements IServicoNotificacao { + @Override + public void enviar(String destinatario, String assunto, String mensagem) { + System.out.println("Enviando push notification para " + destinatario); + System.out.println("Assunto " + assunto); + System.out.println("Mensagem " + mensagem); + System.out.println("Push notification enviado com sucesso!\n"); + } +} diff --git a/src/Exercicio5/SMSService.java b/src/Exercicio5/SMSService.java new file mode 100644 index 0000000..627b6e6 --- /dev/null +++ b/src/Exercicio5/SMSService.java @@ -0,0 +1,10 @@ +package Exercicio5; + +public class SMSService implements IServicoNotificacao { + @Override + public void enviar(String destinatario, String assunto, String mensagem) { + System.out.println("Enviando SMS para " + destinatario); + System.out.println("Mensagem " + mensagem); + System.out.println("SMS enviado com sucesso!\n"); + } +} diff --git a/src/Exercicio5/SlackService.java b/src/Exercicio5/SlackService.java new file mode 100644 index 0000000..f7b71fa --- /dev/null +++ b/src/Exercicio5/SlackService.java @@ -0,0 +1,11 @@ +package Exercicio5; + +class SlackService implements IServicoNotificacao { + @Override + public void enviar(String destinatario, String assunto, String mensagem) { + System.out.println("Enviando Slack para " + destinatario); + System.out.println("Assunto " + assunto); + System.out.println("Mensagem " + mensagem); + System.out.println("Slack enviado com sucesso!\n"); + } +} diff --git a/src/Exercicio5/TipoNotificacao.java b/src/Exercicio5/TipoNotificacao.java new file mode 100644 index 0000000..9ae02f4 --- /dev/null +++ b/src/Exercicio5/TipoNotificacao.java @@ -0,0 +1,5 @@ +package Exercicio5; + +enum TipoNotificacao { + EMAIL, SMS, PUSH, SLACK +} diff --git a/src/eliakim-simoes-oopII.iml b/src/eliakim-simoes-oopII.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/src/eliakim-simoes-oopII.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file