{"id":1541,"date":"2026-07-28T23:12:06","date_gmt":"2026-07-29T02:12:06","guid":{"rendered":"https:\/\/micheladrianomedeiros.com.br\/blog\/?p=1541"},"modified":"2026-07-28T23:12:07","modified_gmt":"2026-07-29T02:12:07","slug":"factory-method-java","status":"publish","type":"post","link":"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/","title":{"rendered":"Factory Method em Java: aprenda o padr\u00e3o com exemplos pr\u00e1ticos"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"562\" src=\"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-content\/uploads\/2026\/07\/ChatGPT-Image-28-de-jul.-de-2026-23_06_47.png\" alt=\"Factory Method em Java\" class=\"wp-image-1542\" srcset=\"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-content\/uploads\/2026\/07\/ChatGPT-Image-28-de-jul.-de-2026-23_06_47.png 1000w, https:\/\/micheladrianomedeiros.com.br\/blog\/wp-content\/uploads\/2026\/07\/ChatGPT-Image-28-de-jul.-de-2026-23_06_47-300x169.png 300w, https:\/\/micheladrianomedeiros.com.br\/blog\/wp-content\/uploads\/2026\/07\/ChatGPT-Image-28-de-jul.-de-2026-23_06_47-768x432.png 768w, https:\/\/micheladrianomedeiros.com.br\/blog\/wp-content\/uploads\/2026\/07\/ChatGPT-Image-28-de-jul.-de-2026-23_06_47-218x122.png 218w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">O <strong>Factory Method em Java<\/strong> resolve um problema frequente em sistemas orientados a objetos: como criar inst\u00e2ncias sem espalhar depend\u00eancias de classes concretas por toda a aplica\u00e7\u00e3o?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Em um c\u00f3digo pequeno, escrever <code>new EmailNotification()<\/code> diretamente pode parecer suficiente. Entretanto, o cen\u00e1rio muda quando a aplica\u00e7\u00e3o precisa escolher entre e-mail, SMS, notifica\u00e7\u00e3o push ou outro canal. Se cada servi\u00e7o conhecer todas essas implementa\u00e7\u00f5es, o c\u00f3digo passa a acumular condicionais, depend\u00eancias e responsabilidades.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O padr\u00e3o Factory Method transfere a decis\u00e3o de cria\u00e7\u00e3o para um m\u00e9todo especializado. Dessa forma, o fluxo principal trabalha com abstra\u00e7\u00f5es, enquanto subclasses ou implementa\u00e7\u00f5es espec\u00edficas decidem qual objeto concreto produzir.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nesta segunda li\u00e7\u00e3o da trilha de Design Patterns, voc\u00ea aprender\u00e1:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>o problema que o Factory Method resolve;<\/li>\n\n\n\n<li>os participantes do padr\u00e3o;<\/li>\n\n\n\n<li>uma implementa\u00e7\u00e3o completa em Java;<\/li>\n\n\n\n<li>como adicionar novos produtos sem alterar o fluxo principal;<\/li>\n\n\n\n<li>como testar o c\u00f3digo;<\/li>\n\n\n\n<li>diferen\u00e7as entre Factory Method, Simple Factory e Abstract Factory;<\/li>\n\n\n\n<li>situa\u00e7\u00f5es nas quais o padr\u00e3o ajuda ou apenas aumenta a complexidade.<\/li>\n<\/ul>\n\n\n\n<div class=\"markdown-heading\"><div id=\"ez-toc-container\" class=\"ez-toc-v2_0_86 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#O_que_e_o_padrao_Factory_Method\" >O que \u00e9 o padr\u00e3o Factory Method?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#O_problema_do_acoplamento_direto\" >O problema do acoplamento direto<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Participantes_do_Factory_Method\" >Participantes do Factory Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Implementacao_do_Product\" >Implementa\u00e7\u00e3o do Product<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Implementacao_do_Creator\" >Implementa\u00e7\u00e3o do Creator<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Implementacao_dos_Concrete_Creators\" >Implementa\u00e7\u00e3o dos Concrete Creators<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Como_adicionar_notificacao_push\" >Como adicionar notifica\u00e7\u00e3o push<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Factory_Method_com_dependencias_reais\" >Factory Method com depend\u00eancias reais<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Como_testar_o_Factory_Method\" >Como testar o Factory Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Factory_Method_nao_e_apenas_uma_fabrica_estatica\" >Factory Method n\u00e3o \u00e9 apenas uma f\u00e1brica est\u00e1tica<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Factory_Method_com_Supplier\" >Factory Method com Supplier<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Factory_Method_Abstract_Factory_e_Builder\" >Factory Method, Abstract Factory e Builder<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Factory_Method\" >Factory Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Abstract_Factory\" >Abstract Factory<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Builder\" >Builder<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Relacao_com_os_principios_SOLID\" >Rela\u00e7\u00e3o com os princ\u00edpios SOLID<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Principio_da_Responsabilidade_Unica\" >Princ\u00edpio da Responsabilidade \u00danica<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Principio_AbertoFechado\" >Princ\u00edpio Aberto\/Fechado<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Principio_da_Substituicao_de_Liskov\" >Princ\u00edpio da Substitui\u00e7\u00e3o de Liskov<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Principio_da_Segregacao_de_Interfaces\" >Princ\u00edpio da Segrega\u00e7\u00e3o de Interfaces<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Principio_da_Inversao_de_Dependencia\" >Princ\u00edpio da Invers\u00e3o de Depend\u00eancia<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Erros_comuns_ao_implementar_Factory_Method\" >Erros comuns ao implementar Factory Method<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Criar_subclasses_sem_variacao_real\" >Criar subclasses sem varia\u00e7\u00e3o real<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Manter_um_grande_switch_no_criador_abstrato\" >Manter um grande switch no criador abstrato<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Expor_o_tipo_concreto_ao_cliente\" >Expor o tipo concreto ao cliente<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Usar_heranca_apenas_para_evitar_new\" >Usar heran\u00e7a apenas para evitar new<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Criar_uma_hierarquia_profunda\" >Criar uma hierarquia profunda<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Ignorar_o_ciclo_de_vida_do_produto\" >Ignorar o ciclo de vida do produto<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Quando_usar_Factory_Method\" >Quando usar Factory Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Quando_evitar_o_padrao\" >Quando evitar o padr\u00e3o<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Exercicio_pratico\" >Exerc\u00edcio pr\u00e1tico<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Desafio_avancado\" >Desafio avan\u00e7ado<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Conclusao\" >Conclus\u00e3o<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Perguntas_para_revisao\" >Perguntas para revis\u00e3o<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-35\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Resumo_da_licao\" >Resumo da li\u00e7\u00e3o<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-36\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Proxima_licao\" >Pr\u00f3xima li\u00e7\u00e3o<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-37\" href=\"https:\/\/micheladrianomedeiros.com.br\/blog\/factory-method-java\/#Practical_Java_Design_Patterns_Building_Reusable_and_Extensible_Software\" >Practical Java Design Patterns: Building Reusable and Extensible Software<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"O_que_e_o_padrao_Factory_Method\"><\/span>O que \u00e9 o padr\u00e3o Factory Method?<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-o-que-\u00e9-o-padr\u00e3o-factory-method\" class=\"anchor\" aria-label=\"Permalink: O que \u00e9 o padr\u00e3o Factory Method?\" href=\"#o-que-%C3%A9-o-padr%C3%A3o-factory-method\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O Factory Method pertence ao grupo dos <strong>padr\u00f5es de cria\u00e7\u00e3o<\/strong>. Esses padr\u00f5es organizam a constru\u00e7\u00e3o de objetos e reduzem o acoplamento entre quem solicita uma inst\u00e2ncia e quem conhece sua classe concreta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A ideia central pode ser resumida assim:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Uma classe define o fluxo de uma opera\u00e7\u00e3o, mas delega a cria\u00e7\u00e3o de um objeto para um m\u00e9todo que subclasses podem sobrescrever.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Portanto, o padr\u00e3o n\u00e3o significa apenas criar uma classe com o nome <code>Factory<\/code>. O elemento decisivo \u00e9 o uso de <strong>polimorfismo<\/strong> para variar o produto criado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Considere um servi\u00e7o respons\u00e1vel por enviar notifica\u00e7\u00f5es. O algoritmo geral pode seguir estas etapas:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>validar o destinat\u00e1rio;<\/li>\n\n\n\n<li>criar a notifica\u00e7\u00e3o apropriada;<\/li>\n\n\n\n<li>registrar o in\u00edcio do envio;<\/li>\n\n\n\n<li>enviar a mensagem;<\/li>\n\n\n\n<li>registrar o resultado.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">O fluxo permanece igual para e-mail, SMS ou push. Contudo, cada canal usa uma implementa\u00e7\u00e3o diferente. O Factory Method preserva o algoritmo comum e permite que cada criador concreto escolha seu produto.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"O_problema_do_acoplamento_direto\"><\/span>O problema do acoplamento direto<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-o-problema-do-acoplamento-direto\" class=\"anchor\" aria-label=\"Permalink: O problema do acoplamento direto\" href=\"#o-problema-do-acoplamento-direto\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Observe uma implementa\u00e7\u00e3o inicial:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">channel<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-k\">if<\/span> (<span class=\"pl-s\">\"email\"<\/span>.<span class=\"pl-en\">equalsIgnoreCase<\/span>(<span class=\"pl-s1\">channel<\/span>)) {\n            <span class=\"pl-smi\">EmailNotification<\/span> <span class=\"pl-s1\">notification<\/span> = <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">EmailNotification<\/span>();\n            <span class=\"pl-s1\">notification<\/span>.<span class=\"pl-en\">send<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s1\">message<\/span>);\n        } <span class=\"pl-k\">else<\/span> <span class=\"pl-k\">if<\/span> (<span class=\"pl-s\">\"sms\"<\/span>.<span class=\"pl-en\">equalsIgnoreCase<\/span>(<span class=\"pl-s1\">channel<\/span>)) {\n            <span class=\"pl-smi\">SmsNotification<\/span> <span class=\"pl-s1\">notification<\/span> = <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">SmsNotification<\/span>();\n            <span class=\"pl-s1\">notification<\/span>.<span class=\"pl-en\">send<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s1\">message<\/span>);\n        } <span class=\"pl-k\">else<\/span> {\n            <span class=\"pl-k\">throw<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">IllegalArgumentException<\/span>(<span class=\"pl-s\">\"Canal n\u00e3o suportado: \"<\/span> + <span class=\"pl-s1\">channel<\/span>);\n        }\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Esse c\u00f3digo funciona. Por\u00e9m, ele apresenta alguns problemas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><br><code>NotificationService<\/code> conhece todas as classes concretas;<\/li>\n\n\n\n<li>cada novo canal exige a altera\u00e7\u00e3o do m\u00e9todo;<\/li>\n\n\n\n<li>a condi\u00e7\u00e3o cresce conforme o sistema recebe novas op\u00e7\u00f5es;<\/li>\n\n\n\n<li>a classe mistura orquestra\u00e7\u00e3o com cria\u00e7\u00e3o de objetos;<\/li>\n\n\n\n<li>os testes precisam considerar v\u00e1rias ramifica\u00e7\u00f5es no mesmo componente.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Al\u00e9m disso, a classe viola a inten\u00e7\u00e3o do <strong>Princ\u00edpio Aberto\/Fechado<\/strong>, do SOLID. O sistema deveria permitir extens\u00e3o sem exigir mudan\u00e7as constantes no fluxo j\u00e1 validado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O <strong>Factory Method em Java<\/strong> separa essas responsabilidades.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Participantes_do_Factory_Method\"><\/span>Participantes do Factory Method<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-participantes-do-factory-method\" class=\"anchor\" aria-label=\"Permalink: Participantes do Factory Method\" href=\"#participantes-do-factory-method\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">A estrutura cl\u00e1ssica cont\u00e9m quatro pap\u00e9is principais.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Participante<\/th><th>Responsabilidade<\/th><\/tr><\/thead><tbody><tr><td><strong>Product<\/strong><\/td><td>Define o contrato dos objetos produzidos<\/td><\/tr><tr><td><strong>Concrete Product<\/strong><\/td><td>Implementa o produto para um caso espec\u00edfico<\/td><\/tr><tr><td><strong>Creator<\/strong><\/td><td>Declara o factory method e cont\u00e9m o fluxo comum<\/td><\/tr><tr><td><strong>Concrete Creator<\/strong><\/td><td>Sobrescreve o factory method e escolhe o produto concreto<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">No exemplo de notifica\u00e7\u00f5es, teremos:<\/p>\n\n\n\n<pre class=\"wp-block-code\" lang=\"text\"><code>Notification                  -&gt; Product\nEmailNotification             -&gt; Concrete Product\nSmsNotification               -&gt; Concrete Product\nNotificationService           -&gt; Creator\nEmailNotificationService      -&gt; Concrete Creator\nSmsNotificationService        -&gt; Concrete Creator\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A classe criadora n\u00e3o precisa limitar seu trabalho \u00e0 fabrica\u00e7\u00e3o do objeto. Pelo contr\u00e1rio, ela normalmente cont\u00e9m uma opera\u00e7\u00e3o de neg\u00f3cio que utiliza o produto criado.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Implementacao_do_Product\"><\/span>Implementa\u00e7\u00e3o do Product<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-implementa\u00e7\u00e3o-do-product\" class=\"anchor\" aria-label=\"Permalink: Implementa\u00e7\u00e3o do Product\" href=\"#implementa%C3%A7%C3%A3o-do-product\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Primeiramente, definimos o contrato das notifica\u00e7\u00f5es:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">interface<\/span> <span class=\"pl-smi\">Notification<\/span> {\n\n    <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>);\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">A interface representa aquilo que o fluxo principal precisa. Como resultado, o criador n\u00e3o precisa conhecer detalhes de SMTP, gateway de SMS ou API de push.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Agora, criamos os produtos concretos.<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">EmailNotification<\/span> <span class=\"pl-k\">implements<\/span> <span class=\"pl-smi\">Notification<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-smi\">System<\/span>.<span class=\"pl-s1\">out<\/span>.<span class=\"pl-en\">printf<\/span>(\n                <span class=\"pl-s\">\"Enviando e-mail para %s: %s%n\"<\/span>,\n                <span class=\"pl-s1\">recipient<\/span>,\n                <span class=\"pl-s1\">message<\/span>\n        );\n    }\n}<\/pre><\/div>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">SmsNotification<\/span> <span class=\"pl-k\">implements<\/span> <span class=\"pl-smi\">Notification<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-smi\">System<\/span>.<span class=\"pl-s1\">out<\/span>.<span class=\"pl-en\">printf<\/span>(\n                <span class=\"pl-s\">\"Enviando SMS para %s: %s%n\"<\/span>,\n                <span class=\"pl-s1\">recipient<\/span>,\n                <span class=\"pl-s1\">message<\/span>\n        );\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">As duas classes implementam o mesmo contrato. Entretanto, cada uma pode integrar um provedor diferente, aplicar valida\u00e7\u00f5es pr\u00f3prias ou transformar a mensagem antes do envio.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Implementacao_do_Creator\"><\/span>Implementa\u00e7\u00e3o do Creator<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-implementa\u00e7\u00e3o-do-creator\" class=\"anchor\" aria-label=\"Permalink: Implementa\u00e7\u00e3o do Creator\" href=\"#implementa%C3%A7%C3%A3o-do-creator\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Em seguida, criamos a classe abstrata que define o m\u00e9todo f\u00e1brica:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">import<\/span> <span class=\"pl-s1\">java<\/span>.<span class=\"pl-s1\">util<\/span>.<span class=\"pl-s1\">Objects<\/span>;\n\n<span class=\"pl-k\">public<\/span> <span class=\"pl-k\">abstract<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-k\">protected<\/span> <span class=\"pl-k\">abstract<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">createNotification<\/span>();\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">notify<\/span>(\n            <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>,\n            <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>\n    ) {\n        <span class=\"pl-en\">validate<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s1\">message<\/span>);\n\n        <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-s1\">notification<\/span> = <span class=\"pl-en\">createNotification<\/span>();\n\n        <span class=\"pl-smi\">System<\/span>.<span class=\"pl-s1\">out<\/span>.<span class=\"pl-en\">println<\/span>(<span class=\"pl-s\">\"Iniciando envio...\"<\/span>);\n        <span class=\"pl-s1\">notification<\/span>.<span class=\"pl-en\">send<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s1\">message<\/span>);\n        <span class=\"pl-smi\">System<\/span>.<span class=\"pl-s1\">out<\/span>.<span class=\"pl-en\">println<\/span>(<span class=\"pl-s\">\"Envio conclu\u00eddo.\"<\/span>);\n    }\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">validate<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-smi\">Objects<\/span>.<span class=\"pl-en\">requireNonNull<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s\">\"Destinat\u00e1rio obrigat\u00f3rio\"<\/span>);\n        <span class=\"pl-smi\">Objects<\/span>.<span class=\"pl-en\">requireNonNull<\/span>(<span class=\"pl-s1\">message<\/span>, <span class=\"pl-s\">\"Mensagem obrigat\u00f3ria\"<\/span>);\n\n        <span class=\"pl-k\">if<\/span> (<span class=\"pl-s1\">recipient<\/span>.<span class=\"pl-en\">isBlank<\/span>()) {\n            <span class=\"pl-k\">throw<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">IllegalArgumentException<\/span>(\n                    <span class=\"pl-s\">\"Destinat\u00e1rio n\u00e3o pode ficar vazio\"<\/span>\n            );\n        }\n\n        <span class=\"pl-k\">if<\/span> (<span class=\"pl-s1\">message<\/span>.<span class=\"pl-en\">isBlank<\/span>()) {\n            <span class=\"pl-k\">throw<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">IllegalArgumentException<\/span>(\n                    <span class=\"pl-s\">\"Mensagem n\u00e3o pode ficar vazia\"<\/span>\n            );\n        }\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O m\u00e9todo <code>createNotification()<\/code> representa o Factory Method. A classe base declara o contrato de cria\u00e7\u00e3o, mas n\u00e3o escolhe a classe concreta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por outro lado, o m\u00e9todo <code>notify()<\/code> cont\u00e9m o algoritmo comum. Ele valida os dados, solicita um produto, executa o envio e registra o andamento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al\u00e9m disso, o modificador <code>final<\/code> impede que subclasses substituam todo o fluxo e eliminem etapas importantes. As subclasses podem variar a cria\u00e7\u00e3o, mas n\u00e3o podem ignorar as valida\u00e7\u00f5es definidas pelo criador.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Essa combina\u00e7\u00e3o aproxima o Factory Method do <strong>Template Method<\/strong>. O algoritmo principal forma um modelo, enquanto um ponto espec\u00edfico permite varia\u00e7\u00e3o. Contudo, cada padr\u00e3o possui uma inten\u00e7\u00e3o diferente: Factory Method concentra-se na cria\u00e7\u00e3o; Template Method concentra-se na varia\u00e7\u00e3o de etapas de um algoritmo.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Implementacao_dos_Concrete_Creators\"><\/span>Implementa\u00e7\u00e3o dos Concrete Creators<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-implementa\u00e7\u00e3o-dos-concrete-creators\" class=\"anchor\" aria-label=\"Permalink: Implementa\u00e7\u00e3o dos Concrete Creators\" href=\"#implementa%C3%A7%C3%A3o-dos-concrete-creators\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Agora, cada criador concreto escolhe um produto:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">EmailNotificationService<\/span>\n        <span class=\"pl-k\">extends<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">protected<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">createNotification<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">EmailNotification<\/span>();\n    }\n}<\/pre><\/div>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">SmsNotificationService<\/span>\n        <span class=\"pl-k\">extends<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">protected<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">createNotification<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">SmsNotification<\/span>();\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Por fim, usamos os servi\u00e7os:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">Main<\/span> {\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-k\">static<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">main<\/span>(<span class=\"pl-smi\">String<\/span>[] <span class=\"pl-s1\">args<\/span>) {\n        <span class=\"pl-smi\">NotificationService<\/span> <span class=\"pl-s1\">emailService<\/span> =\n                <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">EmailNotificationService<\/span>();\n\n        <span class=\"pl-smi\">NotificationService<\/span> <span class=\"pl-s1\">smsService<\/span> =\n                <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">SmsNotificationService<\/span>();\n\n        <span class=\"pl-s1\">emailService<\/span>.<span class=\"pl-en\">notify<\/span>(\n                <span class=\"pl-s\">\"aluno@example.com\"<\/span>,\n                <span class=\"pl-s\">\"Sua matr\u00edcula foi confirmada.\"<\/span>\n        );\n\n        <span class=\"pl-s1\">smsService<\/span>.<span class=\"pl-en\">notify<\/span>(\n                <span class=\"pl-s\">\"+5511999999999\"<\/span>,\n                <span class=\"pl-s\">\"Seu c\u00f3digo de acesso \u00e9 4821.\"<\/span>\n        );\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O cliente ainda escolhe qual criador utilizar. No entanto, ele trabalha com o tipo abstrato <code>NotificationService<\/code>, e o fluxo principal n\u00e3o conhece os produtos concretos.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Como_adicionar_notificacao_push\"><\/span>Como adicionar notifica\u00e7\u00e3o push<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-como-adicionar-notifica\u00e7\u00e3o-push\" class=\"anchor\" aria-label=\"Permalink: Como adicionar notifica\u00e7\u00e3o push\" href=\"#como-adicionar-notifica%C3%A7%C3%A3o-push\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Uma das principais vantagens do <strong>Factory Method em Java<\/strong> aparece quando o sistema precisa crescer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Primeiro, criamos outro produto:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">PushNotification<\/span> <span class=\"pl-k\">implements<\/span> <span class=\"pl-smi\">Notification<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-smi\">System<\/span>.<span class=\"pl-s1\">out<\/span>.<span class=\"pl-en\">printf<\/span>(\n                <span class=\"pl-s\">\"Enviando push ao dispositivo %s: %s%n\"<\/span>,\n                <span class=\"pl-s1\">recipient<\/span>,\n                <span class=\"pl-s1\">message<\/span>\n        );\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Depois, criamos o respectivo criador:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">PushNotificationService<\/span>\n        <span class=\"pl-k\">extends<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">protected<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">createNotification<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">PushNotification<\/span>();\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00e3o alteramos <code>NotificationService<\/code>, <code>EmailNotificationService<\/code> ou <code>SmsNotificationService<\/code>. Assim, o novo comportamento entra por extens\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esse resultado demonstra o Princ\u00edpio Aberto\/Fechado de maneira pr\u00e1tica. O c\u00f3digo continua aberto para novos canais, mas permanece fechado para altera\u00e7\u00f5es desnecess\u00e1rias no algoritmo central.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Factory_Method_com_dependencias_reais\"><\/span>Factory Method com depend\u00eancias reais<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-factory-method-com-depend\u00eancias-reais\" class=\"anchor\" aria-label=\"Permalink: Factory Method com depend\u00eancias reais\" href=\"#factory-method-com-depend%C3%AAncias-reais\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Em sistemas reais, um produto normalmente depende de outras classes. Por exemplo, uma notifica\u00e7\u00e3o por e-mail pode precisar de um cliente SMTP e de configura\u00e7\u00f5es.<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">interface<\/span> <span class=\"pl-smi\">EmailClient<\/span> {\n\n    <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">deliver<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>);\n}<\/pre><\/div>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">SmtpEmailNotification<\/span>\n        <span class=\"pl-k\">implements<\/span> <span class=\"pl-smi\">Notification<\/span> {\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-smi\">EmailClient<\/span> <span class=\"pl-s1\">emailClient<\/span>;\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">SmtpEmailNotification<\/span>(<span class=\"pl-smi\">EmailClient<\/span> <span class=\"pl-s1\">emailClient<\/span>) {\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">emailClient<\/span> = <span class=\"pl-s1\">emailClient<\/span>;\n    }\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-s1\">emailClient<\/span>.<span class=\"pl-en\">deliver<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s1\">message<\/span>);\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O criador pode receber a depend\u00eancia por construtor:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">SmtpNotificationService<\/span>\n        <span class=\"pl-k\">extends<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-smi\">EmailClient<\/span> <span class=\"pl-s1\">emailClient<\/span>;\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">SmtpNotificationService<\/span>(<span class=\"pl-smi\">EmailClient<\/span> <span class=\"pl-s1\">emailClient<\/span>) {\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">emailClient<\/span> = <span class=\"pl-s1\">emailClient<\/span>;\n    }\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">protected<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">createNotification<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">SmtpEmailNotification<\/span>(<span class=\"pl-s1\">emailClient<\/span>);\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Dessa maneira, a f\u00e1brica n\u00e3o precisa criar todas as depend\u00eancias com <code>new<\/code>. Um cont\u00eainer de inje\u00e7\u00e3o, como Spring, CDI ou Guice, pode fornecer o <code>EmailClient<\/code> ao criador.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Portanto, Factory Method e inje\u00e7\u00e3o de depend\u00eancias n\u00e3o competem. Em muitos projetos, eles trabalham juntos.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Como_testar_o_Factory_Method\"><\/span>Como testar o Factory Method<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-como-testar-o-factory-method\" class=\"anchor\" aria-label=\"Permalink: Como testar o Factory Method\" href=\"#como-testar-o-factory-method\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O padr\u00e3o facilita testes quando o fluxo principal depende apenas da interface do produto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podemos criar um produto espi\u00e3o para verificar a chamada:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">NotificationSpy<\/span>\n        <span class=\"pl-k\">implements<\/span> <span class=\"pl-smi\">Notification<\/span> {\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-smi\">boolean<\/span> <span class=\"pl-s1\">sent<\/span>;\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>;\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>;\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">send<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">sent<\/span> = <span class=\"pl-c1\">true<\/span>;\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">recipient<\/span> = <span class=\"pl-s1\">recipient<\/span>;\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">message<\/span> = <span class=\"pl-s1\">message<\/span>;\n    }\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">boolean<\/span> <span class=\"pl-en\">wasSent<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-s1\">sent<\/span>;\n    }\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">String<\/span> <span class=\"pl-en\">recipient<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-s1\">recipient<\/span>;\n    }\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">String<\/span> <span class=\"pl-en\">message<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-s1\">message<\/span>;\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Em seguida, criamos um criador espec\u00edfico para o teste:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">TestNotificationService<\/span>\n        <span class=\"pl-k\">extends<\/span> <span class=\"pl-smi\">NotificationService<\/span> {\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-s1\">notification<\/span>;\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">TestNotificationService<\/span>(<span class=\"pl-smi\">Notification<\/span> <span class=\"pl-s1\">notification<\/span>) {\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">notification<\/span> = <span class=\"pl-s1\">notification<\/span>;\n    }\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Override<\/span>\n    <span class=\"pl-k\">protected<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">createNotification<\/span>() {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-s1\">notification<\/span>;\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Com JUnit 5, o teste pode ficar assim:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">import<\/span> <span class=\"pl-k\">static<\/span> <span class=\"pl-s1\">org<\/span>.<span class=\"pl-s1\">junit<\/span>.<span class=\"pl-s1\">jupiter<\/span>.<span class=\"pl-s1\">api<\/span>.<span class=\"pl-s1\">Assertions<\/span>.<span class=\"pl-s1\">assertEquals<\/span>;\n<span class=\"pl-k\">import<\/span> <span class=\"pl-k\">static<\/span> <span class=\"pl-s1\">org<\/span>.<span class=\"pl-s1\">junit<\/span>.<span class=\"pl-s1\">jupiter<\/span>.<span class=\"pl-s1\">api<\/span>.<span class=\"pl-s1\">Assertions<\/span>.<span class=\"pl-s1\">assertTrue<\/span>;\n\n<span class=\"pl-k\">import<\/span> <span class=\"pl-s1\">org<\/span>.<span class=\"pl-s1\">junit<\/span>.<span class=\"pl-s1\">jupiter<\/span>.<span class=\"pl-s1\">api<\/span>.<span class=\"pl-s1\">Test<\/span>;\n\n<span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">NotificationServiceTest<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Test<\/span>\n    <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">shouldSendNotificationCreatedByFactoryMethod<\/span>() {\n        <span class=\"pl-smi\">NotificationSpy<\/span> <span class=\"pl-s1\">spy<\/span> = <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">NotificationSpy<\/span>();\n        <span class=\"pl-smi\">NotificationService<\/span> <span class=\"pl-s1\">service<\/span> =\n                <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">TestNotificationService<\/span>(<span class=\"pl-s1\">spy<\/span>);\n\n        <span class=\"pl-s1\">service<\/span>.<span class=\"pl-en\">notify<\/span>(\n                <span class=\"pl-s\">\"cliente@example.com\"<\/span>,\n                <span class=\"pl-s\">\"Pedido aprovado\"<\/span>\n        );\n\n        <span class=\"pl-en\">assertTrue<\/span>(<span class=\"pl-s1\">spy<\/span>.<span class=\"pl-en\">wasSent<\/span>());\n        <span class=\"pl-en\">assertEquals<\/span>(\n                <span class=\"pl-s\">\"cliente@example.com\"<\/span>,\n                <span class=\"pl-s1\">spy<\/span>.<span class=\"pl-en\">recipient<\/span>()\n        );\n        <span class=\"pl-en\">assertEquals<\/span>(<span class=\"pl-s\">\"Pedido aprovado\"<\/span>, <span class=\"pl-s1\">spy<\/span>.<span class=\"pl-en\">message<\/span>());\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Esse teste verifica o fluxo sem enviar e-mail ou SMS de verdade. Al\u00e9m disso, ele n\u00e3o depende de bibliotecas de mock.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tamb\u00e9m devemos testar as valida\u00e7\u00f5es:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">import<\/span> <span class=\"pl-k\">static<\/span> <span class=\"pl-s1\">org<\/span>.<span class=\"pl-s1\">junit<\/span>.<span class=\"pl-s1\">jupiter<\/span>.<span class=\"pl-s1\">api<\/span>.<span class=\"pl-s1\">Assertions<\/span>.<span class=\"pl-s1\">assertThrows<\/span>;\n\n<span class=\"pl-k\">import<\/span> <span class=\"pl-s1\">org<\/span>.<span class=\"pl-s1\">junit<\/span>.<span class=\"pl-s1\">jupiter<\/span>.<span class=\"pl-s1\">api<\/span>.<span class=\"pl-s1\">Test<\/span>;\n\n<span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">NotificationValidationTest<\/span> {\n\n    <span class=\"pl-c1\">@<\/span><span class=\"pl-c1\">Test<\/span>\n    <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">shouldRejectBlankRecipient<\/span>() {\n        <span class=\"pl-smi\">NotificationService<\/span> <span class=\"pl-s1\">service<\/span> =\n                <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">TestNotificationService<\/span>(\n                        <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">NotificationSpy<\/span>()\n                );\n\n        <span class=\"pl-en\">assertThrows<\/span>(\n                <span class=\"pl-smi\">IllegalArgumentException<\/span>.<span class=\"pl-k\">class<\/span>,\n                () -&gt; <span class=\"pl-s1\">service<\/span>.<span class=\"pl-en\">notify<\/span>(<span class=\"pl-s\">\" \"<\/span>, <span class=\"pl-s\">\"Mensagem\"<\/span>)\n        );\n    }\n}<\/pre><\/div>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Factory_Method_nao_e_apenas_uma_fabrica_estatica\"><\/span>Factory Method n\u00e3o \u00e9 apenas uma f\u00e1brica est\u00e1tica<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-factory-method-n\u00e3o-\u00e9-apenas-uma-f\u00e1brica-est\u00e1tica\" class=\"anchor\" aria-label=\"Permalink: Factory Method n\u00e3o \u00e9 apenas uma f\u00e1brica est\u00e1tica\" href=\"#factory-method-n%C3%A3o-%C3%A9-apenas-uma-f%C3%A1brica-est%C3%A1tica\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Muitos projetos chamam qualquer m\u00e9todo que cria objetos de Factory Method. Entretanto, existe uma diferen\u00e7a importante entre o padr\u00e3o GoF e uma f\u00e1brica simples.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Considere este exemplo:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">NotificationFactory<\/span> {\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-smi\">NotificationFactory<\/span>() {\n    }\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-k\">static<\/span> <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-en\">create<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">channel<\/span>) {\n        <span class=\"pl-k\">return<\/span> <span class=\"pl-k\">switch<\/span> (<span class=\"pl-s1\">channel<\/span>.<span class=\"pl-en\">toLowerCase<\/span>()) {\n            <span class=\"pl-k\">case<\/span> <span class=\"pl-s\">\"email\"<\/span> -&gt; <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">EmailNotification<\/span>();\n            <span class=\"pl-k\">case<\/span> <span class=\"pl-s\">\"sms\"<\/span> -&gt; <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">SmsNotification<\/span>();\n            <span class=\"pl-k\">case<\/span> <span class=\"pl-s\">\"push\"<\/span> -&gt; <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">PushNotification<\/span>();\n            <span class=\"pl-k\">default<\/span> -&gt; <span class=\"pl-k\">throw<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">IllegalArgumentException<\/span>(\n                    <span class=\"pl-s\">\"Canal inv\u00e1lido: \"<\/span> + <span class=\"pl-s1\">channel<\/span>\n            );\n        };\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Essa classe centraliza a constru\u00e7\u00e3o e pode melhorar o c\u00f3digo. Contudo, ela representa uma <strong>Simple Factory<\/strong>, n\u00e3o o Factory Method cl\u00e1ssico.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A Simple Factory usa uma decis\u00e3o central, normalmente com <code>if<\/code> ou <code>switch<\/code>. J\u00e1 o Factory Method usa heran\u00e7a ou polimorfismo para delegar a cria\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nenhuma op\u00e7\u00e3o vence em todos os cen\u00e1rios. Uma Simple Factory pode resolver perfeitamente um problema pequeno e com poucas varia\u00e7\u00f5es. Por outro lado, o Factory Method oferece mais flexibilidade quando cada produto acompanha um fluxo especializado ou quando novas extens\u00f5es surgem com frequ\u00eancia.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Factory_Method_com_Supplier\"><\/span>Factory Method com <code>Supplier<\/code>\n<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-factory-method-com-supplier\" class=\"anchor\" aria-label=\"Permalink: Factory Method com Supplier\" href=\"#factory-method-com-supplier\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O Java tamb\u00e9m permite tratar construtores como fun\u00e7\u00f5es por meio da interface <code>Supplier&lt;T&gt;<\/code>.<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-k\">import<\/span> <span class=\"pl-s1\">java<\/span>.<span class=\"pl-s1\">util<\/span>.<span class=\"pl-s1\">function<\/span>.<span class=\"pl-s1\">Supplier<\/span>;\n\n<span class=\"pl-k\">public<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-k\">class<\/span> <span class=\"pl-smi\">ConfigurableNotificationService<\/span> {\n\n    <span class=\"pl-k\">private<\/span> <span class=\"pl-k\">final<\/span> <span class=\"pl-smi\">Supplier<\/span>&lt;<span class=\"pl-smi\">Notification<\/span>&gt; <span class=\"pl-s1\">factory<\/span>;\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">ConfigurableNotificationService<\/span>(\n            <span class=\"pl-smi\">Supplier<\/span>&lt;<span class=\"pl-smi\">Notification<\/span>&gt; <span class=\"pl-s1\">factory<\/span>\n    ) {\n        <span class=\"pl-smi\">this<\/span>.<span class=\"pl-s1\">factory<\/span> = <span class=\"pl-s1\">factory<\/span>;\n    }\n\n    <span class=\"pl-k\">public<\/span> <span class=\"pl-smi\">void<\/span> <span class=\"pl-en\">notify<\/span>(<span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-smi\">String<\/span> <span class=\"pl-s1\">message<\/span>) {\n        <span class=\"pl-smi\">Notification<\/span> <span class=\"pl-s1\">notification<\/span> = <span class=\"pl-s1\">factory<\/span>.<span class=\"pl-en\">get<\/span>();\n        <span class=\"pl-s1\">notification<\/span>.<span class=\"pl-en\">send<\/span>(<span class=\"pl-s1\">recipient<\/span>, <span class=\"pl-s1\">message<\/span>);\n    }\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O cliente pode passar refer\u00eancias de construtor:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-smi\">ConfigurableNotificationService<\/span> <span class=\"pl-s1\">emailService<\/span> =\n        <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">ConfigurableNotificationService<\/span>(\n                <span class=\"pl-smi\">EmailNotification<\/span>::<span class=\"pl-k\">new<\/span>\n        );\n\n<span class=\"pl-smi\">ConfigurableNotificationService<\/span> <span class=\"pl-s1\">smsService<\/span> =\n        <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">ConfigurableNotificationService<\/span>(\n                <span class=\"pl-smi\">SmsNotification<\/span>::<span class=\"pl-k\">new<\/span>\n        );<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Essa abordagem usa composi\u00e7\u00e3o em vez de heran\u00e7a. Portanto, ela reduz a quantidade de subclasses e permite trocar a estrat\u00e9gia de cria\u00e7\u00e3o em tempo de execu\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Embora o formato n\u00e3o reproduza exatamente a estrutura cl\u00e1ssica do GoF, ele preserva a inten\u00e7\u00e3o principal: separar o uso do objeto da decis\u00e3o sobre sua constru\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Em Java moderno, vale comparar as duas solu\u00e7\u00f5es antes de criar muitas subclasses.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Factory_Method_Abstract_Factory_e_Builder\"><\/span>Factory Method, Abstract Factory e Builder<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-factory-method-abstract-factory-e-builder\" class=\"anchor\" aria-label=\"Permalink: Factory Method, Abstract Factory e Builder\" href=\"#factory-method-abstract-factory-e-builder\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Os padr\u00f5es de cria\u00e7\u00e3o podem parecer semelhantes. Entretanto, cada um resolve um problema distinto.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Factory_Method\"><\/span>Factory Method<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-factory-method\" class=\"anchor\" aria-label=\"Permalink: Factory Method\" href=\"#factory-method\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O Factory Method delega a cria\u00e7\u00e3o de um produto para subclasses ou implementa\u00e7\u00f5es especializadas. Ele funciona bem quando uma opera\u00e7\u00e3o comum precisa variar o tipo do objeto utilizado.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Abstract_Factory\"><\/span>Abstract Factory<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-abstract-factory\" class=\"anchor\" aria-label=\"Permalink: Abstract Factory\" href=\"#abstract-factory\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">A Abstract Factory cria <strong>fam\u00edlias de objetos relacionados<\/strong>. Por exemplo, uma f\u00e1brica de interface gr\u00e1fica pode produzir bot\u00e3o, campo de texto e janela para Windows; outra f\u00e1brica pode produzir os mesmos componentes para Linux.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enquanto o Factory Method costuma tratar um ponto de cria\u00e7\u00e3o, a Abstract Factory coordena v\u00e1rios produtos compat\u00edveis.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Builder\"><\/span>Builder<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-builder\" class=\"anchor\" aria-label=\"Permalink: Builder\" href=\"#builder\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O Builder organiza a constru\u00e7\u00e3o de objetos complexos em etapas. Ele ajuda quando uma classe possui muitos par\u00e2metros, combina\u00e7\u00f5es opcionais ou regras de montagem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Portanto:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>use Factory Method para variar o produto criado dentro de um fluxo;<\/li>\n\n\n\n<li>use Abstract Factory para produzir fam\u00edlias de produtos compat\u00edveis;<\/li>\n\n\n\n<li>use Builder para montar um objeto complexo passo a passo.<\/li>\n<\/ul>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Relacao_com_os_principios_SOLID\"><\/span>Rela\u00e7\u00e3o com os princ\u00edpios SOLID<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-rela\u00e7\u00e3o-com-os-princ\u00edpios-solid\" class=\"anchor\" aria-label=\"Permalink: Rela\u00e7\u00e3o com os princ\u00edpios SOLID\" href=\"#rela%C3%A7%C3%A3o-com-os-princ%C3%ADpios-solid\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O <strong>Factory Method em Java<\/strong> pode apoiar v\u00e1rios princ\u00edpios do SOLID.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Principio_da_Responsabilidade_Unica\"><\/span>Princ\u00edpio da Responsabilidade \u00danica<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-princ\u00edpio-da-responsabilidade-\u00fanica\" class=\"anchor\" aria-label=\"Permalink: Princ\u00edpio da Responsabilidade \u00danica\" href=\"#princ%C3%ADpio-da-responsabilidade-%C3%BAnica\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O criador coordena o fluxo, enquanto o produto executa uma opera\u00e7\u00e3o espec\u00edfica. Al\u00e9m disso, criadores concretos encapsulam a escolha da implementa\u00e7\u00e3o.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Principio_AbertoFechado\"><\/span>Princ\u00edpio Aberto\/Fechado<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-princ\u00edpio-abertofechado\" class=\"anchor\" aria-label=\"Permalink: Princ\u00edpio Aberto\/Fechado\" href=\"#princ%C3%ADpio-abertofechado\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Novos produtos entram por meio de novas classes. Assim, o algoritmo central n\u00e3o precisa mudar a cada extens\u00e3o.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Principio_da_Substituicao_de_Liskov\"><\/span>Princ\u00edpio da Substitui\u00e7\u00e3o de Liskov<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-princ\u00edpio-da-substitui\u00e7\u00e3o-de-liskov\" class=\"anchor\" aria-label=\"Permalink: Princ\u00edpio da Substitui\u00e7\u00e3o de Liskov\" href=\"#princ%C3%ADpio-da-substitui%C3%A7%C3%A3o-de-liskov\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Todo produto concreto deve respeitar o contrato definido por <code>Notification<\/code>. Da mesma forma, cada criador concreto deve funcionar onde o tipo abstrato <code>NotificationService<\/code> aparece.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Principio_da_Segregacao_de_Interfaces\"><\/span>Princ\u00edpio da Segrega\u00e7\u00e3o de Interfaces<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-princ\u00edpio-da-segrega\u00e7\u00e3o-de-interfaces\" class=\"anchor\" aria-label=\"Permalink: Princ\u00edpio da Segrega\u00e7\u00e3o de Interfaces\" href=\"#princ%C3%ADpio-da-segrega%C3%A7%C3%A3o-de-interfaces\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">A interface <code>Notification<\/code> deve conter apenas opera\u00e7\u00f5es necess\u00e1rias aos clientes. Uma interface excessivamente ampla for\u00e7a produtos a implementar m\u00e9todos que n\u00e3o utilizam.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Principio_da_Inversao_de_Dependencia\"><\/span>Princ\u00edpio da Invers\u00e3o de Depend\u00eancia<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-princ\u00edpio-da-invers\u00e3o-de-depend\u00eancia\" class=\"anchor\" aria-label=\"Permalink: Princ\u00edpio da Invers\u00e3o de Depend\u00eancia\" href=\"#princ%C3%ADpio-da-invers%C3%A3o-de-depend%C3%AAncia\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O fluxo principal depende da abstra\u00e7\u00e3o <code>Notification<\/code>, n\u00e3o de <code>EmailNotification<\/code> ou <code>SmsNotification<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Entretanto, aplicar o padr\u00e3o n\u00e3o garante automaticamente um bom design. As abstra\u00e7\u00f5es precisam representar contratos coerentes, e as subclasses precisam preservar o comportamento esperado.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Erros_comuns_ao_implementar_Factory_Method\"><\/span>Erros comuns ao implementar Factory Method<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-erros-comuns-ao-implementar-factory-method\" class=\"anchor\" aria-label=\"Permalink: Erros comuns ao implementar Factory Method\" href=\"#erros-comuns-ao-implementar-factory-method\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Criar_subclasses_sem_variacao_real\"><\/span>Criar subclasses sem varia\u00e7\u00e3o real<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-criar-subclasses-sem-varia\u00e7\u00e3o-real\" class=\"anchor\" aria-label=\"Permalink: Criar subclasses sem varia\u00e7\u00e3o real\" href=\"#criar-subclasses-sem-varia%C3%A7%C3%A3o-real\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Se todas as subclasses retornam o mesmo produto e n\u00e3o existe perspectiva de mudan\u00e7a, o padr\u00e3o apenas adiciona arquivos e indire\u00e7\u00e3o.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Manter_um_grande_switch_no_criador_abstrato\"><\/span>Manter um grande <code>switch<\/code> no criador abstrato<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-manter-um-grande-switch-no-criador-abstrato\" class=\"anchor\" aria-label=\"Permalink: Manter um grande switch no criador abstrato\" href=\"#manter-um-grande-switch-no-criador-abstrato\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Quando o m\u00e9todo f\u00e1brica cont\u00e9m todas as decis\u00f5es concretas, a classe continua acoplada aos produtos. Nesse caso, voc\u00ea criou uma f\u00e1brica central, n\u00e3o uma extens\u00e3o polim\u00f3rfica.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Expor_o_tipo_concreto_ao_cliente\"><\/span>Expor o tipo concreto ao cliente<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-expor-o-tipo-concreto-ao-cliente\" class=\"anchor\" aria-label=\"Permalink: Expor o tipo concreto ao cliente\" href=\"#expor-o-tipo-concreto-ao-cliente\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O cliente deve trabalhar com <code>Notification<\/code>, sempre que poss\u00edvel. Retornar <code>EmailNotification<\/code> elimina parte do benef\u00edcio da abstra\u00e7\u00e3o.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Usar_heranca_apenas_para_evitar_new\"><\/span>Usar heran\u00e7a apenas para evitar <code>new<\/code>\n<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-usar-heran\u00e7a-apenas-para-evitar-new\" class=\"anchor\" aria-label=\"Permalink: Usar heran\u00e7a apenas para evitar new\" href=\"#usar-heran%C3%A7a-apenas-para-evitar-new\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">A palavra-chave <code>new<\/code> n\u00e3o representa um problema por si mesma. O problema surge quando a decis\u00e3o de cria\u00e7\u00e3o muda, se repete ou acopla componentes que deveriam evoluir separadamente.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Criar_uma_hierarquia_profunda\"><\/span>Criar uma hierarquia profunda<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-criar-uma-hierarquia-profunda\" class=\"anchor\" aria-label=\"Permalink: Criar uma hierarquia profunda\" href=\"#criar-uma-hierarquia-profunda\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Uma estrutura com muitos n\u00edveis de criadores pode dificultar a navega\u00e7\u00e3o. Prefira hierarquias rasas e considere composi\u00e7\u00e3o com <code>Supplier<\/code>, fun\u00e7\u00f5es ou inje\u00e7\u00e3o de depend\u00eancias.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h3 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Ignorar_o_ciclo_de_vida_do_produto\"><\/span>Ignorar o ciclo de vida do produto<span class=\"ez-toc-section-end\"><\/span><\/h3><a id=\"user-content-ignorar-o-ciclo-de-vida-do-produto\" class=\"anchor\" aria-label=\"Permalink: Ignorar o ciclo de vida do produto\" href=\"#ignorar-o-ciclo-de-vida-do-produto\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O factory method pode criar uma inst\u00e2ncia nova a cada chamada ou reutilizar uma inst\u00e2ncia existente. A decis\u00e3o depende do estado, da seguran\u00e7a em concorr\u00eancia e do custo de constru\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Produtos mut\u00e1veis n\u00e3o devem ser compartilhados sem uma an\u00e1lise cuidadosa. Por outro lado, produtos imut\u00e1veis ou sem estado podem permitir reutiliza\u00e7\u00e3o segura.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Quando_usar_Factory_Method\"><\/span>Quando usar Factory Method<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-quando-usar-factory-method\" class=\"anchor\" aria-label=\"Permalink: Quando usar Factory Method\" href=\"#quando-usar-factory-method\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Considere o padr\u00e3o quando:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>uma classe n\u00e3o consegue prever qual produto concreto utilizar\u00e1;<\/li>\n\n\n\n<li>subclasses precisam escolher o objeto usado pelo algoritmo;<\/li>\n\n\n\n<li>novos produtos devem entrar sem altera\u00e7\u00f5es frequentes no c\u00f3digo central;<\/li>\n\n\n\n<li>a cria\u00e7\u00e3o inclui regras, depend\u00eancias ou configura\u00e7\u00f5es relevantes;<\/li>\n\n\n\n<li>o c\u00f3digo precisa substituir produtos em testes;<\/li>\n\n\n\n<li>frameworks precisam oferecer pontos de extens\u00e3o para aplica\u00e7\u00f5es clientes.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Frameworks usam essa ideia com frequ\u00eancia. Eles fornecem um fluxo geral e permitem que a aplica\u00e7\u00e3o substitua um componente espec\u00edfico.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Quando_evitar_o_padrao\"><\/span>Quando evitar o padr\u00e3o<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-quando-evitar-o-padr\u00e3o\" class=\"anchor\" aria-label=\"Permalink: Quando evitar o padr\u00e3o\" href=\"#quando-evitar-o-padr%C3%A3o\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Evite o Factory Method quando:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>existe apenas uma implementa\u00e7\u00e3o est\u00e1vel;<\/li>\n\n\n\n<li>a cria\u00e7\u00e3o consiste em um <code>new<\/code> simples e local;<\/li>\n\n\n\n<li>uma fun\u00e7\u00e3o ou <code>Supplier<\/code> resolve o problema com menos estrutura;<\/li>\n\n\n\n<li>a hierarquia de classes n\u00e3o representa uma rela\u00e7\u00e3o conceitual v\u00e1lida;<\/li>\n\n\n\n<li>a equipe teria dificuldade para compreender a indire\u00e7\u00e3o adicionada.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Design Patterns n\u00e3o servem como metas de quantidade. Um projeto n\u00e3o melhora porque cont\u00e9m mais padr\u00f5es. Ele melhora quando suas decis\u00f5es de design reduzem riscos concretos e tornam as mudan\u00e7as mais seguras.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Exercicio_pratico\"><\/span>Exerc\u00edcio pr\u00e1tico<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-exerc\u00edcio-pr\u00e1tico\" class=\"anchor\" aria-label=\"Permalink: Exerc\u00edcio pr\u00e1tico\" href=\"#exerc%C3%ADcio-pr%C3%A1tico\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Crie um sistema de exporta\u00e7\u00e3o de relat\u00f3rios com os seguintes elementos:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>uma interface <code>ReportExporter<\/code> com o m\u00e9todo <code>export(String content)<\/code>;<\/li>\n\n\n\n<li>produtos concretos para PDF, CSV e JSON;<\/li>\n\n\n\n<li>uma classe abstrata <code>ReportService<\/code>;<\/li>\n\n\n\n<li>um factory method chamado <code>createExporter()<\/code>;<\/li>\n\n\n\n<li>um m\u00e9todo final <code>generateReport()<\/code> que prepare o conte\u00fado e execute a exporta\u00e7\u00e3o;<\/li>\n\n\n\n<li>um criador concreto para cada formato;<\/li>\n\n\n\n<li>testes que usem um <code>ReportExporterSpy<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Depois, responda:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>qual classe conhece o produto concreto?<\/li>\n\n\n\n<li>qual classe cont\u00e9m o algoritmo comum?<\/li>\n\n\n\n<li>como voc\u00ea adicionaria XML sem alterar o criador abstrato?<\/li>\n\n\n\n<li>uma solu\u00e7\u00e3o com <code>Supplier&lt;ReportExporter><\/code> ficaria mais simples?<\/li>\n\n\n\n<li>o produto deve gerar uma nova inst\u00e2ncia em cada chamada?<\/li>\n<\/ul>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Desafio_avancado\"><\/span>Desafio avan\u00e7ado<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-desafio-avan\u00e7ado\" class=\"anchor\" aria-label=\"Permalink: Desafio avan\u00e7ado\" href=\"#desafio-avan%C3%A7ado\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Adapte o exemplo para receber uma configura\u00e7\u00e3o externa, como <code>EMAIL<\/code>, <code>SMS<\/code> ou <code>PUSH<\/code>, sem criar um grande <code>switch<\/code> dentro do fluxo de envio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uma alternativa consiste em registrar criadores em um mapa:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-smi\">Map<\/span>&lt;<span class=\"pl-smi\">String<\/span>, <span class=\"pl-smi\">Supplier<\/span>&lt;<span class=\"pl-smi\">NotificationService<\/span>&gt;&gt; <span class=\"pl-s1\">services<\/span> = <span class=\"pl-smi\">Map<\/span>.<span class=\"pl-en\">of<\/span>(\n        <span class=\"pl-s\">\"EMAIL\"<\/span>, <span class=\"pl-smi\">EmailNotificationService<\/span>::<span class=\"pl-k\">new<\/span>,\n        <span class=\"pl-s\">\"SMS\"<\/span>, <span class=\"pl-smi\">SmsNotificationService<\/span>::<span class=\"pl-k\">new<\/span>,\n        <span class=\"pl-s\">\"PUSH\"<\/span>, <span class=\"pl-smi\">PushNotificationService<\/span>::<span class=\"pl-k\">new<\/span>\n);<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Depois, selecione o criador na borda da aplica\u00e7\u00e3o:<\/p>\n\n\n\n<div class=\"highlight highlight-source-java\"><pre><span class=\"pl-smi\">NotificationService<\/span> <span class=\"pl-s1\">service<\/span> =\n        <span class=\"pl-s1\">services<\/span>.<span class=\"pl-en\">getOrDefault<\/span>(\n                <span class=\"pl-s1\">configuredChannel<\/span>,\n                () -&gt; {\n                    <span class=\"pl-k\">throw<\/span> <span class=\"pl-k\">new<\/span> <span class=\"pl-smi\">IllegalArgumentException<\/span>(\n                            <span class=\"pl-s\">\"Canal n\u00e3o configurado\"<\/span>\n                    );\n                }\n        ).<span class=\"pl-en\">get<\/span>();<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Esse registro mant\u00e9m a decis\u00e3o de configura\u00e7\u00e3o fora do algoritmo de neg\u00f3cio. Al\u00e9m disso, ele permite combinar Factory Method, composi\u00e7\u00e3o e fun\u00e7\u00f5es de f\u00e1brica.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Conclusao\"><\/span>Conclus\u00e3o<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-conclus\u00e3o\" class=\"anchor\" aria-label=\"Permalink: Conclus\u00e3o\" href=\"#conclus%C3%A3o\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O <strong>Factory Method em Java<\/strong> separa o fluxo de uso da decis\u00e3o sobre qual objeto criar. O padr\u00e3o usa abstra\u00e7\u00f5es e polimorfismo para reduzir o acoplamento com classes concretas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A implementa\u00e7\u00e3o cl\u00e1ssica cont\u00e9m Product, Concrete Product, Creator e Concrete Creator. O criador define o algoritmo comum e chama um m\u00e9todo f\u00e1brica. Em seguida, cada criador concreto escolhe o produto apropriado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Contudo, o padr\u00e3o n\u00e3o deve entrar automaticamente em todo ponto que cont\u00e9m <code>new<\/code>. Antes de aplic\u00e1-lo, avalie a frequ\u00eancia das mudan\u00e7as, a quantidade de produtos, a complexidade da cria\u00e7\u00e3o e a possibilidade de usar composi\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quando o problema realmente exige extensibilidade, o Factory Method ajuda a manter o c\u00f3digo aberto para novos comportamentos e protegido contra altera\u00e7\u00f5es repetidas no n\u00facleo da aplica\u00e7\u00e3o.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Perguntas_para_revisao\"><\/span>Perguntas para revis\u00e3o<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-perguntas-para-revis\u00e3o\" class=\"anchor\" aria-label=\"Permalink: Perguntas para revis\u00e3o\" href=\"#perguntas-para-revis%C3%A3o\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Qual problema o Factory Method resolve?<\/li>\n\n\n\n<li>Qual diferen\u00e7a existe entre Product e Creator?<\/li>\n\n\n\n<li>Por que uma f\u00e1brica est\u00e1tica com <code>switch<\/code> n\u00e3o representa necessariamente o padr\u00e3o cl\u00e1ssico?<\/li>\n\n\n\n<li>Como o Factory Method apoia o Princ\u00edpio Aberto\/Fechado?<\/li>\n\n\n\n<li>Quando <code>Supplier&lt;T><\/code> pode substituir uma hierarquia de criadores?<\/li>\n\n\n\n<li>Qual diferen\u00e7a existe entre Factory Method e Abstract Factory?<\/li>\n\n\n\n<li>Como testar o algoritmo do Creator sem executar uma integra\u00e7\u00e3o real?<\/li>\n\n\n\n<li>Por que o uso de <code>new<\/code> n\u00e3o constitui, sozinho, um problema de design?<\/li>\n<\/ol>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Resumo_da_licao\"><\/span>Resumo da li\u00e7\u00e3o<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-resumo-da-li\u00e7\u00e3o\" class=\"anchor\" aria-label=\"Permalink: Resumo da li\u00e7\u00e3o\" href=\"#resumo-da-li%C3%A7%C3%A3o\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">O Factory Method delega a cria\u00e7\u00e3o de objetos a componentes especializados. Em Java, ele reduz o acoplamento, facilita extens\u00f5es e melhora a testabilidade quando o sistema possui produtos vari\u00e1veis.<\/p>\n\n\n\n<div class=\"markdown-heading\"><h2 class=\"heading-element\"><span class=\"ez-toc-section\" id=\"Proxima_licao\"><\/span>Pr\u00f3xima li\u00e7\u00e3o<span class=\"ez-toc-section-end\"><\/span><\/h2><a id=\"user-content-pr\u00f3xima-li\u00e7\u00e3o\" class=\"anchor\" aria-label=\"Permalink: Pr\u00f3xima li\u00e7\u00e3o\" href=\"#pr%C3%B3xima-li%C3%A7%C3%A3o\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"><\/span><\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Na pr\u00f3xima etapa, estudaremos o <strong>Abstract Factory<\/strong>, padr\u00e3o que cria fam\u00edlias de objetos relacionados e garante compatibilidade entre os produtos de cada fam\u00edlia.<\/p>\n\n\n    <article class=\"aabp-card aabp-style-card\">\n                            <a href=\"https:\/\/link.amazon\/B05peeh78\" target=\"_blank\" rel=\"nofollow sponsored noopener\" class=\"aabp-image\">\n                <img decoding=\"async\" src=\"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-content\/uploads\/2026\/07\/71w6ANy8JnL._SL1491_1.jpg\" alt=\"Practical Java Design Patterns: Building Reusable and Extensible Software\" loading=\"lazy\">\n            <\/a>\n                <div class=\"aabp-content\">\n            <h3><span class=\"ez-toc-section\" id=\"Practical_Java_Design_Patterns_Building_Reusable_and_Extensible_Software\"><\/span>Practical Java Design Patterns: Building Reusable and Extensible Software<span class=\"ez-toc-section-end\"><\/span><\/h3>\n            <div class=\"aabp-rating\">\u2b50 5.0\/5<\/div>            <p>Practical Java Design Patterns: Building Reusable and Extensible Software. Produto recomendado para estudos, programa\u00e7\u00e3o e produtividade.<\/p>            <div class=\"aabp-price-row\">\n                                <strong class=\"aabp-price\">R$ 174,43<\/strong>            <\/div>\n            <a class=\"aabp-button\" href=\"https:\/\/link.amazon\/B05peeh78\" target=\"_blank\" rel=\"nofollow sponsored noopener\">Ver na Amazon<\/a>\n            <small class=\"aabp-disclaimer\">Como afiliado, posso receber comiss\u00e3o por compras qualificadas.<\/small>\n        <\/div>\n    <\/article>\n    \n\n\n\n<ul class=\"wp-block-list\">\n<li>Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides. <em>Design Patterns: Elements of Reusable Object-Oriented Software<\/em>.<\/li>\n\n\n\n<li>Joshua Bloch. <em>Effective Java<\/em>.<\/li>\n\n\n\n<li><a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/java\/IandI\/createinterface.html\" target=\"_blank\" rel=\"noopener\">Interfaces em Java \u2014 documenta\u00e7\u00e3o oficial<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/java\/javaOO\/lambdaexpressions.html\" target=\"_blank\" rel=\"noopener\">Express\u00f5es lambda em Java \u2014 documenta\u00e7\u00e3o oficial<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/21\/docs\/api\/java.base\/java\/util\/function\/Supplier.html\" target=\"_blank\" rel=\"noopener\">Interface Supplier \u2014 Java API<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/junit.org\/junit5\/docs\/current\/user-guide\/\" target=\"_blank\" rel=\"noopener\">JUnit 5 User Guide<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Aprenda a aplicar Factory Method em Java para criar objetos com baixo acoplamento, extensibilidade e testes mais simples.<\/p>\n","protected":false},"author":1,"featured_media":1542,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[227,23,609,5,610,228,611],"class_list":["post-1541","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-designpatterns","tag-arquitetura-de-software","tag-design-patterns","tag-factory-method","tag-java","tag-orientacao-a-objetos","tag-padroes-de-criacao","tag-solid"],"_links":{"self":[{"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/posts\/1541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/comments?post=1541"}],"version-history":[{"count":1,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/posts\/1541\/revisions"}],"predecessor-version":[{"id":1545,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/posts\/1541\/revisions\/1545"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/media\/1542"}],"wp:attachment":[{"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/micheladrianomedeiros.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}