balta.io balta.io
  • Cursos
  • Carreiras
  • Para sua Empresa
  • Agenda
  • Blog

Seja Premium
balta.io

  • Cursos
  • Carreiras
  • Para sua Empresa
  • Agenda
  • Blog
  • Player
Seja Premium

Entre ou Cadastre-se

  • Home
  • Artigos
  • Orientação a objetos: Abstração


Orientação a objetos: Abstração

Abstração é um dos conceitos mais importantes do paradigma orientado a objetos e também um de seus pilares.

Neste artigo vamos entender um pouco mais sobre abtrações no geral e como este conceito se aplica na orientação a objetos.

Abstração

O conceito de abstração consiste em esconder os detalhes de algo, no caso, os detalhes desnecessários.

No mundo real, utilizamos abstrações o tempo todo. Tudo que não sabemos como funciona por baixo dos panos pode ser considerado uma abstração.

Para exemplificar melhor, vamos tomar como exemplo a concessionária que realiza manutenções no seu carro. Você leva ele até lá com um problema e ele volta funcionando.

Em suma, pouco importa os detalhes do que aconteceu durante a manutenção do seu carro, o que importa é que ele voltou funcionando.

Abstração na orientação a objetos

Dentro da OOP (Object Oriented Programming -- Programação Orientada a Objetos) temos diversos conceitos de abtração, como por exemplo as interfaces e classes que escondam algo.

Abstração na forma simples

Para começarmos com um exemplo mais simples, vamos tomar como base o seguinte código:

public class Order 
{
    ...
    public decimal Total { get; set; }
    public void CalculateTotal() {...}
    public void AddItem(Item item)
    {
        Items.Add(item);
        CalculateTotal();
    }
    ...
}

Neste exemplo temos uma classe Order que representa um pedido, e dentro dela temos uma propridade chamada Total que define o valor total do pedido, e dois métodos, CalculateTotal e AddItem.

Listas → Para saber mais sobre listas, confira a aula "Listas" do curso Fundamentos da Orientação a Objetos.

Quanto mais contato sua classe tem com o mundo externo, maiores são os impactos das mudanças quando algo for alterado nela.

Por exemplo, se esta classe estiver sendo utilizada em 20 outros lugares diferentes e você alterar a propriedade Total para Amount, geraria um grande refatoramento.

Embora em alguns cenários isto aconteça e seja necessário, quanto mais detalhes pudermos esconder sobre nossas classes, melhor.

Olhando novamente para o código, você identifica algo que poderia mudar?

public class Order 
{
    ...
    public decimal Total { get; set; }
    public void CalculateTotal() {...}
    public void AddItem(Item item)
    {
        Items.Add(item);
        CalculateTotal();
    }
    ...
}

Se notarmos, o cálculo de total está sendo executado a cada item adicionado. E se pararmos para pensar melhor, não faz sentido alguém de fora acionar o método que calcula este pedido.

O pedido por si só, deve saber se gerenciar e com a chamada ao CalculateTotal já sendo feita no método Add, podemos simplesmente marca-lo como privado.

public class Order 
{
    ...
    public decimal Total { get; set; }
    private void CalculateTotal() {...}
    public void AddItem(Item item)
    {
        Items.Add(item);
        CalculateTotal();
    }
    ...
}

Desta forma, privamos o acesso externo utilizando o modificador de acesso private, tornan o método CalculateTotal inacessível externamente.

Modificadores de acesso: Todos os modificadores de acesso com exemplos práticos estão no curso Fundamentos da Orientação a Objetos.

Abstração por interfaces

As interfaces funcionam como contratos (Módulo 1 - Aula 17 - Fundamentos da Orientação a Objetos) que definem o que as implementações (Classes) devem conter.

Em suma as interfaces dizem "O que" e não "Como", sendo assim, podemos tomar o "Como" como os detalhes e o "O que" como uma abstração.

public interface ICustomerRepository
{
    void Save(Customer customer);
}

Tomando como base a interface acima, tomamos ela como um contrato que diz que um Customer pode ser salvo, mas ela não diz como isto deve ser feito.

Este conceito de abstração por interfaces nos leva ao princípio DIP (Veja mais sobre DI aqui) que prega o seguinte:

Sempre que puder, dependa de abstrações ao invés de implementaçõs.

Este simples processo resulta na possibilidade de criação de várias implementações de um mesmo contrato.

Vamos tomar como base esta primeira implementação, que seria uma versão do contrato que está direcionada ao uso do Entity Framework.

public class CustomerRepository : ICustomerRepository
{
    public void Save(Customer customer)
    {
        _context.Customers.Add(customer);
        _context.SaveChanges();
    }
}

Porém, durante os testes de unidade, não podemos depender de dados externos, logo precisamos simular nosso repositório.

Sendo assim, podemos gerar uma outra implementação, baseada no contrato ICustomerRepository que vai enganar nossos testes.

public class FakeCustomerRepository : ICustomerRepository
{
    public void Save(Customer customer)
    {
    }
}

Pronto, neste momento temos duas implementações (CustomerRepository e FakeCustomerRepository) se baseando no contrato ICustomerRepository.

Aplicando a abstração na prática

Agora vamos para um cenário maior, vamos olhar para o objeto OrderHandler que manipula os pedidos.

Este objeto precisa se comunicar com a base de clientes para salvar os dados lá, porém, durante os testes, não teremos uma base para salvar.

Desta forma, nossos testes falhariam, ou teríamos que sempre preparar uma massa de testes (Que em diversas vezes toma tempo) para realizar esta execução.

A saída aqui é Mockar, ou seja, simular que fomos no banco de dados e algo aconteceu. Então, teremos as versões do CustomerRepository e FakeCustomerRepository sendo utilizadas.

Testes de unidade → Veja mais sobre Mocks e muitos testes de unidade no curso Refatorando para Testes de Unidade

Dependendo de abstrações

Nosso primeiro passo é depender de abstrações (interfaces) e não de implementações (classes). Este motivo deve-se ao fato de uma interface poder conter várias implementações, enquanto uma classe não tem essa habilidade.

public class OrderHandler
{
    private readonly ICustomerRepository _repository;

    public OrderHandler(ICustomerRepository repository)
    {
        _repository = repository;
    }
}

Realizando os testes

Tudo o que precisamos fazer agora é instanciar o OrderHandler, que nos obrigará a informar um ICustomerRepository.

A boa notícia é que tanto o CustomerRepository quanto o FakeCustomerRepository são compatíveis, mas neste cenário vamos ficar com o falso.

[TestMethod]
public void Test01()
{
    var repo = new FakeCustomerRepository();
    var handler = new OrderHandler(repo);
}

Utilizando nos Controllers

Caso estivessemos em um cenário Web com MVC, podemos utilizá-los também nos controladores.

public IActionResult Get([FromServices]ICustomerRepository repo)
{
    ...
    repo.Save(customer);
    ...
}

Injeção de dependência

Neste momento você deve estar se perguntando como ele vai saber qual implementação chamar, a CustomerRepository ou a FakeCustomerRepository.

O que vai definir isto é a condiguração do Service Locator na sua aplicação.

services.AddTransient<ICustomerRepository, CustomerRepository>();

Desta forma o ASP.NET sabe qual implementação utilizar, dada uma interface.

Conclusão

Mesmo um assunto simple e básico, gera umas boas reflexões. É importante revisitar conteúdos de tempos em tempos para garantir que temos domínio sobre o assunto, ou que precisamos aprender mais.

Espero que tenham gostado!

Populares

Priority Queue

Priority Queue ou fila prioritária é um tipo de lista inclusa no C# 10 que permite que seus itens...


Implicit Operators no C#

Implicit Operators permitem adicionar comportamentos de conversão a objetos Built In ou complexos...


ASP.NET 5 – Autenticação e Autorização com Bearer e JWT

Este artigo atualmente utiliza a versão 5.0.0-rc.1 do ASP.NET/.NET, o que significa que ainda não...


Clean Code - Guia e Exemplos

Saiba como manter seu código limpo (Clean Code) seguindo algumas práticas sugeridas pelo Robert C...


Git e GitHub - Instalação, Configuração e Primeiros Passos

Git é um sistema de controle de versões distribuídas, enquanto GitHub é uma plataforma que tem o ...


Compartilhe este artigo



Conheça o autor

André Baltieri

André Baltieri

Microsoft MVP

Me dedico ao desenvolvimento de software desde 2003, sendo minha maior especialidade o Desenvolvimento Web. Durante esta jornada pude trabalhar presencialmente aqui no Brasil e Estados Unidos, atender remotamente times da ?ndia, Inglaterra e Holanda, receber 8x Microsoft MVP e realizar diversas consultorias em empresas e projetos de todos os tamanhos.





2.380

Aulas disponíveis

232

horas de conteúdo

50.896

Alunos matriculados

35.193

Certificados emitidos





Comece de graça agora mesmo!

Temos mais de 17 cursos totalmente de graça e todos com certificado de conclusão.

Começar


Prefere algo mais Premium?

Conheça nossos planos



Premium semestral

Compra única, parcelada em até
12x no cartão de crédito


12x R$

41

,48

=R$ 497,80
  • 6 meses de acesso
  • Acesso à todo conteúdo
  • Emissão de Certificado
  • Tira Dúvidas Online
  • 52 cursos disponíveis
  • 4 carreiras disponíveis
  • 161 temas de tecnologia
  • Conteúdo novo todo mês
  • Encontros Premium

Começar agora

Política de privacidade

Premium anual

Compra única, parcelada em até
12x no cartão de crédito


12x R$

70

,65

=R$ 847,80
  • 1 ano de acesso
  • Acesso à todo conteúdo
  • Emissão de Certificado
  • Tira Dúvidas Online
  • 52 cursos disponíveis
  • 4 carreiras disponíveis
  • 161 temas de tecnologia
  • Conteúdo novo todo mês
  • Encontros Premium

Começar agora

Política de privacidade



Precisa de ajuda?

Dúvidas frequentes



  • Posso começar de graça?

    Sim! Basta criar sua conta gratuita no balta.io e começar seus estudos. Nós contamos com diversos cursos TOTALMENTE gratuitos e com certificado de conclusão.

  • Vou ter que pagar algo?

    Nós temos cursos gratuitos e pagos, porém você não precisa informar nenhum dado de pagamento para começar seus estudos gratuitamente conosco. Os cursos gratuitos são completos e com certificado de conclusão, você não paga nada por eles.

    Porém, caso queira algo mais Premium , você terá acesso à diversos benefícios que vão te ajudar ainda mais em sua carreira.

  • Por onde devo começar?

    Siga SEMPRE as nossas Carreiras , elas vão te orientar em todos os sentidos. Os cursos já estão organizados em categorias e carreiras para facilitar seu aprendizado.
    Nossa sugestão para aprendizado é começar pelo Backend e seguindo para Frontend e Mobile.

    • Backend
    • Frontend
    • Mobile

  • Os cursos ensinam tudo que preciso?

    Nenhum curso no mundo vai te ensinar tudo, desculpa ser sincero! Os cursos são uma base, eles fornecem por volta de 30% do que você precisa aprender, o resto é com você, com dedicação e MUITA prática.

  • O que eu devo estudar?

    Java ou .NET? Angular ou React? Xamarin ou Flutter? A resposta é simples e direta: "Você já sabe o básico?"

    Se você ainda não sabe BEM o básico, ou seja, os fundamentos, OOP, SOLID, Clean Code, está perdendo tempo estudando Frameworks ou até coisas mais avançadas como Docker. Foque nos seus objetivos primeiro.
    Agora se você está indeciso sobre qual Framework estudar, a boa notícia é que o mercado neste momento está bem aquecido e você tem várias oportunidade. Desta forma o que levaríamos em conta para tomar esta decisão seria:

    • Já sei o básico
    • O Framework/Tecnologia tem mercado onde eu estou (região)
    • O Framework/Tecnologia é utilizado em uma empresa onde quero atual
    • O Framework/Tecnologia resolve meu problema
    • Eu gosto de utilizar o Framework/Tecnologia

  • Estou pronto para estudar no balta.io?

    Com certeza! O primeiro passo é começar e você pode fazer isto agora mesmo!

    Começar de graça

Ainda tem dúvidas?





Assine nosso Newsletter

Receba em primeira mão todas as nossas novidades.

Cadastrar


balta.io

Sobre

  • Como funciona?
  • Seja Premium
  • Agenda
  • Blog
  • Todos os cursos

Cursos

  • Frontend
  • Backend
  • Mobile
  • Fullstack

Suporte

  • Termos de uso
  • Privacidade
  • Cancelamento
  • Central de ajuda

Redes Sociais

  • Telegram
  • Facebook
  • Instagram
  • YouTube
  • Twitch
  • LinkedIn
  • Discord