none
Porque programar para Interfaces e não para uma implementação ? RRS feed

  • Pergunta

  • Olaa,

                   Estava pesquisando sobre Interfaces e me deparei com a seguinte afirmação: " Programe para uma interface e não para uma implementação ". Diante do que foi afirmado segue abaixo algumas dúvidas:

    1) Porque programar para uma Interface, e não para uma implementação 

    2) Quais os problemas de se programar para uma implementação ?

    3) Qual a relação da respectiva afirmação com o conceito de Polimorfismo ? Existe relação entre ambos ?

    4) Porque programar para interface favorece trabalhar com Abstrações

    5) Ao programar para uma interface, todas as minhas Classes Concretas terão que implementar uma interface ? Ou seja, se eu possuir um sistema de 03 Camadas e minha Camada de Negocio possuir 30 Classes, todas essas classes terão que ter e implementar Interfaces, e se minha Camada DAL possuir 10 Classes, todas essas classes terão que implementar Interfaces ?

    4) Relacionado a Questão 03. Qual o critério para determinação de que uma classe irá precisar ou não de interface ?

    Desde Já, Agradeço.

    quarta-feira, 9 de maio de 2012 03:03

Respostas

  • Rodrigo, bom dia

    a resposta para sua pergunta é bem simples, gerar baixo acoplamento entre as classes e com isto tornar seu código mais fléxivel as mudanças.

    Não é que exista um problema em se programar para uma implementação, mas você está deixando seu código mais "amarrado", menos reutilizável e com maior possiblidade de falhas.

    A implementação e utilização de polimorfismo, "O polimorfismo é caracterizado quando duas ou mais classes distintas tem métodos de mesmo nome, de forma que uma função possa utilizar um objeto de qualquer uma das classes polimórficas, sem necessidade de tratar de forma diferenciada conforme a classe do objeto", é básicamente implementada através de classes abstratas ou interfaces, por exemplo:

    public interface ICalculadora
        {
            int Soma(int x, int y);
            int Subtracao(int x, int y);
            int Multiplicacao(int x, int y);
            double Divisao(int x, int y);
        }
    
        public interface ICalculadoraCientifica
        {
            public double Potenciação(int x, int y);
        }
    
        public class Calculadora : ICalculadora
        {
    
            public int Soma(int x, int y)
            {
                return x + y;
            }
    
            public int Subtracao(int x, int y)
            {
                return x - y;
            }
    
            public int Multiplicacao(int x, int y)
            {
                return x * y;
            }
    
            public double Divisao(int x, int y)
            {
                return x / y;
            }
        }
    
        public class CalculadoraCientifica : ICalculadora, ICalculadoraCientifica
        {
    
            public int Soma(int x, int y)
            {
                return x + y;
            }
    
            public int Subtracao(int x, int y)
            {
                return x - y;
            }
    
            public int Multiplicacao(int x, int y)
            {
                return x * y;
            }
    
            public double Divisao(int x, int y)
            {
                return x / y;
            }
    
            public double Potenciação(int x, int y)
            {
                return Math.Pow(x, y);
            }
        }


    Assim, poderei utilizar minhas classes para a implementação:

                ICalculadora calc = new Calculadora();
                int x = calc.Soma(2000, 3000);
                
                calc = new CalculadoraCientifica();
                int y = calc.Soma(2300, 300);

    a resposta paras as últimas questões é depende. tudo irá depender de como você quer que seu código de se comporte. Veja que classes utilitárias que tem um comportamento muito particular por exemplo, não tem necessidade de implementar uma interface. Tudo aquilo que você vê que poderá re-utilziar de alguma forma, seria bom implementar uma interface ou até mesmo uma classe abstrata, a utilização dos conceitos da orientação a objeto no código é que irá deixar sua aplicação robusta e simples ao mesmo tempo.

    uma coisa interessante que é possivel fazer com implementação à interfaces é a injeção de dependência

    http://pt.wikipedia.org/wiki/Inje%C3%A7%C3%A3o_de_depend%C3%AAncia

    http://www.ninject.org/

    http://msdn.microsoft.com/en-us/library/aa973811.aspx

    espero ter ajudado um pouco.


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Twitter @Olavooneto
    Facebook Olavo Neto
    Linkedin Olavo Neto
    Se for útil marque como resposta e faça um Developer feliz :)

    • Sugerido como Resposta EduardoPiresMVP quarta-feira, 9 de maio de 2012 16:35
    • Não Sugerido como Resposta _dev quarta-feira, 9 de maio de 2012 17:58
    • Sugerido como Resposta Rene Felix quinta-feira, 10 de maio de 2012 00:22
    • Marcado como Resposta _dev quinta-feira, 10 de maio de 2012 14:19
    quarta-feira, 9 de maio de 2012 12:03
    Moderador
  • Boa tarde,

    Vou tentar responder as suas perguntas em ordem e a sugestão do Oliveira e em seguida fazer uma conclusão breve.

    1) Porque programar para uma Interface, e não para uma implementação ? 
    R: Primeiro não se programa para uma Interface, você implementa interface em uma dada Classe. Eu gosto bastante de jogos e acho que fica facil de entender mas você pode abstrair para windows forms por exemplo. 

    Se você fosse fazer uma arquitetura que renderizar um Classe independente o que fosse essa classe. Exemplo botões, Textbox, labels etc...

    Um modo MUITO facil seria cria uma interface IDrawable que você obriga-se a classe a implementar para chamar o metodo Render() por exemplo, neste método cada componente se desenharia o botão pareceria um botão, o Label um label assim por diante.

    E na Arquitetura você executaria mais ou menos assim


    List<IDrawable> ListaDrawable = //recebe de algum lugar. Foreach(var componente in ListaDrawable){ componenete.Render(); //desenha o componente }

    2) Quais os problemas de se programar para uma implementação ?

    Nenhum problema você só não consegue Abstrair por exemplo, é bem mais fácil criar uma tela de busca genérica que recebe uma Interface e executa o método da classe passada para a Busca.

    3) Qual a relação da respectiva afirmação com o conceito de Polimorfismo ? Existe relação entre ambos ?

    Novamente nenhum problema em programar para a implementação do que programar para Polimorfismo, por exemplo, Com polimorfismo você poderia estar programando um sistema de venda de classificados, por exemplo, você poderia ter uma classe Pai chamada Anuncio e duas filhas chamadas AnuncioImovel e AnuncioCarro. Utilizando polimorfismos algumas ações no controle destes 3 se tornaria infinitamente mais fácil do que implementar 3 vezes uma para Anuncio Imovel outra para Anuncio de Carro e uma genérica

    4) Porque programar para interface favorece trabalhar com Abstrações ? 

    Continuando minha arquitetura na resposta 1 para desenhar componentes na tela. Pouco importanta quem é o componente que será desenhado você obrigaria ele a implementar por exemplo posição X, Y, largura altura e o método Render().

    5) Ao programar para uma interface, todas as minhas Classes Concretas terão que implementar uma interface ? Ou seja, se eu possuir um sistema de 03 Camadas e minha Camada de Negocio possuir 30 Classes, todas essas classes terão que ter e implementar Interfaces, e se minha Camada DAL possuir 10 Classes, todas essas classes terão que implementar Interfaces ?

    Não, você só usará uma interface na classe que você quiser, OU, se o seu método receber uma interface será necessário que a classe que vocÊ passe para o método implementa a interface.
    Voltando no exemplo de desnehar a tela

    //O componente passado para o método DEVE implementar a classe IDrawable
    void DesenhaNovoComponente(IDrawable componente){
      componente.Render();
    }

    4) Relacionado a Questão 03. Qual o critério para determinação de que uma classe irá precisar ou não de interface ?

    Depende totalmente da sua arquitetura eu coloco Interfaces em momentos que preciso garantir uma implementação ou em partes genéricas como desenhar componentes.

    Em relação a Injeção de Dependencia, é bem mais complicado vou tentar resumir quando você utiliza injeção de dependencia você geralmente utiliza interface para TUDO. Portanto você cria a classe e já cria seus métodos não é tão abstrato pois você já está pensando na classe daquela interface o contrário do meu caso de desenhar componente independendo do componente por exemplo


    • Marcado como Resposta _dev quinta-feira, 10 de maio de 2012 14:19
    quarta-feira, 9 de maio de 2012 19:44

Todas as Respostas

  • Rodrigo, bom dia

    a resposta para sua pergunta é bem simples, gerar baixo acoplamento entre as classes e com isto tornar seu código mais fléxivel as mudanças.

    Não é que exista um problema em se programar para uma implementação, mas você está deixando seu código mais "amarrado", menos reutilizável e com maior possiblidade de falhas.

    A implementação e utilização de polimorfismo, "O polimorfismo é caracterizado quando duas ou mais classes distintas tem métodos de mesmo nome, de forma que uma função possa utilizar um objeto de qualquer uma das classes polimórficas, sem necessidade de tratar de forma diferenciada conforme a classe do objeto", é básicamente implementada através de classes abstratas ou interfaces, por exemplo:

    public interface ICalculadora
        {
            int Soma(int x, int y);
            int Subtracao(int x, int y);
            int Multiplicacao(int x, int y);
            double Divisao(int x, int y);
        }
    
        public interface ICalculadoraCientifica
        {
            public double Potenciação(int x, int y);
        }
    
        public class Calculadora : ICalculadora
        {
    
            public int Soma(int x, int y)
            {
                return x + y;
            }
    
            public int Subtracao(int x, int y)
            {
                return x - y;
            }
    
            public int Multiplicacao(int x, int y)
            {
                return x * y;
            }
    
            public double Divisao(int x, int y)
            {
                return x / y;
            }
        }
    
        public class CalculadoraCientifica : ICalculadora, ICalculadoraCientifica
        {
    
            public int Soma(int x, int y)
            {
                return x + y;
            }
    
            public int Subtracao(int x, int y)
            {
                return x - y;
            }
    
            public int Multiplicacao(int x, int y)
            {
                return x * y;
            }
    
            public double Divisao(int x, int y)
            {
                return x / y;
            }
    
            public double Potenciação(int x, int y)
            {
                return Math.Pow(x, y);
            }
        }


    Assim, poderei utilizar minhas classes para a implementação:

                ICalculadora calc = new Calculadora();
                int x = calc.Soma(2000, 3000);
                
                calc = new CalculadoraCientifica();
                int y = calc.Soma(2300, 300);

    a resposta paras as últimas questões é depende. tudo irá depender de como você quer que seu código de se comporte. Veja que classes utilitárias que tem um comportamento muito particular por exemplo, não tem necessidade de implementar uma interface. Tudo aquilo que você vê que poderá re-utilziar de alguma forma, seria bom implementar uma interface ou até mesmo uma classe abstrata, a utilização dos conceitos da orientação a objeto no código é que irá deixar sua aplicação robusta e simples ao mesmo tempo.

    uma coisa interessante que é possivel fazer com implementação à interfaces é a injeção de dependência

    http://pt.wikipedia.org/wiki/Inje%C3%A7%C3%A3o_de_depend%C3%AAncia

    http://www.ninject.org/

    http://msdn.microsoft.com/en-us/library/aa973811.aspx

    espero ter ajudado um pouco.


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Twitter @Olavooneto
    Facebook Olavo Neto
    Linkedin Olavo Neto
    Se for útil marque como resposta e faça um Developer feliz :)

    • Sugerido como Resposta EduardoPiresMVP quarta-feira, 9 de maio de 2012 16:35
    • Não Sugerido como Resposta _dev quarta-feira, 9 de maio de 2012 17:58
    • Sugerido como Resposta Rene Felix quinta-feira, 10 de maio de 2012 00:22
    • Marcado como Resposta _dev quinta-feira, 10 de maio de 2012 14:19
    quarta-feira, 9 de maio de 2012 12:03
    Moderador
  • Prezado Oliveira Neto,

                                      Muito obrigado pela atenção, você me ajudou muito, não só dessa vez mas muitas outras. Mas tenho somente uma última dúvida, isso realmente não ficou claro para mim, Estava lendo um artigo de Vinicius Quaiato sobre Injeção de Depêndencia no qual ele afirma:

    "Quando uma classe possui dependência de alguma outra classe concreta, devemos então criar uma dependência para uma interface, ou seja, uma abstração.Com nossa classe dependendo de uma abstração, nós injetamos um objeto concreto nela. "

    http://viniciusquaiato.com/blog/injecao-de-dependencia/

    Porque ao criarmos uma dependência para uma Interface, estamos criando dependência para uma Abstração ? Qual a relação entre Interface e Abstração levando em consideração o que foi citado acima ?

    Novamente Obrigado.

    Um Grande Abraço.

    quarta-feira, 9 de maio de 2012 17:58
  • Boa tarde,

    Vou tentar responder as suas perguntas em ordem e a sugestão do Oliveira e em seguida fazer uma conclusão breve.

    1) Porque programar para uma Interface, e não para uma implementação ? 
    R: Primeiro não se programa para uma Interface, você implementa interface em uma dada Classe. Eu gosto bastante de jogos e acho que fica facil de entender mas você pode abstrair para windows forms por exemplo. 

    Se você fosse fazer uma arquitetura que renderizar um Classe independente o que fosse essa classe. Exemplo botões, Textbox, labels etc...

    Um modo MUITO facil seria cria uma interface IDrawable que você obriga-se a classe a implementar para chamar o metodo Render() por exemplo, neste método cada componente se desenharia o botão pareceria um botão, o Label um label assim por diante.

    E na Arquitetura você executaria mais ou menos assim


    List<IDrawable> ListaDrawable = //recebe de algum lugar. Foreach(var componente in ListaDrawable){ componenete.Render(); //desenha o componente }

    2) Quais os problemas de se programar para uma implementação ?

    Nenhum problema você só não consegue Abstrair por exemplo, é bem mais fácil criar uma tela de busca genérica que recebe uma Interface e executa o método da classe passada para a Busca.

    3) Qual a relação da respectiva afirmação com o conceito de Polimorfismo ? Existe relação entre ambos ?

    Novamente nenhum problema em programar para a implementação do que programar para Polimorfismo, por exemplo, Com polimorfismo você poderia estar programando um sistema de venda de classificados, por exemplo, você poderia ter uma classe Pai chamada Anuncio e duas filhas chamadas AnuncioImovel e AnuncioCarro. Utilizando polimorfismos algumas ações no controle destes 3 se tornaria infinitamente mais fácil do que implementar 3 vezes uma para Anuncio Imovel outra para Anuncio de Carro e uma genérica

    4) Porque programar para interface favorece trabalhar com Abstrações ? 

    Continuando minha arquitetura na resposta 1 para desenhar componentes na tela. Pouco importanta quem é o componente que será desenhado você obrigaria ele a implementar por exemplo posição X, Y, largura altura e o método Render().

    5) Ao programar para uma interface, todas as minhas Classes Concretas terão que implementar uma interface ? Ou seja, se eu possuir um sistema de 03 Camadas e minha Camada de Negocio possuir 30 Classes, todas essas classes terão que ter e implementar Interfaces, e se minha Camada DAL possuir 10 Classes, todas essas classes terão que implementar Interfaces ?

    Não, você só usará uma interface na classe que você quiser, OU, se o seu método receber uma interface será necessário que a classe que vocÊ passe para o método implementa a interface.
    Voltando no exemplo de desnehar a tela

    //O componente passado para o método DEVE implementar a classe IDrawable
    void DesenhaNovoComponente(IDrawable componente){
      componente.Render();
    }

    4) Relacionado a Questão 03. Qual o critério para determinação de que uma classe irá precisar ou não de interface ?

    Depende totalmente da sua arquitetura eu coloco Interfaces em momentos que preciso garantir uma implementação ou em partes genéricas como desenhar componentes.

    Em relação a Injeção de Dependencia, é bem mais complicado vou tentar resumir quando você utiliza injeção de dependencia você geralmente utiliza interface para TUDO. Portanto você cria a classe e já cria seus métodos não é tão abstrato pois você já está pensando na classe daquela interface o contrário do meu caso de desenhar componente independendo do componente por exemplo


    • Marcado como Resposta _dev quinta-feira, 10 de maio de 2012 14:19
    quarta-feira, 9 de maio de 2012 19:44
  • Muito Obrigado a todos pela atenção e paciência, minha dúvida foi sanada.

    Grande Abraço.

    Boa Semana.

    quinta-feira, 10 de maio de 2012 14:20
  • @rodrigo_dev

    Interface e um tipo de contrato que voce faz com o resto do programa. Todo o teu programa tem de seguir e obedecer este contrato e as regras que voce coloa na interface.

    se voce na interface declaraste um valor int, entao cquando usar este valor tem sempre de ser int, nao pode ser alterdao, se for alterado gera erro.

    Como o Olavo disse fica facil de detectar o erro e melhor organizacao e reutilizacao. 

    Programa-se muito com interface em teams ou equipas de programadores.


    O Amor que Sinto por Ti, Apenas Deus e capaz de sentir e superar tal amor!

    quinta-feira, 10 de maio de 2012 21:09