{"id":862,"date":"2024-10-07T10:55:02","date_gmt":"2024-10-07T13:55:02","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/?p=862"},"modified":"2024-10-07T10:55:03","modified_gmt":"2024-10-07T13:55:03","slug":"poo-4o-pilar-abstracao","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/poo-4o-pilar-abstracao\/","title":{"rendered":"Poo 4o. Pilar: Abstra\u00e7\u00e3o"},"content":{"rendered":"\n<p>O conceito de <strong>Abstra\u00e7\u00e3o<\/strong> \u00e9 o pilar final da Programa\u00e7\u00e3o Orientada a Objetos e tem como objetivo esconder os detalhes complexos de implementa\u00e7\u00e3o de um objeto, expondo apenas as partes essenciais para o usu\u00e1rio. Esse processo permite que trabalhemos com sistemas de forma mais simples e organizada, focando apenas no que \u00e9 realmente necess\u00e1rio para o funcionamento de uma classe ou objeto.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Com a abstra\u00e7\u00e3o, podemos definir <strong>interfaces<\/strong> ou <strong>classes abstratas<\/strong> que descrevem o comportamento esperado de um grupo de objetos, sem se preocupar com os detalhes espec\u00edficos de implementa\u00e7\u00e3o. Esse conceito torna o c\u00f3digo mais flex\u00edvel e f\u00e1cil de manter, pois podemos criar novos objetos baseados na mesma interface sem precisar alterar o restante do sistema.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Por que a Abstra\u00e7\u00e3o \u00e9 Importante?<\/strong><\/h3>\n\n\n\n<p>A abstra\u00e7\u00e3o \u00e9 essencial no desenvolvimento de software porque ela nos permite trabalhar em um n\u00edvel mais alto, escondendo a complexidade dos detalhes de implementa\u00e7\u00e3o e focando apenas no comportamento essencial. Isso simplifica o design, manuten\u00e7\u00e3o e expans\u00e3o dos sistemas, garantindo que apenas as informa\u00e7\u00f5es relevantes sejam expostas, deixando os detalhes internos encapsulados.<\/p>\n\n\n\n<p>Ao aplicar a abstra\u00e7\u00e3o, conseguimos criar sistemas modulares, onde as partes internas podem ser alteradas ou aprimoradas sem impactar o resto da aplica\u00e7\u00e3o. Vamos ver algumas situa\u00e7\u00f5es reais onde a abstra\u00e7\u00e3o \u00e9 amplamente usada:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Sistemas de Pagamento em e-commerce<\/strong>: Imagine um sistema que lida com diferentes m\u00e9todos de pagamento (cart\u00e3o de cr\u00e9dito, PayPal, boleto, etc.). Podemos criar uma interface comum que define o comportamento essencial de um m\u00e9todo de pagamento, enquanto as classes concretas implementam cada tipo de pagamento espec\u00edfico. Assim, se precisarmos adicionar um novo m\u00e9todo no futuro, basta criar uma nova classe que implemente a interface, sem alterar o restante do sistema.<\/li>\n\n\n\n<li><strong>Opera\u00e7\u00f5es de Banco de Dados<\/strong>: Abstrair o acesso a diferentes bancos de dados (SQLite, MySQL, SQL Server) pode permitir que um sistema se conecte a m\u00faltiplos bancos sem alterar o c\u00f3digo de neg\u00f3cios. Com isso, conseguimos mudar o tipo de banco de dados ou adicionar um novo suporte sem tocar em outras camadas da aplica\u00e7\u00e3o.<\/li>\n\n\n\n<li><strong>Interfaces de Usu\u00e1rio (UI)<\/strong>: Em aplica\u00e7\u00f5es desktop e mobile, a abstra\u00e7\u00e3o pode ser usada para criar interfaces gen\u00e9ricas de usu\u00e1rios. O comportamento b\u00e1sico de uma tela pode ser definido em uma interface, enquanto implementa\u00e7\u00f5es diferentes lidam com especificidades para Android, iOS ou Windows. Isso permite criar uma \u00fanica l\u00f3gica de interface que funciona em v\u00e1rias plataformas.<\/li>\n\n\n\n<li><strong>Processamento de Pedidos em um ERP<\/strong>: Em um ERP, o m\u00f3dulo de pedidos pode ser abstrato o suficiente para permitir que diferentes tipos de pedidos (vendas, compras, devolu\u00e7\u00f5es) sigam a mesma l\u00f3gica base, mas com detalhes espec\u00edficos implementados em subclasses. Isso facilita a adi\u00e7\u00e3o de novos tipos de pedidos sem modificar o n\u00facleo do sistema.<\/li>\n<\/ol>\n\n\n\n<p>Esses exemplos demonstram que a abstra\u00e7\u00e3o n\u00e3o s\u00f3 simplifica o desenvolvimento, mas tamb\u00e9m torna os sistemas mais adapt\u00e1veis e escal\u00e1veis.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>O que veremos a seguir?<\/strong><\/h3>\n\n\n\n<p>Agora que entendemos a import\u00e2ncia da abstra\u00e7\u00e3o, o pr\u00f3ximo passo ser\u00e1 revisar a s\u00e9rie completa, amarrando todos os pilares da Programa\u00e7\u00e3o Orientada a Objetos e discutindo como aplicar esses conceitos em projetos reais, com exemplos pr\u00e1ticos e dicas para usar essas t\u00e9cnicas no desenvolvimento Delphi.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Exemplo Pr\u00e1tico em Delphi<\/strong><\/h3>\n\n\n\n<p>Vamos criar um exemplo em Delphi de abstra\u00e7\u00e3o utilizando uma interface para pedidos. Vamos definir uma interface para um pedido, e duas classes que a implementam de maneiras diferentes.<\/p>\n\n\n\n<p><strong>Interface para Pedido:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  IPedido = interface\n    ['{GUID}']\n    procedure AdicionarProduto(const Produto: string; Quantidade: Integer);\n    function CalcularTotal: Currency;\n    procedure FinalizarPedido;\n  end;\n<\/pre><\/div>\n\n\n\n<p><strong>Classe Pedido Padr\u00e3o:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TPedidoPadr\u00e3o = class(TInterfacedObject, IPedido)\n  private\n    FProdutos: TStringList;\n    FTotal: Currency;\n  public\n    constructor Create;\n    destructor Destroy; override;\n    procedure AdicionarProduto(const Produto: string; Quantidade: Integer);\n    function CalcularTotal: Currency;\n    procedure FinalizarPedido;\n  end;\n\nconstructor TPedidoPadr\u00e3o.Create;\nbegin\n  FProdutos := TStringList.Create;\n  FTotal := 0;\nend;\n\ndestructor TPedidoPadr\u00e3o.Destroy;\nbegin\n  FProdutos.Free;\n  inherited;\nend;\n\nprocedure TPedidoPadr\u00e3o.AdicionarProduto(const Produto: string; Quantidade: Integer);\nbegin\n  FProdutos.Add(Produto + ' x' + IntToStr(Quantidade));\n  FTotal := FTotal + (Quantidade * 100); \/\/ Exemplo: Cada produto custa R$100,00.\nend;\n\nfunction TPedidoPadr\u00e3o.CalcularTotal: Currency;\nbegin\n  Result := FTotal;\nend;\n\nprocedure TPedidoPadr\u00e3o.FinalizarPedido;\nbegin\n  Writeln('Pedido Finalizado! Total: R$' + CurrToStr(FTotal));\nend;\n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Explica\u00e7\u00e3o do Exemplo<\/strong><\/h3>\n\n\n\n<p>Neste exemplo, criamos a interface <code>IPedido<\/code>, que define tr\u00eas m\u00e9todos essenciais para qualquer pedido: <code>AdicionarProduto<\/code>, <code>CalcularTotal<\/code>, e <code>FinalizarPedido<\/code>. A classe <code>TPedidoPadr\u00e3o<\/code> implementa essa interface e cont\u00e9m a l\u00f3gica b\u00e1sica para calcular o total de um pedido e finaliz\u00e1-lo.<\/p>\n\n\n\n<p>Essa implementa\u00e7\u00e3o permite que outras classes possam usar a interface sem precisar conhecer os detalhes internos da classe <code>TPedidoPadr\u00e3o<\/code>. Por exemplo, uma classe de pedido especial pode implementar a mesma interface com regras de desconto, sem precisar alterar o restante do sistema.<\/p>\n\n\n\n<p>Agora vamos criar uma segunda classe que tamb\u00e9m implementa a interface <code>IPedido<\/code>, mas de uma maneira diferente. Essa classe vai adicionar uma funcionalidade de <strong>desconto<\/strong> no pedido, que ser\u00e1 aplicada ao valor total. Essa abordagem ilustra como diferentes implementa\u00e7\u00f5es da mesma interface podem coexistir, oferecendo comportamentos distintos.<\/p>\n\n\n\n<p><strong>Classe Pedido com Desconto:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  TPedidoComDesconto = class(TInterfacedObject, IPedido)\n  private\n    FProdutos: TStringList;\n    FTotal: Currency;\n    FDesconto: Currency;\n  public\n    constructor Create;\n    destructor Destroy; override;\n    procedure AdicionarProduto(const Produto: string; Quantidade: Integer);\n    function CalcularTotal: Currency;\n    procedure AplicarDesconto(Desconto: Currency);\n    procedure FinalizarPedido;\n  end;\n\nconstructor TPedidoComDesconto.Create;\nbegin\n  FProdutos := TStringList.Create;\n  FTotal := 0;\n  FDesconto := 0;\nend;\n\ndestructor TPedidoComDesconto.Destroy;\nbegin\n  FProdutos.Free;\n  inherited;\nend;\n\nprocedure TPedidoComDesconto.AdicionarProduto(const Produto: string; Quantidade: Integer);\nbegin\n  FProdutos.Add(Produto + ' x' + IntToStr(Quantidade));\n  FTotal := FTotal + (Quantidade * 100); \/\/ Exemplo: Cada produto custa R$100,00.\nend;\n\nprocedure TPedidoComDesconto.AplicarDesconto(Desconto: Currency);\nbegin\n  if Desconto &gt; FTotal then\n    raise Exception.Create('Desconto n\u00e3o pode ser maior que o total do pedido');\n  FDesconto := Desconto;\nend;\n\nfunction TPedidoComDesconto.CalcularTotal: Currency;\nbegin\n  Result := FTotal - FDesconto;\nend;\n\nprocedure TPedidoComDesconto.FinalizarPedido;\nbegin\n  Writeln('Pedido com Desconto Finalizado! Total com Desconto: R$' + CurrToStr(CalcularTotal));\nend;\n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Explica\u00e7\u00e3o do Exemplo<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Classe <code>TPedidoComDesconto<\/code>:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Essa classe implementa a interface <code>IPedido<\/code>, mas com uma l\u00f3gica adicional de desconto. Um novo m\u00e9todo <code>AplicarDesconto<\/code> foi adicionado, que permite reduzir o valor total do pedido.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>M\u00e9todo <code>AplicarDesconto<\/code>:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Este m\u00e9todo recebe o valor do desconto e o aplica ao total do pedido. A l\u00f3gica inclui uma verifica\u00e7\u00e3o para garantir que o desconto n\u00e3o seja maior que o valor total, lan\u00e7ando uma exce\u00e7\u00e3o se essa regra for violada.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>M\u00e9todo <code>CalcularTotal<\/code>:<\/strong>\n<ul class=\"wp-block-list\">\n<li>O m\u00e9todo <code>CalcularTotal<\/code> retorna o valor total subtraindo o desconto aplicado, diferentemente da classe <code>TPedidoPadr\u00e3o<\/code>, onde o desconto n\u00e3o \u00e9 considerado.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Tratamento de Exce\u00e7\u00f5es:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Implementamos tratamento de erro no m\u00e9todo <code>AplicarDesconto<\/code> para garantir que a l\u00f3gica de neg\u00f3cios seja respeitada, impedindo que o desconto ultrapasse o valor do pedido.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Uso das Classes:<\/strong><\/h3>\n\n\n\n<p>Agora, vamos ver como podemos usar ambas as classes (<code>TPedidoPadr\u00e3o<\/code> e <code>TPedidoComDesconto<\/code>) no mesmo c\u00f3digo:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">var\n  Pedido: IPedido;\nbegin\n  \/\/ Usando a classe TPedidoPadr\u00e3o\n  Pedido := TPedidoPadr\u00e3o.Create;\n  Pedido.AdicionarProduto('Produto A', 2);\n  Pedido.FinalizarPedido;\n\n  \/\/ Usando a classe TPedidoComDesconto\n  Pedido := TPedidoComDesconto.Create;\n  Pedido.AdicionarProduto('Produto B', 3);\n  TPedidoComDesconto(Pedido).AplicarDesconto(50.0); \/\/ Aplicando desconto\n  Pedido.FinalizarPedido;\nend;\n<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Conclus\u00e3o<\/strong><\/h3>\n\n\n\n<p>A abstra\u00e7\u00e3o, como vimos, \u00e9 um pilar fundamental da Programa\u00e7\u00e3o Orientada a Objetos, permitindo que desenvolvedores criem sistemas modulares e f\u00e1ceis de manter. Ao ocultar os detalhes complexos e focar no comportamento essencial, conseguimos criar c\u00f3digo mais limpo e escal\u00e1vel, com menos acoplamento entre as partes. No exemplo pr\u00e1tico, mostramos como podemos criar diferentes implementa\u00e7\u00f5es para uma mesma interface, ilustrando como a abstra\u00e7\u00e3o facilita a reutiliza\u00e7\u00e3o e a expans\u00e3o dos sistemas.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Revis\u00e3o Geral dos 04 Pilares<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Encapsulamento<\/strong>: Protege os dados e restringe o acesso a eles, expondo apenas o necess\u00e1rio por meio de m\u00e9todos p\u00fablicos. Ele garante que o estado interno de um objeto s\u00f3 possa ser alterado de maneira controlada, proporcionando maior seguran\u00e7a e organiza\u00e7\u00e3o. Exemplo: controlando o acesso aos dados de um pedido.<\/li>\n\n\n\n<li><strong>Heran\u00e7a<\/strong>: Permite criar novas classes baseadas em classes existentes, promovendo o reuso de c\u00f3digo. Isso facilita a cria\u00e7\u00e3o de sistemas extens\u00edveis, onde funcionalidades comuns s\u00e3o centralizadas e especializa\u00e7\u00f5es s\u00e3o feitas em subclasses. Exemplo: <code>TPedidoOnline<\/code> e <code>TPedidoPresencial<\/code>, ambas herdando de uma classe <code>TPedido<\/code>.<\/li>\n\n\n\n<li><strong>Polimorfismo<\/strong>: Proporciona flexibilidade, permitindo que objetos de diferentes tipos sejam tratados de maneira uniforme. Isso permite que m\u00e9todos sobrecarregados ou sobrescritos ofere\u00e7am comportamentos diferentes com a mesma interface. Exemplo: usando diferentes tipos de c\u00e1lculo de frete para pedidos.<\/li>\n\n\n\n<li><strong>Abstra\u00e7\u00e3o<\/strong>: Ajuda a esconder a complexidade e se concentrar nos aspectos mais importantes, como comportamentos e regras de neg\u00f3cio, sem se preocupar com a implementa\u00e7\u00e3o interna. Exemplo: criar uma interface gen\u00e9rica <code>IPedido<\/code> para diferentes tipos de pedidos em um ERP.<\/li>\n<\/ol>\n\n\n\n<p>Esses pilares trabalham juntos para criar software robusto, extens\u00edvel e f\u00e1cil de manter. Nos pr\u00f3ximos artigos, esses conceitos ser\u00e3o explorados em profundidade para mostrar como aplic\u00e1-los no dia a dia de projetos reais.<\/p>\n\n\n\n<p>\ud83d\udd1c <strong>Nova S\u00e9rie: Padr\u00f5es de Programa\u00e7\u00e3o e C\u00f3digo Limpo<\/strong><\/p>\n\n\n\n<p>A pr\u00f3xima s\u00e9rie trar\u00e1 uma abordagem pr\u00e1tica para te ajudar a escrever c\u00f3digo mais organizado e eficiente. Vamos explorar padr\u00f5es de codifica\u00e7\u00e3o que melhoram a legibilidade e manuten\u00e7\u00e3o do c\u00f3digo. Entre os temas, abordaremos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Como nomear vari\u00e1veis e fun\u00e7\u00f5es de forma significativa.<\/li>\n\n\n\n<li>Boas pr\u00e1ticas de indenta\u00e7\u00e3o e formata\u00e7\u00e3o.<\/li>\n\n\n\n<li>Regras de codifica\u00e7\u00e3o que facilitam o trabalho em equipe.<\/li>\n<\/ul>\n\n\n\n<p>Prepare-se para aprimorar suas habilidades e elevar seu n\u00edvel como desenvolvedor! Vamos transformar seu c\u00f3digo em uma verdadeira obra-prima. \ud83d\ude80<\/p>\n\n\n\n<p>O objetivo n\u00e3o \u00e9 falar de c\u00f3digo-limpo, j\u00e1 que falamos bastante sobre isso semanas atr\u00e1s, mas vamos te mostrar como usar um padr\u00e3o e estilo de programa\u00e7\u00e3o que facilitar\u00e1 a leitura de c\u00f3digo e manuten\u00e7\u00e3o dos seus sistemas. Bora?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Participe da Comunidade no Telegram<\/h3>\n\n\n\n<p>\ud83d\ude80 Quer continuar essa discuss\u00e3o e trocar ideias com outros desenvolvedores? Junte-se \u00e0 nossa comunidade no Telegram! L\u00e1, voc\u00ea pode comentar sobre o que achou deste artigo, tirar suas d\u00favidas e compartilhar suas experi\u00eancias com POO e Delphi, e ainda discutir ou tirar suas d\u00favidas sobre os mais variados temas em uma comunidade com mais de 1.000 desenvolvedores.<\/p>\n\n\n\n<p>\ud83d\udd17 <a href=\"https:\/\/t.me\/AdrianoSantosCommunity\" target=\"_blank\" rel=\"noreferrer noopener\">Clique aqui para entrar na comunidade<\/a><\/p>\n\n\n\n<p>Te vejo l\u00e1!<\/p>\n\n\n\n<p>Adriano Santos<\/p>\n","protected":false},"excerpt":{"rendered":"<p>O conceito de Abstra\u00e7\u00e3o \u00e9 o pilar final da Programa\u00e7\u00e3o Orientada a Objetos e tem como objetivo esconder os detalhes complexos de implementa\u00e7\u00e3o de um objeto, expondo apenas as partes essenciais para o usu\u00e1rio. Esse processo permite que trabalhemos com sistemas de forma mais simples e organizada, focando apenas no que \u00e9 realmente necess\u00e1rio para [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":865,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-862","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/comments?post=862"}],"version-history":[{"count":3,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":866,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/862\/revisions\/866"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/865"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}