SlideShare uma empresa Scribd logo
1 de 57
Os cinco princípios ágeis de POO
Autor: Ramon Valerio da Silva
Desenvolvedor de Sistemas na Tecgraf PUC-RIO
E-mail: ramonvalerios@gmail.com
Os Princípios SOLID
Identificados por Robert C. Martin (mais conhecido como Uncle Bob) por volta do ano 2000.
● SRP - Princípio da Responsabilidade Única
● OCP - Princípio do Aberto e Fechado
● LSP - Princípio da Substituição de Liskov
● ISP - Princípio da Segregação de Interfaces
● DIP - Princípio da Inversão de Dependência
SOLID - Benefícios
● Fácil de se manter, adaptar e se ajustar às alterações de
escopo;
● Fácil de entender e testar;
● Construído para ter alterações com o menor esforço
possível;
● Possibilidade de ser reaproveitado;
● Maior tempo possível em produção;
SOLID - Possíveis problemas evitados
● Dificuldade na testabilidade / Criação de testes de
unidade;
● Código espaguete, sem estrutura ou padrão;
● Dificuldades de isolar funcionalidades;
● Duplicação de código, uma alteração precisa ser feita
em N pontos;
● Fragilidade, o código quebra facilmente em vários
pontos após alguma mudança.
SOLID - SRP(Single Responsability Principle)
“O SRP é o primeiro e mais importante, e se não respeitá-lo,
provavelmente vai comprometer o resto dos princípios.”
“Uma classe deve ter um, e apenas um, motivo para ser
modificada”.
● Um arquivo de classe, deve ter apenas uma classe.
● Um método deve ter apenas uma responsabilidade.
● Um evento deve ter apenas uma responsabilidade.
SRP - Estrutura da violação
“Esta classe está assumindo muitas responsabilidades e violando os princípios do SRP.”
SRP - Quantas violações esta classe possui?
public class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get;set;}
public string Incluir()
{
if (!Email.Contains("@"))
return "Cliente com e-mail inválido";
if (CPF.Length != 11)
return "Cliente com CPF inválido";
using (var conexao = new OracleConnection())
{
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO CLIENTE (NOME,
EMAIL CPF, DATACADASTRO) VALUES (@nome, @email,
@cpf, @dataCad))";
cmd.Parameters.AddWithValue("nome", Nome);
cmd.Parameters.AddWithValue("email", Email);
cmd.Parameters.AddWithValue("cpf", CPF);
cmd.Parameters.AddWithValue("dataCad", DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
var mail = new MailMessage("tecgraf@tecgraf.com",
Email);
var client = new SmtpClient
{
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = "smtp.google.com"
};
mail.Subject = "Bem-vindo.";
mail.Body = "Parabéns! Você está casastrado.";
client.Send(mail);
return "Cliente cadastrado com sucesso!";
}
SRP - Violações
public class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get;set;}
public string Incluir()
{
if (!Email.Contains("@"))
return "Cliente com e-mail inválido";
if (CPF.Length != 11)
return "Cliente com CPF inválido";
using (var conexao = new OracleConnection())
{
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO CLIENTE (NOME,
EMAIL CPF, DATACADASTRO) VALUES (@nome, @email,
@cpf, @dataCad))";
cmd.Parameters.AddWithValue("nome", Nome);
cmd.Parameters.AddWithValue("email", Email);
cmd.Parameters.AddWithValue("cpf", CPF);
cmd.Parameters.AddWithValue("dataCad", DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
var mail = new MailMessage("tecgraf@tecgraf.com",
Email);
var client = new SmtpClient
{
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = "smtp.google.com"
};
mail.Subject = "Bem-vindo.";
mail.Body = "Parabéns! Você está casastrado.";
client.Send(mail);
return "Cliente cadastrado com sucesso!";
}
SRP - Violações
public class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get;set;}
public string Incluir()
{
if (!Email.Contains("@"))
return "Cliente com e-mail inválido";
if (CPF.Length != 11)
return "Cliente com CPF inválido";
using (var conexao = new OracleConnection())
{
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO CLIENTE (NOME,
EMAIL CPF, DATACADASTRO) VALUES (@nome, @email,
@cpf, @dataCad))";
cmd.Parameters.AddWithValue("nome", Nome);
cmd.Parameters.AddWithValue("email", Email);
cmd.Parameters.AddWithValue("cpf", CPF);
cmd.Parameters.AddWithValue("dataCad", DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
var mail = new MailMessage("tecgraf@tecgraf.com",
Email);
var client = new SmtpClient
{
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = "smtp.google.com"
};
mail.Subject = "Bem-vindo.";
mail.Body = "Parabéns! Você está casastrado.";
client.Send(mail);
return "Cliente cadastrado com sucesso!";
}
SRP - Violações
public class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get;set;}
public string Incluir()
{
if (!Email.Contains("@"))
return "Cliente com e-mail inválido";
if (CPF.Length != 11)
return "Cliente com CPF inválido";
using (var conexao = new OracleConnection())
{
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO CLIENTE (NOME,
EMAIL CPF, DATACADASTRO) VALUES (@nome, @email,
@cpf, @dataCad))";
cmd.Parameters.AddWithValue("nome", Nome);
cmd.Parameters.AddWithValue("email", Email);
cmd.Parameters.AddWithValue("cpf", CPF);
cmd.Parameters.AddWithValue("dataCad", DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
var mail = new MailMessage("tecgraf@tecgraf.com",
Email);
var client = new SmtpClient
{
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = "smtp.google.com"
};
mail.Subject = "Bem-vindo.";
mail.Body = "Parabéns! Você está casastrado.";
client.Send(mail);
return "Cliente cadastrado com sucesso!";
}
SRP - Violações
public class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get;set;}
public string Incluir()
{
if (!Email.Contains("@"))
return "Cliente com e-mail inválido";
if (CPF.Length != 11)
return "Cliente com CPF inválido";
using (var conexao = new OracleConnection())
{
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO CLIENTE (NOME,
EMAIL CPF, DATACADASTRO) VALUES (@nome, @email,
@cpf, @dataCad))";
cmd.Parameters.AddWithValue("nome", Nome);
cmd.Parameters.AddWithValue("email", Email);
cmd.Parameters.AddWithValue("cpf", CPF);
cmd.Parameters.AddWithValue("dataCad", DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
var mail = new MailMessage("tecgraf@tecgraf.com",
Email);
var client = new SmtpClient
{
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = "smtp.google.com"
};
mail.Subject = "Bem-vindo.";
mail.Body = "Parabéns! Você está casastrado.";
client.Send(mail);
return "Cliente cadastrado com sucesso!";
}
SRP - Estrutura da solução
“Estas classes possuem apenas um motivo para serem alteradas, assumindo uma
única responsabilidade, e respeitando o SRP.”
SRP - Soluções
public class Cliente {
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get; set; }
public bool IsValid() {
return EmailServices.IsValid(Email) && CPFServices.IsValid(CPF);
}
}
SRP - Soluções
public class ClienteRepository {
public void Incluir(Cliente cliente) {
using (var conexao = new OracleConnection()) {
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))";
cmd.Parameters.AddWithValue("nome", cliente.Nome);
cmd.Parameters.AddWithValue("email", cliente.Email);
cmd.Parameters.AddWithValue("cpf", cliente.CPF);
cmd.Parameters.AddWithValue("dataCad", cliente.DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
SRP - Soluções
public class ClienteService {
public string Incluir(Cliente cliente)
{
if (!cliente.IsValid())
return "Dados inválidos";
var repositorio = new ClienteRepository();
repositorio.Incluir(cliente);
EmailServices.Enviar("tecgraf@tecgraf.com", cliente.Email, "Bem-vindo", "Parabéns está Cadastrado");
return "Cliente cadastrado com sucesso";
}
}
SRP - Soluções
public static class EmailServices {
public static bool IsValid(string email) {
return email.Contains("@");
}
public static void Enviar(string de, string para, string assunto, string mensagem) {
var mail = new MailMessage(de, para);
var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false, Host = "smtp.google.com"
};
mail.Subject = assunto;
mail.Body = mensagem;
client.Send(mail);
}
}
SRP - Soluções
public static class CPFServices
{
public static bool IsValid(string cpf)
{
return cpf.Length == 11;
}
}
SOLID - OCP(Open Closed Principle)
“Você deve ser capaz de estender um
comportamento de uma classe, sem modificá-la.”
“Entidades de softwares (classes, módulos, funções, etc) devem
estar abertas para extensão, mas fechadas para modificação.”
OCP - Estrutura da violação
“A classe DebitoConta está assumindo muitas responsabilidades e
violando os princípios do SRP.”
OCP - Onde estão as violações desta classe?
public class DebitoConta {
public void Debitar(decimal valor, string conta, TipoConta tipoConta) {
if (tipoConta == TipoConta.Corrente) {
// Debita Conta Corrente
}
if (tipoConta == TipoConta.Poupanca) {
// Valida Aniversário da Conta
// Debita Conta Poupança
}
}
}
public enum TipoConta
{
Corrente,
Poupanca
}
OCP - Violações
public class DebitoConta {
public void Debitar(decimal valor, string conta, TipoConta tipoConta) {
if (tipoConta == TipoConta.Corrente) {
// Debita Conta Corrente
}
if (tipoConta == TipoConta.Poupanca) {
// Valida Aniversário da Conta
// Debita Conta Poupança
}
}
}
public enum TipoConta
{
Corrente,
Poupanca
}
OCP - Estrutura da solução
“Estas classes estão assumindo uma única responsabilidade.”
OCP - Soluções
public abstract class DebitoConta
{
public string NumeroTransacao { get; set; }
public abstract string Debitar(decimal valor, string conta);
}
OCP - Soluções
public class DebitoContaCorrente : DebitoConta
{
public override string Debitar(decimal valor, string conta)
{
// Debita Conta Corrente
return NumeroTransacao;
}
}
OCP - Soluções
public class DebitoContaPoupanca : DebitoConta
{
public override string Debitar(decimal valor, string conta)
{
// Valida Aniversário da Conta
// Debita Conta Poupança
return NumeroTransacao;
}
}
OCP - Soluções
public class DebitoContaInvestimento : DebitoConta
{
public override string Debitar(decimal valor, string conta)
{
// Debita Conta Investimento
// Isentar Taxas
return NumeroTransacao;
}
}
SOLID - LSP(Liskov Substitution Principle)
“Uma classe base deve poder ser substituída pela sua classe derivada.”
“Se nada como um pato, voa como um pato, porém precisa de baterias, provavelmente você
possui um problema de abstração.”
“As classes derivadas devem ser substituíveis por suas classes base.”
LSP - Estrutura da Violação
LSP - Violações
public class Ave
{
public virtual void Voar()
{
Console.WriteLine("Voando");
}
}
LSP - Violações
public class Aguia: Ave
{
public override void Voar()
{
base.Voar();
Console.WriteLine("Voar sempre alto...");
}
}
LSP - Violações
public class Pato: Ave
{
public override void Voar()
{
base.Voar();
Console.WriteLine("Voar sempre baixo...");
}
}
LSP - Violações
public class Avestruz : Ave
{
public override void Voar()
{
Console.WriteLine("Ops... eu não posso voar!!");
}
}
LSP - Violações
public class Program
{
static void Main()
{
var aves = new List<Ave>();
aves.Add(new Aguia());
aves.Add(new Pato());
aves.Add(new Avestruz());
foreach (Ave ave in aves)
{
ave.Voar();
}
}
}
LSP - Estrutura da Solução
LSP - Violações
public class Retangulo
{
protected virtual double Altura { get; set; }
protected virtual double Largura { get; set; }
public double GetArea()
{
return Altura * Largura;
}
}
LSP - Violações
public class Quadrado : Retangulo
{
public override double Altura
{
set { base.Altura = base.Largura = value; }
}
public override double Largura
{
set { base.Altura = base.Largura = value; }
}
}
LSP - Violações
public class Program {
private static void ObterAreaRetangulo(Retangulo retangulo) {
Console.WriteLine("Calculo da área do Retangulo");
Console.WriteLine(retangulo.Altura + " x " + retangulo.Largura);
Console.WriteLine(“Resultado: ” + retangulo.GetArea());
Console.ReadKey();
}
private static void Main() {
var quadrado = new Quadrado(){ Altura = 10, Largura = 5};
ObterAreaRetangulo(quadrado);
}
}
Calculo da área do Retangulo
5 x 5
Resultado: 25
SOLID - ISP(Interface Segregation Principle)
“Classes não devem ser forçadas a depender de
métodos que não usam.”
“Muitas interfaces específicas são melhores do que
uma única interface.”
ISP - Violações
public interface IFormCadastro
{
void Validar();
void Salvar();
void EnviarEmail();
}
ISP - Violações
public class FormCadastroCliente : IFormCadastro
{
public void Validar()
{
// Validar CPF, Email
}
public void Salvar()
{
// Insert na tabela Cliente
}
public void EnviarEmail()
{
// Enviar e-mail para o cliente
}
}
ISP - Violações
public class FormCadastroProduto : IFormCadastro
{
public void Validar()
{
// Validar valor
}
public void Salvar()
{
// Insert tabela Produto
}
public void EnviarEmail()
{
// Produto não tem e-mail, o que eu faço agora???
}
}
ISP - Soluções
public interface IFormCadastroCliente
{
void Validar();
void Salvar();
void Enviar();
}
public interface IFormCadastroProduto
{
void Validar();
void Salvar();
}
ISP - Soluções
public class CadastroCliente : ICadastroCliente {
public void Validar() {
// Validar CPF, Email
}
public void Salvar() {
// Insert na tabela Cliente
}
public void EnviarEmail() {
// Enviar e-mail para o cliente
}
}
public class CadastroProduto : ICadastroProduto {
public void Validar() {
// Validar valor
}
public void Salvar() {
// Insert tabela Produto
}
}
SOLID - DIP(Dependency Inversion Principle)
“Módulos de alto nível não devem depender de
módulos de baixo nível. Ambos devem depender
de abstrações;”
“Abstrações não devem depender de detalhes;
Detalhes devem depender de abstrações.”
DIP - Estrutura da violação
“Estas classes não contém interfaces para padronizar seus métodos e também não possui o recurso da abstração
das interfaces, deixando a estrutura fortemente acoplada, ou seja, com muitas dependências, violando os princípios
do DIP.”
DIP - Violações
public class Cliente {
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get; set; }
public bool IsValid() {
return EmailServices.IsValid(Email) && CPFServices.IsValid(CPF);
}
}
“FORTE ACOPLAMENTO!”
DIP - Violações
public class ClienteService
{
public string Incluir(Cliente cliente)
{
if (!cliente.IsValid())
return "Dados inválidos";
var repositorio = new ClienteRepository();
repositorio.Incluir(cliente);
EmailServices.Enviar("tecgraf@tecgraf.com", cliente.Email, "Bem-vindo", "Parabéns está Cadastrado");
return "Cliente cadastrado com sucesso";
}
}
“FORTE ACOPLAMENTO!”
DIP - Violações
public static class CPFServices
{
public static bool IsValid(string cpf)
{
return cpf.Length == 11;
}
}
DIP - Violações
public static class EmailServices {
public static bool IsValid(string email) {
return email.Contains("@");
}
public static void Enviar(string de, string para, string assunto, string mensagem) {
var mail = new MailMessage(de, para);
var client = new SmtpClient {
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = "smtp.google.com"
};
mail.Subject = assunto;
mail.Body = mensagem;
client.Send(mail);
}
}
DIP - Violações
public class ClienteRepository {
public void Incluir(Cliente cliente) {
using (var conexao = new OracleConnection())
{
conexao.ConnectionString = "MinhaConnectionString";
var cmd = new OracleCommand(conexao);
cmd.CommandText = "INSERT INTO CLIENTE(NOME, EMAIL CPF, DATACADASTRO) VALUES(@nome, @email, @cpf, @dataCad)";
cmd.Parameters.AddWithValue("nome", cliente.Nome);
cmd.Parameters.AddWithValue("email", cliente.Email);
cmd.Parameters.AddWithValue("cpf", cliente.CPF);
cmd.Parameters.AddWithValue("dataCad", cliente.DataCadastro);
conexao.Open();
cmd.ExecuteNonQuery();
conexao.Close();
}
}
}
DIP - Estrutura da solução
IClienteRepository
IClienteService
IEmailService
ICPFService
“Agora eu posso usar as interfaces como abstrações das classes que o implementam, deixando a
estrutura com baixo acoplamento, ou seja sem dependência.”
DIP - Soluções
public class Cliente {
private readonly ICPFServices _cpfServices;
private readonly IEmailServices _emailServices;
public Cliente(ICPFServices cpfServices, IEmailServices emailServices) {
_cpfServices = cpfServices; _emailServices = emailServices;
}
public int ClienteId { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string CPF { get; set; }
public DateTime DataCadastro { get; set; }
public bool IsValid(){
return _emailServices.IsValid(Email) && _cpfServices.IsValid(CPF);
} }
DIP - Soluções
public class ClienteService : IClienteServices {
private readonly IClienteRepository _clienteRepository;
private readonly IEmailServices _emailServices;
public ClienteServices(IClienteRepository clienteRepository, IEmailServices emailServices) {
_clienteRepository = clienteRepository; _emailServices = emailServices;
}
public string Incluir(Cliente cliente) {
if (!cliente.IsValid())
return "Dados inválidos";
_clienteRepository.Incluir(cliente);
_emailServices.Enviar("tecgraf@tecgraf.com", cliente.Email, "Bem-vindo", "Parabéns está Cadastrado");
return "Cliente cadastrado com sucesso";
}
}
DIP - Exemplo de um Container de DI
private static void RegisterServices(IKernel kernel)
{
//Service
kernel.Bind<IClienteService>().To<ClienteService>();
kernel.Bind<ICPFService>().To<CPFService>();
kernel.Bind<IEmailService>().To<EmailService>();
//Repository
kernel.Bind<IClienteRepository>().To<ClienteRepository>();
}
“Um homem sábio pode aprender mais com uma pergunta tola do que um
tolo pode aprender a partir de uma resposta sensata.”
1 - Quais os benefícios em usar o SRP?
2 - Por que usar OCP se eu posso colocar mais um if ou criar enums e
flags que resolve muito mais rápido?
3 - O que viola o LSP?
4 - No ISP usar muitas interfaces específicas é bom ou ruim, e
porque?
5 - Quais são as vantagens do DIP? Quais princípios eu devo
respeitar para aplicar o DIP?
6 - Quais são os benefícios de um software usando princípios SOLID?
Livros recomendados
Obrigado a todos pela participação!

Mais conteúdo relacionado

Mais procurados

58754491 tabela-antibioticos
58754491 tabela-antibioticos58754491 tabela-antibioticos
58754491 tabela-antibioticosRenata Figueredo
 
Febre reumática (davyson sampaio braga)
Febre reumática (davyson sampaio braga)Febre reumática (davyson sampaio braga)
Febre reumática (davyson sampaio braga)Davyson Sampaio
 
Tabela de farmacos HAS, antianginosos, hipolipêmicos
Tabela de farmacos HAS, antianginosos, hipolipêmicosTabela de farmacos HAS, antianginosos, hipolipêmicos
Tabela de farmacos HAS, antianginosos, hipolipêmicosTamara Garcia
 
Apresentação raciocionio clínico
Apresentação raciocionio clínicoApresentação raciocionio clínico
Apresentação raciocionio clínicojaninemagalhaes
 
Fisiologia sistema endócrino suprarenais
Fisiologia sistema endócrino suprarenaisFisiologia sistema endócrino suprarenais
Fisiologia sistema endócrino suprarenaisjrdsm06
 
Neurofibromatose
NeurofibromatoseNeurofibromatose
Neurofibromatosegabrielrb87
 
Iv curso teórico prático - aula ac bas
Iv curso teórico prático - aula ac basIv curso teórico prático - aula ac bas
Iv curso teórico prático - aula ac basctisaolucascopacabana
 
Síndromes Respiratórias - Semioliga UFMT
Síndromes Respiratórias - Semioliga UFMTSíndromes Respiratórias - Semioliga UFMT
Síndromes Respiratórias - Semioliga UFMTSemioliga UFMT
 
Hipertensão pulmonar
Hipertensão pulmonarHipertensão pulmonar
Hipertensão pulmonardapab
 
INSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTA
INSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTAINSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTA
INSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTApauloalambert
 
Cardiopatias congênitas cianogênicas
Cardiopatias congênitas cianogênicasCardiopatias congênitas cianogênicas
Cardiopatias congênitas cianogênicasresenfe2013
 
Aula aval testes diagnósticos
Aula aval testes diagnósticosAula aval testes diagnósticos
Aula aval testes diagnósticosDaniela Lima
 

Mais procurados (20)

58754491 tabela-antibioticos
58754491 tabela-antibioticos58754491 tabela-antibioticos
58754491 tabela-antibioticos
 
Febre reumática (davyson sampaio braga)
Febre reumática (davyson sampaio braga)Febre reumática (davyson sampaio braga)
Febre reumática (davyson sampaio braga)
 
Síndrome Metabólica na Infância
Síndrome Metabólica na InfânciaSíndrome Metabólica na Infância
Síndrome Metabólica na Infância
 
Tabela de farmacos HAS, antianginosos, hipolipêmicos
Tabela de farmacos HAS, antianginosos, hipolipêmicosTabela de farmacos HAS, antianginosos, hipolipêmicos
Tabela de farmacos HAS, antianginosos, hipolipêmicos
 
Ascite
AsciteAscite
Ascite
 
Apresentação raciocionio clínico
Apresentação raciocionio clínicoApresentação raciocionio clínico
Apresentação raciocionio clínico
 
Fisiologia sistema endócrino suprarenais
Fisiologia sistema endócrino suprarenaisFisiologia sistema endócrino suprarenais
Fisiologia sistema endócrino suprarenais
 
Neurofibromatose
NeurofibromatoseNeurofibromatose
Neurofibromatose
 
Neoplasias Periampulares
Neoplasias PeriampularesNeoplasias Periampulares
Neoplasias Periampulares
 
Iv curso teórico prático - aula ac bas
Iv curso teórico prático - aula ac basIv curso teórico prático - aula ac bas
Iv curso teórico prático - aula ac bas
 
Hemorragia intraparenquimatosa / Hemorragia cerebral espontânea
Hemorragia intraparenquimatosa / Hemorragia cerebral espontâneaHemorragia intraparenquimatosa / Hemorragia cerebral espontânea
Hemorragia intraparenquimatosa / Hemorragia cerebral espontânea
 
Síndromes Respiratórias - Semioliga UFMT
Síndromes Respiratórias - Semioliga UFMTSíndromes Respiratórias - Semioliga UFMT
Síndromes Respiratórias - Semioliga UFMT
 
Hipertensão pulmonar
Hipertensão pulmonarHipertensão pulmonar
Hipertensão pulmonar
 
Hipertensão Portal
Hipertensão PortalHipertensão Portal
Hipertensão Portal
 
INSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTA
INSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTAINSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTA
INSUFICIENCIA HEPÁTICA E HIPERTENSÃO PORTA
 
Icterícia 2014
Icterícia 2014Icterícia 2014
Icterícia 2014
 
Patologias da Prostata
Patologias da ProstataPatologias da Prostata
Patologias da Prostata
 
Cardiopatias congênitas cianogênicas
Cardiopatias congênitas cianogênicasCardiopatias congênitas cianogênicas
Cardiopatias congênitas cianogênicas
 
Aula aval testes diagnósticos
Aula aval testes diagnósticosAula aval testes diagnósticos
Aula aval testes diagnósticos
 
Cirrose hepática
Cirrose hepáticaCirrose hepática
Cirrose hepática
 

Semelhante a SOLID - Os cinco princípios ágeis de POO

Fazendo uma aplicação cliente/servidor (e algumas dicas...)
Fazendo uma aplicação cliente/servidor (e algumas dicas...)Fazendo uma aplicação cliente/servidor (e algumas dicas...)
Fazendo uma aplicação cliente/servidor (e algumas dicas...)Makoto Miyagawa
 
Como conectar programas em linguagem java a bases de dados
Como conectar programas em linguagem java  a bases de dadosComo conectar programas em linguagem java  a bases de dados
Como conectar programas em linguagem java a bases de dadosHenrique Fernandes
 
Integração do Flex com PHP através do AMFPHP
Integração do Flex com PHP através do AMFPHPIntegração do Flex com PHP através do AMFPHP
Integração do Flex com PHP através do AMFPHPelliando dias
 
Programação Concorrente - Aula 05
Programação Concorrente - Aula 05Programação Concorrente - Aula 05
Programação Concorrente - Aula 05thomasdacosta
 
Palestra Novidades da linguagem C# 6
Palestra Novidades da linguagem C# 6Palestra Novidades da linguagem C# 6
Palestra Novidades da linguagem C# 6Renato Haddad
 
Formulários Web em PHP com plug-ins avançados e AJAX
Formulários Web em PHP com plug-ins avançados e AJAXFormulários Web em PHP com plug-ins avançados e AJAX
Formulários Web em PHP com plug-ins avançados e AJAXManuel Lemos
 
Como escrever bons testes! - Dex transforming days
Como escrever bons testes! - Dex transforming days Como escrever bons testes! - Dex transforming days
Como escrever bons testes! - Dex transforming days Danilo Pereira De Luca
 
Enriquecendo um Modelo de Domínio Anêmico
Enriquecendo um Modelo de Domínio AnêmicoEnriquecendo um Modelo de Domínio Anêmico
Enriquecendo um Modelo de Domínio AnêmicoThoughtWorks Brasil
 
ORM - TDC Porto Alegre 2014 Trilha .NET
ORM - TDC Porto Alegre 2014 Trilha .NETORM - TDC Porto Alegre 2014 Trilha .NET
ORM - TDC Porto Alegre 2014 Trilha .NETJorge Maia
 
Desenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored ProcedureDesenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored ProcedureFernando Roberto Proença
 
Javascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOJavascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOWesley Lemos
 
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...André Ricardo Barreto de Oliveira
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Rodrigo Urubatan
 
Node.js - #6 - Core Modules - net - Rodrigo Branas
Node.js - #6 - Core Modules - net - Rodrigo BranasNode.js - #6 - Core Modules - net - Rodrigo Branas
Node.js - #6 - Core Modules - net - Rodrigo BranasRodrigo Branas
 

Semelhante a SOLID - Os cinco princípios ágeis de POO (20)

Design patterns
Design patternsDesign patterns
Design patterns
 
Fazendo uma aplicação cliente/servidor (e algumas dicas...)
Fazendo uma aplicação cliente/servidor (e algumas dicas...)Fazendo uma aplicação cliente/servidor (e algumas dicas...)
Fazendo uma aplicação cliente/servidor (e algumas dicas...)
 
Como conectar programas em linguagem java a bases de dados
Como conectar programas em linguagem java  a bases de dadosComo conectar programas em linguagem java  a bases de dados
Como conectar programas em linguagem java a bases de dados
 
Java script aula 08 - formulários
Java script   aula 08 - formuláriosJava script   aula 08 - formulários
Java script aula 08 - formulários
 
Integração do Flex com PHP através do AMFPHP
Integração do Flex com PHP através do AMFPHPIntegração do Flex com PHP através do AMFPHP
Integração do Flex com PHP através do AMFPHP
 
Programação Concorrente - Aula 05
Programação Concorrente - Aula 05Programação Concorrente - Aula 05
Programação Concorrente - Aula 05
 
Palestra Novidades da linguagem C# 6
Palestra Novidades da linguagem C# 6Palestra Novidades da linguagem C# 6
Palestra Novidades da linguagem C# 6
 
Formulários Web em PHP com plug-ins avançados e AJAX
Formulários Web em PHP com plug-ins avançados e AJAXFormulários Web em PHP com plug-ins avançados e AJAX
Formulários Web em PHP com plug-ins avançados e AJAX
 
Como escrever bons testes! - Dex transforming days
Como escrever bons testes! - Dex transforming days Como escrever bons testes! - Dex transforming days
Como escrever bons testes! - Dex transforming days
 
Enriquecendo um Modelo de Domínio Anêmico
Enriquecendo um Modelo de Domínio AnêmicoEnriquecendo um Modelo de Domínio Anêmico
Enriquecendo um Modelo de Domínio Anêmico
 
ORM - TDC Porto Alegre 2014 Trilha .NET
ORM - TDC Porto Alegre 2014 Trilha .NETORM - TDC Porto Alegre 2014 Trilha .NET
ORM - TDC Porto Alegre 2014 Trilha .NET
 
Desenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored ProcedureDesenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored Procedure
 
Javascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOJavascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POO
 
Java 16 Jdbc
Java 16 JdbcJava 16 Jdbc
Java 16 Jdbc
 
Artigoajax
ArtigoajaxArtigoajax
Artigoajax
 
Palestra PHPSP+Locaweb 2014 - PDO
Palestra PHPSP+Locaweb 2014 - PDOPalestra PHPSP+Locaweb 2014 - PDO
Palestra PHPSP+Locaweb 2014 - PDO
 
Ganhando tempo com casos de testes
Ganhando tempo com casos de testesGanhando tempo com casos de testes
Ganhando tempo com casos de testes
 
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
 
Node.js - #6 - Core Modules - net - Rodrigo Branas
Node.js - #6 - Core Modules - net - Rodrigo BranasNode.js - #6 - Core Modules - net - Rodrigo Branas
Node.js - #6 - Core Modules - net - Rodrigo Branas
 

SOLID - Os cinco princípios ágeis de POO

  • 1. Os cinco princípios ágeis de POO Autor: Ramon Valerio da Silva Desenvolvedor de Sistemas na Tecgraf PUC-RIO E-mail: ramonvalerios@gmail.com
  • 2. Os Princípios SOLID Identificados por Robert C. Martin (mais conhecido como Uncle Bob) por volta do ano 2000. ● SRP - Princípio da Responsabilidade Única ● OCP - Princípio do Aberto e Fechado ● LSP - Princípio da Substituição de Liskov ● ISP - Princípio da Segregação de Interfaces ● DIP - Princípio da Inversão de Dependência
  • 3. SOLID - Benefícios ● Fácil de se manter, adaptar e se ajustar às alterações de escopo; ● Fácil de entender e testar; ● Construído para ter alterações com o menor esforço possível; ● Possibilidade de ser reaproveitado; ● Maior tempo possível em produção;
  • 4. SOLID - Possíveis problemas evitados ● Dificuldade na testabilidade / Criação de testes de unidade; ● Código espaguete, sem estrutura ou padrão; ● Dificuldades de isolar funcionalidades; ● Duplicação de código, uma alteração precisa ser feita em N pontos; ● Fragilidade, o código quebra facilmente em vários pontos após alguma mudança.
  • 5. SOLID - SRP(Single Responsability Principle) “O SRP é o primeiro e mais importante, e se não respeitá-lo, provavelmente vai comprometer o resto dos princípios.” “Uma classe deve ter um, e apenas um, motivo para ser modificada”. ● Um arquivo de classe, deve ter apenas uma classe. ● Um método deve ter apenas uma responsabilidade. ● Um evento deve ter apenas uma responsabilidade.
  • 6. SRP - Estrutura da violação “Esta classe está assumindo muitas responsabilidades e violando os princípios do SRP.”
  • 7. SRP - Quantas violações esta classe possui? public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get;set;} public string Incluir() { if (!Email.Contains("@")) return "Cliente com e-mail inválido"; if (CPF.Length != 11) return "Cliente com CPF inválido"; using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))"; cmd.Parameters.AddWithValue("nome", Nome); cmd.Parameters.AddWithValue("email", Email); cmd.Parameters.AddWithValue("cpf", CPF); cmd.Parameters.AddWithValue("dataCad", DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); } var mail = new MailMessage("tecgraf@tecgraf.com", Email); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = "Bem-vindo."; mail.Body = "Parabéns! Você está casastrado."; client.Send(mail); return "Cliente cadastrado com sucesso!"; }
  • 8. SRP - Violações public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get;set;} public string Incluir() { if (!Email.Contains("@")) return "Cliente com e-mail inválido"; if (CPF.Length != 11) return "Cliente com CPF inválido"; using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))"; cmd.Parameters.AddWithValue("nome", Nome); cmd.Parameters.AddWithValue("email", Email); cmd.Parameters.AddWithValue("cpf", CPF); cmd.Parameters.AddWithValue("dataCad", DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); } var mail = new MailMessage("tecgraf@tecgraf.com", Email); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = "Bem-vindo."; mail.Body = "Parabéns! Você está casastrado."; client.Send(mail); return "Cliente cadastrado com sucesso!"; }
  • 9. SRP - Violações public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get;set;} public string Incluir() { if (!Email.Contains("@")) return "Cliente com e-mail inválido"; if (CPF.Length != 11) return "Cliente com CPF inválido"; using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))"; cmd.Parameters.AddWithValue("nome", Nome); cmd.Parameters.AddWithValue("email", Email); cmd.Parameters.AddWithValue("cpf", CPF); cmd.Parameters.AddWithValue("dataCad", DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); } var mail = new MailMessage("tecgraf@tecgraf.com", Email); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = "Bem-vindo."; mail.Body = "Parabéns! Você está casastrado."; client.Send(mail); return "Cliente cadastrado com sucesso!"; }
  • 10. SRP - Violações public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get;set;} public string Incluir() { if (!Email.Contains("@")) return "Cliente com e-mail inválido"; if (CPF.Length != 11) return "Cliente com CPF inválido"; using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))"; cmd.Parameters.AddWithValue("nome", Nome); cmd.Parameters.AddWithValue("email", Email); cmd.Parameters.AddWithValue("cpf", CPF); cmd.Parameters.AddWithValue("dataCad", DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); } var mail = new MailMessage("tecgraf@tecgraf.com", Email); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = "Bem-vindo."; mail.Body = "Parabéns! Você está casastrado."; client.Send(mail); return "Cliente cadastrado com sucesso!"; }
  • 11. SRP - Violações public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get;set;} public string Incluir() { if (!Email.Contains("@")) return "Cliente com e-mail inválido"; if (CPF.Length != 11) return "Cliente com CPF inválido"; using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))"; cmd.Parameters.AddWithValue("nome", Nome); cmd.Parameters.AddWithValue("email", Email); cmd.Parameters.AddWithValue("cpf", CPF); cmd.Parameters.AddWithValue("dataCad", DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); } var mail = new MailMessage("tecgraf@tecgraf.com", Email); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = "Bem-vindo."; mail.Body = "Parabéns! Você está casastrado."; client.Send(mail); return "Cliente cadastrado com sucesso!"; }
  • 12. SRP - Estrutura da solução “Estas classes possuem apenas um motivo para serem alteradas, assumindo uma única responsabilidade, e respeitando o SRP.”
  • 13. SRP - Soluções public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get; set; } public bool IsValid() { return EmailServices.IsValid(Email) && CPFServices.IsValid(CPF); } }
  • 14. SRP - Soluções public class ClienteRepository { public void Incluir(Cliente cliente) { using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandText = "INSERT INTO CLIENTE (NOME, EMAIL CPF, DATACADASTRO) VALUES (@nome, @email, @cpf, @dataCad))"; cmd.Parameters.AddWithValue("nome", cliente.Nome); cmd.Parameters.AddWithValue("email", cliente.Email); cmd.Parameters.AddWithValue("cpf", cliente.CPF); cmd.Parameters.AddWithValue("dataCad", cliente.DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); }
  • 15. SRP - Soluções public class ClienteService { public string Incluir(Cliente cliente) { if (!cliente.IsValid()) return "Dados inválidos"; var repositorio = new ClienteRepository(); repositorio.Incluir(cliente); EmailServices.Enviar("tecgraf@tecgraf.com", cliente.Email, "Bem-vindo", "Parabéns está Cadastrado"); return "Cliente cadastrado com sucesso"; } }
  • 16. SRP - Soluções public static class EmailServices { public static bool IsValid(string email) { return email.Contains("@"); } public static void Enviar(string de, string para, string assunto, string mensagem) { var mail = new MailMessage(de, para); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = assunto; mail.Body = mensagem; client.Send(mail); } }
  • 17. SRP - Soluções public static class CPFServices { public static bool IsValid(string cpf) { return cpf.Length == 11; } }
  • 18. SOLID - OCP(Open Closed Principle) “Você deve ser capaz de estender um comportamento de uma classe, sem modificá-la.” “Entidades de softwares (classes, módulos, funções, etc) devem estar abertas para extensão, mas fechadas para modificação.”
  • 19. OCP - Estrutura da violação “A classe DebitoConta está assumindo muitas responsabilidades e violando os princípios do SRP.”
  • 20. OCP - Onde estão as violações desta classe? public class DebitoConta { public void Debitar(decimal valor, string conta, TipoConta tipoConta) { if (tipoConta == TipoConta.Corrente) { // Debita Conta Corrente } if (tipoConta == TipoConta.Poupanca) { // Valida Aniversário da Conta // Debita Conta Poupança } } } public enum TipoConta { Corrente, Poupanca }
  • 21. OCP - Violações public class DebitoConta { public void Debitar(decimal valor, string conta, TipoConta tipoConta) { if (tipoConta == TipoConta.Corrente) { // Debita Conta Corrente } if (tipoConta == TipoConta.Poupanca) { // Valida Aniversário da Conta // Debita Conta Poupança } } } public enum TipoConta { Corrente, Poupanca }
  • 22. OCP - Estrutura da solução “Estas classes estão assumindo uma única responsabilidade.”
  • 23. OCP - Soluções public abstract class DebitoConta { public string NumeroTransacao { get; set; } public abstract string Debitar(decimal valor, string conta); }
  • 24. OCP - Soluções public class DebitoContaCorrente : DebitoConta { public override string Debitar(decimal valor, string conta) { // Debita Conta Corrente return NumeroTransacao; } }
  • 25. OCP - Soluções public class DebitoContaPoupanca : DebitoConta { public override string Debitar(decimal valor, string conta) { // Valida Aniversário da Conta // Debita Conta Poupança return NumeroTransacao; } }
  • 26. OCP - Soluções public class DebitoContaInvestimento : DebitoConta { public override string Debitar(decimal valor, string conta) { // Debita Conta Investimento // Isentar Taxas return NumeroTransacao; } }
  • 27. SOLID - LSP(Liskov Substitution Principle) “Uma classe base deve poder ser substituída pela sua classe derivada.” “Se nada como um pato, voa como um pato, porém precisa de baterias, provavelmente você possui um problema de abstração.” “As classes derivadas devem ser substituíveis por suas classes base.”
  • 28. LSP - Estrutura da Violação
  • 29. LSP - Violações public class Ave { public virtual void Voar() { Console.WriteLine("Voando"); } }
  • 30. LSP - Violações public class Aguia: Ave { public override void Voar() { base.Voar(); Console.WriteLine("Voar sempre alto..."); } }
  • 31. LSP - Violações public class Pato: Ave { public override void Voar() { base.Voar(); Console.WriteLine("Voar sempre baixo..."); } }
  • 32. LSP - Violações public class Avestruz : Ave { public override void Voar() { Console.WriteLine("Ops... eu não posso voar!!"); } }
  • 33. LSP - Violações public class Program { static void Main() { var aves = new List<Ave>(); aves.Add(new Aguia()); aves.Add(new Pato()); aves.Add(new Avestruz()); foreach (Ave ave in aves) { ave.Voar(); } } }
  • 34. LSP - Estrutura da Solução
  • 35. LSP - Violações public class Retangulo { protected virtual double Altura { get; set; } protected virtual double Largura { get; set; } public double GetArea() { return Altura * Largura; } }
  • 36. LSP - Violações public class Quadrado : Retangulo { public override double Altura { set { base.Altura = base.Largura = value; } } public override double Largura { set { base.Altura = base.Largura = value; } } }
  • 37. LSP - Violações public class Program { private static void ObterAreaRetangulo(Retangulo retangulo) { Console.WriteLine("Calculo da área do Retangulo"); Console.WriteLine(retangulo.Altura + " x " + retangulo.Largura); Console.WriteLine(“Resultado: ” + retangulo.GetArea()); Console.ReadKey(); } private static void Main() { var quadrado = new Quadrado(){ Altura = 10, Largura = 5}; ObterAreaRetangulo(quadrado); } } Calculo da área do Retangulo 5 x 5 Resultado: 25
  • 38. SOLID - ISP(Interface Segregation Principle) “Classes não devem ser forçadas a depender de métodos que não usam.” “Muitas interfaces específicas são melhores do que uma única interface.”
  • 39. ISP - Violações public interface IFormCadastro { void Validar(); void Salvar(); void EnviarEmail(); }
  • 40. ISP - Violações public class FormCadastroCliente : IFormCadastro { public void Validar() { // Validar CPF, Email } public void Salvar() { // Insert na tabela Cliente } public void EnviarEmail() { // Enviar e-mail para o cliente } }
  • 41. ISP - Violações public class FormCadastroProduto : IFormCadastro { public void Validar() { // Validar valor } public void Salvar() { // Insert tabela Produto } public void EnviarEmail() { // Produto não tem e-mail, o que eu faço agora??? } }
  • 42. ISP - Soluções public interface IFormCadastroCliente { void Validar(); void Salvar(); void Enviar(); } public interface IFormCadastroProduto { void Validar(); void Salvar(); }
  • 43. ISP - Soluções public class CadastroCliente : ICadastroCliente { public void Validar() { // Validar CPF, Email } public void Salvar() { // Insert na tabela Cliente } public void EnviarEmail() { // Enviar e-mail para o cliente } } public class CadastroProduto : ICadastroProduto { public void Validar() { // Validar valor } public void Salvar() { // Insert tabela Produto } }
  • 44. SOLID - DIP(Dependency Inversion Principle) “Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações;” “Abstrações não devem depender de detalhes; Detalhes devem depender de abstrações.”
  • 45. DIP - Estrutura da violação “Estas classes não contém interfaces para padronizar seus métodos e também não possui o recurso da abstração das interfaces, deixando a estrutura fortemente acoplada, ou seja, com muitas dependências, violando os princípios do DIP.”
  • 46. DIP - Violações public class Cliente { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get; set; } public bool IsValid() { return EmailServices.IsValid(Email) && CPFServices.IsValid(CPF); } } “FORTE ACOPLAMENTO!”
  • 47. DIP - Violações public class ClienteService { public string Incluir(Cliente cliente) { if (!cliente.IsValid()) return "Dados inválidos"; var repositorio = new ClienteRepository(); repositorio.Incluir(cliente); EmailServices.Enviar("tecgraf@tecgraf.com", cliente.Email, "Bem-vindo", "Parabéns está Cadastrado"); return "Cliente cadastrado com sucesso"; } } “FORTE ACOPLAMENTO!”
  • 48. DIP - Violações public static class CPFServices { public static bool IsValid(string cpf) { return cpf.Length == 11; } }
  • 49. DIP - Violações public static class EmailServices { public static bool IsValid(string email) { return email.Contains("@"); } public static void Enviar(string de, string para, string assunto, string mensagem) { var mail = new MailMessage(de, para); var client = new SmtpClient { Port = 25, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Host = "smtp.google.com" }; mail.Subject = assunto; mail.Body = mensagem; client.Send(mail); } }
  • 50. DIP - Violações public class ClienteRepository { public void Incluir(Cliente cliente) { using (var conexao = new OracleConnection()) { conexao.ConnectionString = "MinhaConnectionString"; var cmd = new OracleCommand(conexao); cmd.CommandText = "INSERT INTO CLIENTE(NOME, EMAIL CPF, DATACADASTRO) VALUES(@nome, @email, @cpf, @dataCad)"; cmd.Parameters.AddWithValue("nome", cliente.Nome); cmd.Parameters.AddWithValue("email", cliente.Email); cmd.Parameters.AddWithValue("cpf", cliente.CPF); cmd.Parameters.AddWithValue("dataCad", cliente.DataCadastro); conexao.Open(); cmd.ExecuteNonQuery(); conexao.Close(); } } }
  • 51. DIP - Estrutura da solução IClienteRepository IClienteService IEmailService ICPFService “Agora eu posso usar as interfaces como abstrações das classes que o implementam, deixando a estrutura com baixo acoplamento, ou seja sem dependência.”
  • 52. DIP - Soluções public class Cliente { private readonly ICPFServices _cpfServices; private readonly IEmailServices _emailServices; public Cliente(ICPFServices cpfServices, IEmailServices emailServices) { _cpfServices = cpfServices; _emailServices = emailServices; } public int ClienteId { get; set; } public string Nome { get; set; } public string Email { get; set; } public string CPF { get; set; } public DateTime DataCadastro { get; set; } public bool IsValid(){ return _emailServices.IsValid(Email) && _cpfServices.IsValid(CPF); } }
  • 53. DIP - Soluções public class ClienteService : IClienteServices { private readonly IClienteRepository _clienteRepository; private readonly IEmailServices _emailServices; public ClienteServices(IClienteRepository clienteRepository, IEmailServices emailServices) { _clienteRepository = clienteRepository; _emailServices = emailServices; } public string Incluir(Cliente cliente) { if (!cliente.IsValid()) return "Dados inválidos"; _clienteRepository.Incluir(cliente); _emailServices.Enviar("tecgraf@tecgraf.com", cliente.Email, "Bem-vindo", "Parabéns está Cadastrado"); return "Cliente cadastrado com sucesso"; } }
  • 54. DIP - Exemplo de um Container de DI private static void RegisterServices(IKernel kernel) { //Service kernel.Bind<IClienteService>().To<ClienteService>(); kernel.Bind<ICPFService>().To<CPFService>(); kernel.Bind<IEmailService>().To<EmailService>(); //Repository kernel.Bind<IClienteRepository>().To<ClienteRepository>(); }
  • 55. “Um homem sábio pode aprender mais com uma pergunta tola do que um tolo pode aprender a partir de uma resposta sensata.” 1 - Quais os benefícios em usar o SRP? 2 - Por que usar OCP se eu posso colocar mais um if ou criar enums e flags que resolve muito mais rápido? 3 - O que viola o LSP? 4 - No ISP usar muitas interfaces específicas é bom ou ruim, e porque? 5 - Quais são as vantagens do DIP? Quais princípios eu devo respeitar para aplicar o DIP? 6 - Quais são os benefícios de um software usando princípios SOLID?
  • 57. Obrigado a todos pela participação!

Notas do Editor

  1. https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
  2. https://pt.wikipedia.org/wiki/Barbara_Liskov
  3. https://en.wikipedia.org/wiki/Interface_segregation_principle
  4. Contato para dúvidas: rvalerio@tecgraf.puc-rio.com