Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/com/lojaonline/LojaOnline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.lojaonline;

import com.lojaonline.envio.GerenciadorEnvio;
import com.lojaonline.pagamento.*;
import com.lojaonline.pedido.Pedido;
import com.lojaonline.produtos.Produto;
import com.lojaonline.repositorio.EmMemoriaPedidoRepositorio;
import com.lojaonline.servicos.ServicoPedido;

import java.util.List;

public class LojaOnline {
public static void main(String[] args) {
var repo = new EmMemoriaPedidoRepositorio();

// Posso trocar o metodo de pagamento livremente (OCP + LSP)
PagamentoPort pagamento = new ProcessadorPagamento<>(new CartaoCredito());
// PagamentoPort pagamento = new ProcessadorPagamento<>(new Pix());
// PagamentoPort pagamento = new ProcessadorPagamento<>(new Boleto());

var envio = new GerenciadorEnvio();
var servico = new ServicoPedido(repo, pagamento, envio);

var itens = List.of(
new Produto("Motoserra", 1500.00),
new Produto("Capacete", 300.00),
new Produto("Luvas", 50.00)
);

var pedido = new Pedido(itens, "Rua das Flores, 123");
long id = servico.criarNovoPedido(pedido);
servico.processarPedido(id);
servico.enviarPedido(id);
}
}


6 changes: 6 additions & 0 deletions src/com/lojaonline/envio/EnvioPort.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.lojaonline.envio;

// ISP: contrato mínimo para envio.
public interface EnvioPort {
void enviarPara(String endereco);
}
8 changes: 8 additions & 0 deletions src/com/lojaonline/envio/GerenciadorEnvio.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lojaonline.envio;

public class GerenciadorEnvio implements EnvioPort {
@Override
public void enviarPara(String endereco) {
System.out.println("Enviando pedido para: " + endereco);
}
}
8 changes: 8 additions & 0 deletions src/com/lojaonline/pagamento/Boleto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lojaonline.pagamento;

public class Boleto implements MetodoPagamento {
@Override
public void processarPagamento(double valor) {
System.out.println("Boleto gerado e compensado: R$ " + valor);
}
}
8 changes: 8 additions & 0 deletions src/com/lojaonline/pagamento/CartaoCredito.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lojaonline.pagamento;

public class CartaoCredito implements MetodoPagamento {
@Override
public void processarPagamento(double valor) {
System.out.println("Pagamento aprovado via Cartão de Crédito: R$ " + valor);
}
}
6 changes: 6 additions & 0 deletions src/com/lojaonline/pagamento/MetodoPagamento.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.lojaonline.pagamento;

// ISP: contrato pequeno e específico.
public interface MetodoPagamento {
void processarPagamento(double valor);
}
6 changes: 6 additions & 0 deletions src/com/lojaonline/pagamento/PagamentoPort.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.lojaonline.pagamento;

// DIP: porta de alto nível para o serviço depender.
public interface PagamentoPort {
void pagar(double valor);
}
8 changes: 8 additions & 0 deletions src/com/lojaonline/pagamento/Pix.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lojaonline.pagamento;

public class Pix implements MetodoPagamento {
@Override
public void processarPagamento(double valor) {
System.out.println("Pagamento confirmado via PIX: R$ " + valor);
}
}
16 changes: 16 additions & 0 deletions src/com/lojaonline/pagamento/ProcessadorPagamento.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.lojaonline.pagamento;

// LSP: qualquer MetodoPagamento pode ser plugado sem quebrar cliente.
// DIP/ISP: expõe apenas PagamentoPort para o serviço.
public class ProcessadorPagamento<T extends MetodoPagamento> implements PagamentoPort {
private final T metodo;

public ProcessadorPagamento(T metodo) {
this.metodo = metodo;
}

@Override
public void pagar(double valor) {
metodo.processarPagamento(valor);
}
}
34 changes: 34 additions & 0 deletions src/com/lojaonline/pedido/Pedido.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.lojaonline.pedido;

import com.lojaonline.produtos.Produto;
import java.util.ArrayList;
import java.util.List;

// SRP: dados e regras do pedido (sem pagar/enviar aqui).
public class Pedido {
private Long id;
private final List<Produto> itens = new ArrayList<>();
private StatusPedido status = StatusPedido.PENDENTE;
private final String enderecoEntrega;

public Pedido(List<Produto> itens, String enderecoEntrega) {
if (itens != null) itens.forEach(this.itens::add);
this.enderecoEntrega = enderecoEntrega;
}

public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

public StatusPedido getStatus() { return status; }
public void setStatus(StatusPedido status) { this.status = status; }

public String getEnderecoEntrega() { return enderecoEntrega; }
public List<Produto> getItens() { return List.copyOf(itens); }

public void addItem(Produto p) { itens.add(p); }
public void removerItem(Produto p) { itens.remove(p); }

public double calcularTotal() {
return itens.stream().mapToDouble(Produto::getPreco).sum();
}
}
5 changes: 5 additions & 0 deletions src/com/lojaonline/pedido/StatusPedido.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.lojaonline.pedido;

public enum StatusPedido {
PENDENTE, PAGO, ENVIADO, CANCELADO
}
18 changes: 18 additions & 0 deletions src/com/lojaonline/produtos/Produto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.lojaonline.produtos;

import java.util.Objects;

// SRP: representa um produto.
public class Produto {
private final String nome;
private final double preco;

public Produto(String nome, double preco) {
this.nome = Objects.requireNonNull(nome, "nome obrigatório");
if (preco < 0) throw new IllegalArgumentException("Preço não pode ser negativo");
this.preco = preco;
}

public String getNome() { return nome; }
public double getPreco() { return preco; }
}
33 changes: 33 additions & 0 deletions src/com/lojaonline/repositorio/EmMemoriaPedidoRepositorio.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.lojaonline.repositorio;

import com.lojaonline.pedido.Pedido;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

// Implementação simples para rodar e testar sem BD/JPA.
public class EmMemoriaPedidoRepositorio implements PedidoRepositorio {
private final Map<Long, Pedido> store = new ConcurrentHashMap<>();
private long seq = 0L;

@Override
public void salvar(Pedido pedido) {
if (pedido.getId() == null) {
seq++;
pedido.setId(seq);
}
store.put(pedido.getId(), pedido);
}

@Override
public Optional<Pedido> buscarPorId(long id) {
return Optional.ofNullable(store.get(id));
}

@Override
public List<Pedido> buscarPorStatus(String status) {
return store.values().stream()
.filter(p -> p.getStatus().name().equalsIgnoreCase(status))
.collect(Collectors.toList());
}
}
12 changes: 12 additions & 0 deletions src/com/lojaonline/repositorio/PedidoRepositorio.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.lojaonline.repositorio;

import com.lojaonline.pedido.Pedido;
import java.util.List;
import java.util.Optional;

// ISP + DIP: contrato específico (nada de Object).
public interface PedidoRepositorio {
void salvar(Pedido pedido);
Optional<Pedido> buscarPorId(long id);
List<Pedido> buscarPorStatus(String status);
}
48 changes: 48 additions & 0 deletions src/com/lojaonline/servicos/ServicoPedido.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.lojaonline.servicos;

import com.lojaonline.envio.EnvioPort;
import com.lojaonline.pagamento.PagamentoPort;
import com.lojaonline.pedido.Pedido;
import com.lojaonline.pedido.StatusPedido;
import com.lojaonline.repositorio.PedidoRepositorio;

// SRP: orquestra o fluxo; DIP: depende só de portas.
public class ServicoPedido {
private final PedidoRepositorio repo;
private final PagamentoPort pagamento;
private final EnvioPort envio;

public ServicoPedido(PedidoRepositorio repo, PagamentoPort pagamento, EnvioPort envio) {
this.repo = repo;
this.pagamento = pagamento;
this.envio = envio;
}

public long criarNovoPedido(Pedido pedido) {
repo.salvar(pedido);
System.out.println("Novo pedido criado! id=" + pedido.getId());
return pedido.getId();
}

public void processarPedido(long id) {
var pedido = repo.buscarPorId(id).orElseThrow(() -> new IllegalArgumentException("Pedido não encontrado"));
if (pedido.getStatus() != StatusPedido.PENDENTE) {
throw new IllegalStateException("Apenas pedidos PENDENTES podem ser pagos.");
}
pagamento.pagar(pedido.calcularTotal());
pedido.setStatus(StatusPedido.PAGO);
repo.salvar(pedido);
System.out.println("Pedido pago com sucesso!");
}

public void enviarPedido(long id) {
var pedido = repo.buscarPorId(id).orElseThrow(() -> new IllegalArgumentException("Pedido não encontrado"));
if (pedido.getStatus() != StatusPedido.PAGO) {
throw new IllegalStateException("Só é possível enviar pedidos pagos.");
}
envio.enviarPara(pedido.getEnderecoEntrega());
pedido.setStatus(StatusPedido.ENVIADO);
repo.salvar(pedido);
System.out.println("Pedido enviado com sucesso!");
}
}
11 changes: 11 additions & 0 deletions src/oopII.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>