Download - Android DevConference - SOLID no Android
![Page 1: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/1.jpg)
SOLID no AndroidAndroid Dev Conference 2016
![Page 2: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/2.jpg)
Esses são os slides que apresentei noAndroid Dev Conference 2016.
Acreditei que por não conter nenhum“voice over” seria justo fazer pequenas
adaptações para melhor entendimento,espero que seja útil para você!
![Page 3: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/3.jpg)
Twitter: http://twitter.com/marcellogalhardLinkedIn: https://www.linkedin.com/in/marcellogalhardoGithub: https://github.com/marcellogalhardoE-mail: [email protected]: https://medium.com/@marcellogalhardo
Contatos.
![Page 4: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/4.jpg)
Marcello GalhardoDesenvolvedor Android
![Page 5: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/5.jpg)
![Page 6: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/6.jpg)
![Page 7: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/7.jpg)
Criado em 2000 porRobert C. Martin; 5
princípios deprogramação.
![Page 8: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/8.jpg)
"Paciência você deveter meu jovem
Padawan."
![Page 9: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/9.jpg)
"Quem plantagambiarras, colhe
bugs."
![Page 10: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/10.jpg)
http://martinfowler.com/bliki/DesignStaminaHypothesis.html
Trade Off Qualidade
![Page 11: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/11.jpg)
Princípio daResponsabilidade
ÚnicaSingle Responsibility Principle
![Page 12: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/12.jpg)
"Uma classe deve terum, e somente um,motivo para mudar."
![Page 13: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/13.jpg)
Violação.
![Page 14: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/14.jpg)
public class Produto {
private String descricao; private int quantidade; private long preco;
// ... getters/setters
}
public class Pedido {
private int numeroDoPedido; private List<Produto> produtos = new ArrayList<>();
// ... getters/setters
}
![Page 15: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/15.jpg)
public class PedidoRecyclerAdapter extends RecyclerView.Adapter<PedidoRecyclerAdapter.ViewHolder> { private List<Pedido> pedidos; public OrderRecyclerAdapter(List<Pedido> pedidos) { this.pedidos = pedidos; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(context); View v = inflater.inflate(R.layout.item_pedidos, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder holder, int position) { // TODO: Faz o vínculo entre o modelo e a view } @Override public int getItemCount() { return pedidos.size(); } // ... ViewHolder e métodos
}
![Page 16: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/16.jpg)
@Override public void onBindViewHolder(ViewHolder holder, int position) { Pedido pedido = items.get(position);
holder.numeroDoPedido.setText(pedido.getNumeroDoPedido().toString());
long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US); String valorTotal = formatter.format(total); holder.valorTotalDoPedido.setText(valorTotal);
holder.itemView.setTag(pedido);}
public static class ViewHolder extends RecyclerView.ViewHolder { public TextView numeroDoPedido; public TextView valorTotalDoPedido; // FindViews.}
![Page 17: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/17.jpg)
long total = 0;for (Produto produto : pedido.getProdutos()) { total += produto.getPreco();}NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US);String valorTotal = formatter.format(total);holder.valorTotalDoPedido.setText(valorTotal);
![Page 18: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/18.jpg)
Solução.
![Page 19: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/19.jpg)
public class Pedido {
private int numeroDoPedido; private List<Produto> produtos = new ArrayList<>();
// ... getters/setters
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } return total; }
public String getValorTotalDoPedidoFormatado() { long total = getValorTotalDoPedido(); NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US); String valorTotal = formatter.format(total); return valorTotal; }
}
![Page 20: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/20.jpg)
@Override public void onBindViewHolder(ViewHolder holder, int position) { Pedido pedido = items.get(position); holder.numeroDoPedido.setText(pedido.getNumeroDoPedidoFormatado()); holder.valorTotalDoPedido.setText(pedido.getValorTotalDoPedidoFormato()); holder.itemView.setTag(pedido);}
![Page 21: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/21.jpg)
Rigidez.
![Page 22: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/22.jpg)
Princípio doAberto e Fechado
Open/Closed Principle
![Page 23: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/23.jpg)
"Você deve ser capaz deestender um
comportamento de umaclasse, sem modificá-lo."
![Page 24: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/24.jpg)
Violação.
![Page 25: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/25.jpg)
public class Pedido {
private int numeroDoPedido; private List<Produto> produtos = new ArrayList<>();
// ... getters/setters
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } return total; }
public String getValorTotalDoPedidoFormatado() { long total = getValorTotalDoPedido(); NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US); String valorTotal = formatter.format(total); return valorTotal; }
}
![Page 26: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/26.jpg)
private static final int SEM_DESCONTO = 0;private static final int DESCONTO_10_POR_CENTO = 1;private static final int DESCONTO_15_POR_CENTO = 2;
private int tipoDeDesconto;
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } if (tipoDeDesconto == DESCONTO_10_POR_CENTO) { long descontoDe10PorCento = total * 0.1; total += descontoDe10PorCento; } else if (tipoDeDesconto == DESCONTO_15_POR_CENTO ) { long descontoDe15PorCento = total * 0.15; total += descontoDe15PorCento; } return total;}
![Page 27: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/27.jpg)
public class Pedido {
private static final int SEM_DESCONTO = 0; private static final int DESCONTO_10_POR_CENTO = 1; private static final int DESCONTO_15_POR_CENTO = 2;
private int numeroDoPedido; private List<Produto> produtos = new ArrayList<>(); private int tipoDeDesconto;
// ... getters/setters
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } if (tipoDeDesconto == DESCONTO_10_POR_CENTO) { long descontoDe10PorCento = total * 0.1; total += descontoDe10PorCento; } else if (tipoDeDesconto == DESCONTO_15_POR_CENTO ) { long descontoDe15PorCento = total * 0.15; total += descontoDe15PorCento; } return total; }
public String getValorTotalDoPedidoFormatado() { long total = getValorTotalDoPedido(); NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US); String valorTotal = formatter.format(total); return valorTotal; }
}
![Page 28: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/28.jpg)
private static final int SEM_DESCONTO = 0;private static final int DESCONTO_10_POR_CENTO = 1;private static final int DESCONTO_15_POR_CENTO = 2;private static final int DESCONTO_20_POR_CENTO = 3;private static final int DESCONTO_25_POR_CENTO = 4;
private int tipoDeDesconto;
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } if (tipoDeDesconto == DESCONTO_10_POR_CENTO) { long descontoDe10PorCento = total * 0.1; total += descontoDe10PorCento; } else if (tipoDeDesconto == DESCONTO_15_POR_CENTO) { long descontoDe15PorCento = total * 0.15; total += descontoDe15PorCento; } else if (tipoDeDesconto == DESCONTO_20_POR_CENTO) { long descontoDe20PorCento = total * 0.20; total += descontoDe20PorCento; } else if (tipoDeDesconto == DESCONTO_25_POR_CENTO) { long descontoDe25PorCento = total * 0.25; total += descontoDe25PorCento; } return total;}
![Page 29: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/29.jpg)
Solução.
![Page 30: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/30.jpg)
public interface Desconto {
long calculaDesconto(long valor);
}
![Page 31: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/31.jpg)
public interface Desconto {
long calculaDesconto(long valor);
}
// Padrão de Projeto: Objeto Nulo.public class SemDesconto implements Desconto {
public long calculaDesconto(long valor) { return 0; }
}
public class DescontoDe10PorCento implements Desconto {
public long calculaDesconto(long valor) { return valor * 0.1; }
}
public class DescontoDe15PorCento implements Desconto {
public long calculaDesconto(long valor) { return valor * 0.15; }
}
// Outros descontos.
![Page 32: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/32.jpg)
Objeto Nulo
![Page 33: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/33.jpg)
private Desconto desconto = new SemDesconto();
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } // Não é necessário verificar se o desconto é null, pois // sempre existirá um desconto vazio: SemDesconto. desconto = desconto.calculaDesconto(total); return total + desconto;}
![Page 34: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/34.jpg)
public class Pedido {
private int numeroDoPedido; private List<Produto> produtos = new ArrayList<>(); private Desconto desconto = new SemDesconto();
// ... getters/setters
public long getValorTotalDoPedido() { long total = 0; for (Produto produto : pedido.getProdutos()) { total += produto.getPreco(); } desconto = desconto.calculaDesconto(total); return total + desconto; }
public String getValorTotalDoPedidoFormatado() { long total = getValorTotalDoPedido(); NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US); String valorTotal = formatter.format(total); return valorTotal; }
}
![Page 35: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/35.jpg)
Princípio daSubstituição de
LiskovLiskov Substitution Principle
![Page 36: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/36.jpg)
"Classes derivadasdevem ser
substituíveis porsuas classes base."
![Page 37: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/37.jpg)
Violação.
![Page 38: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/38.jpg)
// Violação do Princípio de Liskov.
public interface Carro {
public void partidaNoMotor();}
public class Ferrari implements Carro {
@Override public double partidaNoMotor() { // TODO: Lógica. }}
public class Tesla implements Carro {
@Override public void ligaCarro() { // TODO: Lógica. }
@Override public double partidaNoMotor() { // TODO: Lógica. }}
// Iniciar Carro.public void iniciarPartidaDeCarro(Carro carro) { carro.partidaNoMotor();}
![Page 39: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/39.jpg)
// "Tentativa de correção" do princípio de Liskov.
public void iniciarPartidaDeCarro(Carro carro) { if (carro instanceof Tesla) { Tesla tesla = (Tesla) carro; tesla.ligaCarro(); } carro.partidaNoMotor();}
![Page 40: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/40.jpg)
Solução.
![Page 41: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/41.jpg)
// Correção do Princípio de Liskov
public interface Carro { public void partidaNoMotor();}
public class Ferrari implements Carro {
@Override public double partidaNoMotor() { // TODO: Implementação. }
}
public class Tesla implements Carro {
// Implementação do ligaCarro();
@Override public double partidaNoMotor() { if (!estaDescarregado) { ligaCarro(); } // TODO: Implementação. }
}
// Iniciar Carro.public void iniciarPartidaDeCarro(Carro carro) { carro.partidaNoMotor();}
![Page 42: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/42.jpg)
Princípio daSegregação de
InterfaceInterface Segregation Principle
![Page 43: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/43.jpg)
"Muitas interfacesespecíficas são
melhores do queuma interface
única."
![Page 44: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/44.jpg)
Violação.
![Page 45: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/45.jpg)
public interface OnClickListener {
void onClick(View v);
void onLongClick(View v);
void onTouch(View v, MotionEvent event);
}
![Page 46: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/46.jpg)
// Violação do Princípio da Segregação de Interfaces
Button botao = (Button) findViewById(R.id.botao);botao.setOnClickListener(new View.OnClickListener {
public void onClick(View v) { // TODO: Faz algo bem legal... } public void onLongClick(View v) { // Não precisamos disso. }
public void onTouch(View v, MotionEvent event) { // Disso também não. }
});
![Page 47: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/47.jpg)
Solução.
![Page 48: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/48.jpg)
// Correção do Princípio da Segregação de Interfaces.
public interface OnClickListener { void onClick(View v);}
public interface OnLongClickListener { void onLongClick(View v);}
public interface OnTouchListener { void onTouch(View v, MotionEvent event);}
![Page 49: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/49.jpg)
Princípio daInversão da
DependênciaDependency Inversion Principle
![Page 50: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/50.jpg)
"Dependa de umaabstração e não de
umaimplementação."
![Page 51: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/51.jpg)
Violação.
![Page 52: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/52.jpg)
// Violação do Princípio da Inversão de Dependência.
class Presenter {
private final UsuarioRepositorio usuarioRepositorio = new UsuarioRepositorio();
// TODO: Implementação diversas.
}
class UsuarioRepositorio {
public getUsuario() { // TODO: Recupera o usuário conectado. }
}
![Page 53: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/53.jpg)
Solução.
![Page 54: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/54.jpg)
// Correção do Princípio da Inversão de Dependência.
class Presenter {
private final UsuarioRepositorio usuarioRepositorio;
@Inject public Presenter(UsuarioRepositorio usuarioRepositorio) { this.usuarioRepositorio = usuarioRepositorio; }
// TODO: Implementação diversas.
}
interface UsuarioRepositorio {
Usuario getUsuario();
}
class UsuarioManager implements UsuarioRepositorio {
@Override public getUsuario() { // TODO: Recupera o usuário conectado. }
}
![Page 55: Android DevConference - SOLID no Android](https://reader031.vdocuments.com.br/reader031/viewer/2022022419/5870803a1a28ab57368b62eb/html5/thumbnails/55.jpg)