{"id":231154,"date":"2022-12-14T14:16:00","date_gmt":"2022-12-14T11:16:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231154"},"modified":"2022-12-14T14:18:26","modified_gmt":"2022-12-14T11:18:26","slug":"widgets-do-wordpress-detectar-programacao-orientada-a-objetos","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-detectar-programacao-orientada-a-objetos\/","title":{"rendered":"Widgets do WordPress: detectar programa\u00e7\u00e3o orientada a objetos"},"content":{"rendered":"\n<p>Se voc\u00ea n\u00e3o leu o primeiro post desta s\u00e9rie, eu recomendo, pois estamos come\u00e7ando a escrever c\u00f3digo orientado a objetos para WordPress atrav\u00e9s do uso da <strong><a href=\"https:\/\/developer.wordpress.org\/themes\/functionality\/widgets\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API Widgets.<\/a><\/strong><\/p>\n<p>A s\u00e9rie vai capturar algumas coisas:<\/p>\n<ol>\n<li>mostrar o esqueleto b\u00e1sico de um widget e por que ele \u00e9 orientado a objetos,<\/li>\n<li>discutir quais coisas voc\u00ea deve ser capaz de perceber e por que<\/li>\n<li>atualize o Widget Boilerplate diretamente neste site primeiro e depois envie-o para o GitHub,<\/li>\n<li>construir um widget usando a API com o clich\u00ea como base para nosso trabalho.<\/li>\n<\/ol>\n<p>Mas antes de fazer isso, eu quero ter certeza de que todos que est\u00e3o lendo isso est\u00e3o a par dos princ\u00edpios b\u00e1sicos da programa\u00e7\u00e3o orientada a objetos e t\u00eam tudo o que \u00e9 necess\u00e1rio para construir uma solu\u00e7\u00e3o orientada a objetos para WordPress.<\/p>\n<p>Para isso, recomendo o seguinte:<\/p>\n<ol>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/os-dois-primeiros-pilares-da-poo\/\" title=\"Dois Pilares da Programa\u00e7\u00e3o Orientada a Objetos: Parte 1 de 2\">Dois Pilares da Programa\u00e7\u00e3o Orientada a Objetos: Parte 1 de 2<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/os-segundos-dois-pilares-da-poo\/\" title=\"Dois Pilares da Programa\u00e7\u00e3o Orientada a Objetos: Parte 2 de 2\">Dois Pilares da Programa\u00e7\u00e3o Orientada a Objetos: Parte 2 de 2<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/aulas-de-resumo-parte-1-comportamento-de-abstracao\/\" title=\"Aulas de Resumo, Parte 1 - Comportamento de Abstra\u00e7\u00e3o\">Aulas de Resumo, Parte 1 &#8211; Comportamento de Abstra\u00e7\u00e3o<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/classes-abstratas-parte-2-classes-abstratas-e-interfaces\/\" title=\"Classes Abstratas, Parte 2 - Classes Abstratas e Interfaces\">Classes Abstratas, Parte 2 &#8211; Classes Abstratas e Interfaces<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/tommcfarlin.com\/tag\/the-independent-wordpress-developer\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">O desenvolvedor independente do WordPress<\/a><\/strong><\/li>\n<\/ol>\n<p>Se voc\u00ea leu todo esse conte\u00fado, \u00f3timo. Voc\u00ea estar\u00e1 bem preparado para este post e os pr\u00f3ximos posts. Caso contr\u00e1rio, pode haver alguns buracos no resto do que voc\u00ea est\u00e1 prestes a ler, mas a ess\u00eancia do post deve ser clara o suficiente.<\/p>\n<h3>Qual \u00e9 o neg\u00f3cio, exatamente?<\/h3>\n<p>Aqui est\u00e1 a coisa: <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-uma-abordagem-orientada-a-objetos\/\" title=\"Na semana passada\">Na semana passada<\/a><\/strong>, compartilhei um pouco de c\u00f3digo junto com algumas informa\u00e7\u00f5es sobre a <strong><a href=\"https:\/\/developer.wordpress.org\/themes\/functionality\/widgets\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de Widgets<\/a><\/strong>. Vou revisitar isso um pouco mais neste post antes de entrarmos na parte mais intensiva de codifica\u00e7\u00e3o por dois motivos:<\/p>\n<ol>\n<li>Eu quero que todos lendo isso estejam na mesma p\u00e1gina no que se refere \u00e0 escrita de c\u00f3digo orientado a objetos (no m\u00ednimo, neste contexto),<\/li>\n<li>Reconhe\u00e7o que as pessoas v\u00eam de diferentes origens e quero ter certeza de que estamos todos na mesma p\u00e1gina o m\u00e1ximo poss\u00edvel antes de prosseguir.<\/li>\n<\/ol>\n<p>Se voc\u00ea tem experi\u00eancia em escrever c\u00f3digo orientado a objetos, especialmente em uma capacidade avan\u00e7ada, isso pode parecer mais simples para voc\u00ea; caso contr\u00e1rio, espero que isso o arme com tudo o que voc\u00ea precisa para detectar pr\u00e1ticas orientadas a objetos n\u00e3o apenas relacionadas a essa API, mas tamb\u00e9m ao ler o c\u00f3digo de outras pessoas.<\/p>\n<h2>Como detectar a programa\u00e7\u00e3o orientada a objetos<\/h2>\n<p>Talvez uma primeira pergunta natural seja por que precisamos ser capazes de detectar, ler ou entender a programa\u00e7\u00e3o orientada a objetos antes de realmente escrev\u00ea-la?<\/p>\n<h3>Uma palavra sobre c\u00f3digo ruim<\/h3>\n<p>A resposta curta para isso \u00e9 esta:<\/p>\n<p>Voc\u00ea n\u00e3o precisa, mas eu \u00e9 \u00fatil. Se voc\u00ea for capaz de ler programa\u00e7\u00e3o orientada a objetos, ter\u00e1 uma vantagem inicial em tirar vantagem do que ela oferece como paradigma, porque ir\u00e1 desenvolver as estrat\u00e9gias e o trabalho feito por outros em outros projetos.<\/p>\n<p>Isso n\u00e3o significa que n\u00e3o vamos ler o c\u00f3digo ruim, mas faremos o que pudermos para identificar o c\u00f3digo ruim, identificar as \u00e1reas problem\u00e1ticas e ent\u00e3o fazer o que pudermos para evitar incorpor\u00e1-lo ao nosso trabalho.<\/p>\n<p>Por enquanto, por\u00e9m, vamos dar uma olhada na <strong><a href=\"https:\/\/developer.wordpress.org\/themes\/functionality\/widgets\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API Widgets<\/a><\/strong> para ver o que podemos fazer para detectar a programa\u00e7\u00e3o orientada a objetos.<\/p>\n<h3>De volta \u00e0 programa\u00e7\u00e3o orientada a objetos<\/h3>\n<p>No post anterior, descrevi duas coisas que indicam que a API \u00e9 orientada a objetos (pelo menos at\u00e9 certo ponto):<\/p>\n<ol>\n<li>o uso da palavra-chave <strong>extends ,<\/strong><\/li>\n<li>fun\u00e7\u00f5es que devemos implementar.<\/li>\n<\/ol>\n<p>A raz\u00e3o pela qual quero revisitar este t\u00f3pico \u00e9 que ele identifica duas coisas principais que fazem parte dos princ\u00edpios b\u00e1sicos da orienta\u00e7\u00e3o a objetos: <strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.inheritance.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Heran\u00e7a<\/a><\/strong> e implementa\u00e7\u00e3o de fun\u00e7\u00e3o (que geralmente faz parte de <strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.abstract.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">classes abstratas<\/a><\/strong> ).<\/p>\n<p>Uma nota antes de olharmos para o acima:<\/p>\n<p>Quando voc\u00ea olhar para <strong><a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">a fonte da classe WP_Widget<\/a><\/strong>, voc\u00ea notar\u00e1 que n\u00e3o existem m\u00e9todos abstratos. Mas algumas das fun\u00e7\u00f5es que devemos implementar, que mencionarei mais adiante neste post, s\u00e3o as principais candidatas a m\u00e9todos abstratos. E vou discutir o porqu\u00ea, tamb\u00e9m.<\/p>\n<p>Vamos separar os t\u00f3picos acima em duas se\u00e7\u00f5es separadas: Heran\u00e7a e Abstra\u00e7\u00f5es.<\/p>\n<h3>Heran\u00e7a<\/h3>\n<p>Eu abordei heran\u00e7a \u00e9 profundidade relativa <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-uma-abordagem-orientada-a-objetos\/\" title=\"no post anterior\">no post anterior<\/a><\/strong>, ent\u00e3o n\u00e3o vou detalhar o ponto aqui. Vou oferecer algumas palavras, mas estou muito mais interessado em discutir a abstra\u00e7\u00e3o, o que farei em um momento.<\/p>\n<p>Antes de ir muito longe nisso, por\u00e9m, consulte <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/ea73655b0a022d65317529930cbb0cad#file-00-widget-base-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o seguinte c\u00f3digo:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nclass AcmeWidget extends WP_Widget \n{ \n    public function __construct() \n    {\n    }\n\n    public function widget($args, $instance) \n    {\n    }\n\n    public function form($instance)\n    {\n    }\n\n    public function update($newInstance, $oldInstance)\n    {\n    }\n}<\/code><\/pre>\n<p>Mas primeiro, podemos reconhecer que qualquer classe que implemente a API Widgets deve usar heran\u00e7a simplesmente por causa da palavra-chave <strong>extends<\/strong>.<\/p>\n<p>Isso significa que h\u00e1 um n\u00edvel de funcionalidade que vamos herdar (ou obter de gra\u00e7a) e h\u00e1 um n\u00edvel de funcionalidade que devemos implementar por conta pr\u00f3pria.<\/p>\n<p>Do <strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.inheritance.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">manual do PHP<\/a><\/strong> :<\/p>\n<blockquote>\n<p>Por exemplo, quando voc\u00ea estende uma classe, a subclasse herda todos os m\u00e9todos p\u00fablicos e protegidos da classe pai. A menos que uma classe substitua esses m\u00e9todos, eles manter\u00e3o sua funcionalidade original.<\/p>\n<\/blockquote>\n<p>Quando voc\u00ea herda a funcionalidade de uma classe, no entanto, voc\u00ea pode descobrir que \u00e9 importante chamar estritamente o construtor do pai (em nossa fun\u00e7\u00e3o <strong>__construct<\/strong> ).<\/p>\n<p>Mas isso levanta o que acredito ser um dos problemas mais importantes com heran\u00e7a em PHP (e toda a raz\u00e3o pela qual eu queria incluir esta se\u00e7\u00e3o): precisamos chamar o construtor pai explicitamente?<\/p>\n<p>Ainda de acordo com <strong><a href=\"http:\/\/www.php.net\/manual\/en\/language.oop5.decon.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o manual:<\/a><\/strong><\/p>\n<blockquote>\n<p>Os construtores pai n\u00e3o s\u00e3o chamados implicitamente se a classe filho definir um construtor. Para executar um construtor pai, \u00e9 necess\u00e1ria uma chamada para <strong>parent::__construct()<\/strong> dentro do construtor filho. Se o filho n\u00e3o definir um construtor, ent\u00e3o ele pode ser herdado da classe pai como um m\u00e9todo de classe normal (se n\u00e3o foi declarado como privado).<\/p>\n<\/blockquote>\n<p>Mas podemos simplificar isso. Talvez isso seja mais f\u00e1cil de lembrar:<\/p>\n<ol>\n<li>Se nossa classe usa heran\u00e7a, mas n\u00e3o define um construtor, o construtor pai \u00e9 chamado.<\/li>\n<li>Se nossa classe usa heran\u00e7a, mas define um construtor, a constru\u00e7\u00e3o pai deve ser chamada explicitamente.<\/li>\n<\/ol>\n<p>Ou talvez ainda mais simplesmente:<\/p>\n<ul>\n<li>Se nossa classe n\u00e3o definir um construtor, o c\u00f3digo padr\u00e3o ser\u00e1 o construtor dos pais.<\/li>\n<\/ul>\n<p>Faz sentido? Resumindo, se definirmos nossas propriedades, inicializa\u00e7\u00e3o e c\u00f3digo em um construtor, a primeira linha do construtor de nossa classe deve ser uma chamada para o construtor pai.<\/p>\n<h3>Abstra\u00e7\u00e3o<\/h3>\n<p>Para ser absolutamente claro, o c\u00f3digo-fonte da classe <strong>WP_Widget<\/strong> n\u00e3o inclui m\u00e9todos abstratos. Parte disso tem a ver com como a classe \u00e9 constru\u00edda, parte disso tem a ver com compatibilidade com vers\u00f5es anteriores e recursos do PHP5.<\/p>\n<p>Isso n\u00e3o significa que n\u00e3o podemos identificar quais fun\u00e7\u00f5es podem ser marcadas como <strong>abstract<\/strong>. Na verdade, acho que \u00e9 um caso sobre quais classes devem ser abstratas. Mas primeiro, vamos definir fun\u00e7\u00f5es abstratas.<\/p>\n<p><strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.abstract.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Do manual<\/a><\/strong> :<\/p>\n<blockquote>\n<p>Ao herdar de uma classe abstrata, todos os m\u00e9todos marcados como abstratos na declara\u00e7\u00e3o de classe do pai devem ser definidos pelo filho; al\u00e9m disso, esses m\u00e9todos devem ser definidos com a mesma (ou menos restrita) visibilidade.<\/p>\n<\/blockquote>\n<p>Ao olhar para a fonte do nosso widget:<\/p>\n<pre><code>&lt;?php\nclass AcmeWidget extends WP_Widget \n{ \n    public function __construct() \n    {\n    }\n\n    public function widget($args, $instance) \n    {\n    }\n\n    public function form($instance)\n    {\n    }\n\n    public function update($newInstance, $oldInstance)\n    {\n    }\n}<\/code><\/pre>\n<p>Acho que \u00e9 justo dizer que a fun\u00e7\u00e3o de <strong>formul\u00e1rio<\/strong> pode ser marcada como <strong>abstrata<\/strong> porque \u00e9 exclusiva da nossa implementa\u00e7\u00e3o. Outra maneira de pensar sobre fun\u00e7\u00f5es abstratas do ponto de vista da programa\u00e7\u00e3o \u00e9 perguntar a si mesmo: quais fun\u00e7\u00f5es exigir\u00e3o uma funcionalidade exclusiva?<\/p>\n<p>E neste caso, a fun\u00e7\u00e3o de <strong>formul\u00e1rio<\/strong> \u00e9 exatamente isso porque cada widget ser\u00e1 exclusivamente diferente em rela\u00e7\u00e3o ao que ele renderiza. A fun\u00e7\u00e3o de <strong>widget<\/strong> tamb\u00e9m pode ser marcada como abstrata porque gera o conte\u00fado do widget. Este conte\u00fado \u00e9, naturalmente, baseado na funcionalidade que implementamos em nossa implementa\u00e7\u00e3o.<\/p>\n<p>Al\u00e9m disso, o c\u00f3digo-fonte da pr\u00f3pria classe <strong>WP_Widget<\/strong> diz:<\/p>\n<blockquote>\n<p>A fun\u00e7\u00e3o WP_Widget::widget() deve ser substitu\u00edda em uma subclasse.&#8217;<\/p>\n<\/blockquote>\n<p>Este \u00e9 precisamente o tipo de fun\u00e7\u00e3o que deve ser marcada como abstrata. Porque o PHP lan\u00e7ar\u00e1 um erro se uma fun\u00e7\u00e3o for marcada como abstrata e n\u00e3o implementada. N\u00e3o precis\u00e1vamos de nenhuma chamada de fun\u00e7\u00e3o <strong>die<\/strong> ou algo assim.<\/p>\n<p>As outras fun\u00e7\u00f5es, no entanto, n\u00e3o precisar\u00e3o necessariamente ser marcadas como abstratas e aqui est\u00e1 o porqu\u00ea:<\/p>\n<ol>\n<li><strong>__construct<\/strong> chamar\u00e1 o construtor do pai, no n\u00edvel mais b\u00e1sico, e isso \u00e9 necess\u00e1rio para inicializar a classe base. N\u00e3o se esque\u00e7a, por\u00e9m; podemos adicionar nossas propriedades a esse m\u00e9todo que s\u00e3o exclusivas de nossa classe.<\/li>\n<li><strong>update\u00a0<\/strong> usa a funcionalidade na classe pai para serializar informa\u00e7\u00f5es.<\/li>\n<\/ol>\n<p>Assim, ficamos com duas fun\u00e7\u00f5es que poderiam ser marcadas como abstratas em uma itera\u00e7\u00e3o mais moderna da classe.<\/p>\n<h2>Pr\u00f3ximo<\/h2>\n<p>Neste ponto, todos n\u00f3s devemos estar na mesma p\u00e1gina no que se refere ao c\u00f3digo orientado a objetos. Pelo menos at\u00e9 onde podemos chegar atrav\u00e9s de uma s\u00e9rie de postagens no blog.<\/p>\n<p>A partir do pr\u00f3ximo post, vamos voltar a escrever c\u00f3digo.<\/p>\n<p>Ou seja, vamos revisitar o <strong><a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress Widget Boilerplate<\/a><\/strong> e vou refator\u00e1-lo em seu estado atual para adotar padr\u00f5es PHP mais modernos.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161697-61e7280e064dc.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161697-61e7280e064dc.png\" alt=\"Widgets do WordPress: detectar programa\u00e7\u00e3o orientada a objetos\"><\/a><\/p>\n<p>Vou compartilhar as mudan\u00e7as que estou fazendo, as justificativas do porqu\u00ea, e depois tamb\u00e9m falarei sobre o tipo de widget que vamos construir com base no clich\u00ea (e podemos fazer isso).<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>O objetivo \u00e9 armar voc\u00ea com tudo que voc\u00ea precisa para detectar pr\u00e1ticas orientadas a objetos tanto nesta API quanto em outras.<\/p>\n","protected":false},"author":1,"featured_media":235594,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,722,806,867],"tags":[1170],"class_list":["post-231154","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-php-8","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=231154"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231154\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/235594"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=231154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=231154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=231154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}