{"id":232009,"date":"2023-01-04T13:25:00","date_gmt":"2023-01-04T10:25:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=232009"},"modified":"2023-01-04T13:25:05","modified_gmt":"2023-01-04T10:25:05","slug":"desacoplamento-da-logica-de-dominio-no-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/desacoplamento-da-logica-de-dominio-no-wordpress\/","title":{"rendered":"Desacoplamento da l\u00f3gica de dom\u00ednio no WordPress"},"content":{"rendered":"\n<p>Lembre-se de que o WordPress usa o <a href=\"https:\/\/en.wikipedia.org\/wiki\/Event-driven_architecture\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">padr\u00e3o de design orientado a eventos<\/a> e, embora muitas vezes nos refiramos a a\u00e7\u00f5es e filtros, o conceito se resume a ganchos. O fluxo de controle atrav\u00e9s do programa \u00e9 mais ou menos assim:<\/p>\n<ol>\n<li>Executar o programa,<\/li>\n<li>Sempre que o programa encontrar um gancho (no WordPress, veremos <code>do_action<\/code>ou <code>apply_filters<\/code>), fa\u00e7a uma itera\u00e7\u00e3o por todos os ganchos registrados,<\/li>\n<li>Retorne o controle de volta ao programa,<\/li>\n<li>Executar at\u00e9 o final.<\/li>\n<\/ol>\n<p>Isso n\u00e3o \u00e9 completamente diferente do padr\u00e3o Publisher\/Subscriber (ou <a href=\"https:\/\/en.wikipedia.org\/wiki\/Publish%E2%80%93subscribe_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">PubSub<\/a>, para abreviar), mas h\u00e1 uma diferen\u00e7a fundamental: o padr\u00e3o orientado a eventos simplesmente sinaliza que algo aconteceu e, se houver ganchos, eles ser\u00e3o acionados. O padr\u00e3o PubSub dir\u00e1 a um assinante registrado para fazer algo.<\/p>\n<p>De qualquer forma, de volta aos ganchos no WordPress. Manter os dois conceitos de ganchos que temos pode ser feito mais facilmente pensando neles assim:<\/p>\n<ul>\n<li>A\u00e7\u00f5es s\u00e3o para fazer algo,<\/li>\n<li>Os filtros s\u00e3o para processar dados.<\/li>\n<\/ul>\n<p>Se voc\u00ea deseja abordar o desenvolvimento do WordPress de maneira orientada a objetos, n\u00e3o \u00e9 uma boa ideia acoplar seu c\u00f3digo ao n\u00facleo do WordPress registrando suas classes por meio de ganchos no aplicativo principal.<\/p>\n<p>Em outras palavras, n\u00e3o registre sua l\u00f3gica de neg\u00f3cios no WordPress. Mantenha-os separados. Aqui est\u00e1 um teste decisivo para saber se seu trabalho est\u00e1 fortemente acoplado ao WordPress: Se voc\u00ea n\u00e3o pode executar um teste de unidade em sua classe sem carregar o WordPress, ele est\u00e1 fortemente acoplado.<\/p>\n<p>Ent\u00e3o, qual \u00e9 a solu\u00e7\u00e3o? Delega\u00e7\u00e3o.<\/p>\n<h2>L\u00f3gica de dom\u00ednio no WordPress<\/h2>\n<p>A l\u00f3gica de dom\u00ednio e a l\u00f3gica de neg\u00f3cios s\u00e3o intercambi\u00e1veis \u200b\u200bno que me diz respeito, ent\u00e3o se voc\u00ea leu posts anteriores sobre isso e eu falei sobre eles de maneiras diferentes, voc\u00ea sabe por qu\u00ea.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-158738-61e6e493ec777.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-158738-61e6e493ec777.png\" alt=\"Desacoplamento da l\u00f3gica de dom\u00ednio no WordPress\"><\/a><\/p>\n<p><a href=\"https:\/\/unsplash.com\/photos\/guiQYiRxkZY\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Cr\u00e9dito<\/a><\/p>\n<p>Em seguida, a ideia de delegar l\u00f3gica do WordPress para uma classe de l\u00f3gica de dom\u00ednio no WordPress \u00e9 feita por uma classe intermedi\u00e1ria que \u00e9 respons\u00e1vel pelo seguinte:<\/p>\n<ol>\n<li>Inscrevendo-se em um gancho,<\/li>\n<li>Delegar o trabalho a uma classe.<\/li>\n<\/ol>\n<p>Eu sei que as classes devem fazer &#8220;uma coisa bem&quot;, mas e se essa coisa for delega\u00e7\u00e3o?<\/p>\n<blockquote>\n<p>comprometer (poderes, fun\u00e7\u00f5es, etc.) a outro como agente<\/p>\n<p><a href=\"https:\/\/www.dictionary.com\/browse\/delegate\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o dicion\u00e1rio<\/a><\/p>\n<\/blockquote>\n<p>E para comprometer a funcionalidade adequadamente com outro agente ou, no nosso caso, uma classe, voc\u00ea precisa saber o que est\u00e1 delegando. \u00c0s vezes, para fazer uma coisa, voc\u00ea precisa saber v\u00e1rias informa\u00e7\u00f5es.<\/p>\n<p>Ent\u00e3o, como isso se parece praticamente falando? Imagine que voc\u00ea tenha um <code>[AbstractSubscriber](https:\/\/github.com\/tommcfarlin\/remove-empty-shortcodes\/blob\/master\/src\/Subscriber\/AbstractSubscriber.php)<\/code>to para levar o nome de um gancho em seu construtor:<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of Remove Empty Shortcodes.\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace TomMcFarlinRESCSubscriber;\n\nuse TomMcFarlinUtilitiesRegistry;\n\n\/**\n * An abstract implementation of a subscriber that requires a hook and the ability to\n * start the class.\n *\/\nabstract class AbstractSubscriber\n{\n    \/**\n     * @var string a reference to the hook to which the subscriber should be registered\n     *\/\n    protected $hook;\n\n    \/**\n     * @var Registry a reference to the simple container used to maintain plugin objects\n     *\/\n    protected $registry;\n\n    \/**\n     * @param string $hook the hook to which the subscriber is registered\n     *\/\n    public function __construct(string $hook)\n    {\n        $this-&gt;hook = $hook;\n        $this-&gt;registry = apply_filters('rescRegistry', null);\n    }\n\n    \/**\n     * @return string the hook to which the subscriber is registered\n     *\/\n    public function getHook(): string\n    {\n        return $this-&gt;hook;\n    }\n\n    abstract public function load();\n}<\/code><\/pre>\n<p>E ent\u00e3o, uma vez feito, a <code>load<\/code>fun\u00e7\u00e3o enviar\u00e1 o trabalho para uma classe respons\u00e1vel por realmente fazer o processamento.<\/p>\n<p>Veja, por exemplo, <a href=\"https:\/\/github.com\/tommcfarlin\/remove-empty-shortcodes\/blob\/master\/src\/WordPress\/PostContentProcessor.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">este c\u00f3digo<\/a> de <a href=\"https:\/\/github.com\/tommcfarlin\/remove-empty-shortcodes\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Remove Empty Shortcodes<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of Remove Empty Shortcodes.\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace TomMcFarlinRESCWordPress;\n\n\/**\n * Processes the post content by looking to see if any orphaned shortcode\n * exists and then removes it from displaying it from the user.\n *\/\nclass PostContentProcessor\n{\n    \/**\n     * A reference to the Shortcode Manager for processing orphaned shortcodes.\n     *\/\n    private $shortcodeManager;\n\n    \/**\n     * Initializes the class by setting up a reference to the Registry and the\n     * Shortcode Manager.\n     *\/\n    public function __construct()\n    {\n        $registry = apply_filters('rescRegistry', null);\n        $this-&gt;shortcodeManager = $registry-&gt;get('shortcodeManager');\n    }\n\n    \/**\n     * @param string $content the filtered post content\n     *\n     * @return string $content the filtered post content without the shortcode\n     *\/\n    public function run(string $content): string\n    {\n        return $this-&gt;shortcodeManager-&gt;processShortcodes($content);\n    }\n}<\/code><\/pre>\n<p>Uma classe se inscreve em um evento espec\u00edfico, como <code>[the_content](https:\/\/developer.wordpress.org\/reference\/functions\/the_content\/)<\/code>, e depois delega o trabalho para a classe de processamento de conte\u00fado posterior.<\/p>\n<p>Isso literalmente permite que o arquivo bootstrap do plugin instancie o delegado. O delegado ent\u00e3o se conecta ao WordPress e quando o WordPress chega ao ponto adequado de execu\u00e7\u00e3o, o delegado envia a responsabilidade para a classe respons\u00e1vel por process\u00e1-lo.<\/p>\n<p>Toda essa arquitetura n\u00e3o \u00e9 apenas completamente reutiliz\u00e1vel (veja o uso de uma classe abstrata acima), mas nos permite desacoplar a l\u00f3gica de dom\u00ednio do WordPress e test\u00e1-la isoladamente.<\/p>\n<h2>Mais sobre separa\u00e7\u00e3o de interesses<\/h2>\n<p>Eu escrevi alguns outros posts sobre separa\u00e7\u00e3o de interesses:<\/p>\n<ul>\n<li><a href=\"https:\/\/tommcfarlin.com\/separation-of-concerns-with-wordpress-templates\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Separa\u00e7\u00e3o de preocupa\u00e7\u00f5es com modelos WordPress<\/a><\/li>\n<li><a href=\"https:\/\/tommcfarlin.com\/separation-of-concerns-with-queries-and-helper-functions\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Separa\u00e7\u00e3o de preocupa\u00e7\u00f5es com consultas e fun\u00e7\u00f5es auxiliares<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/programacao-wordpress-separando-preocupacoes\/\" title=\"Programa\u00e7\u00e3o WordPress: Separando Preocupa\u00e7\u00f5es\">Programa\u00e7\u00e3o WordPress: Separando Preocupa\u00e7\u00f5es<\/a><\/li>\n<\/ul>\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>Lembre-se de que o WordPress usa o padr\u00e3o de design orientado a eventos e, embora muitas vezes nos refiramos a a\u00e7\u00f5es e filtros, o conceito se resume a ganchos. O fluxo de controle atrav\u00e9s do programa \u00e9 algo\u2026<\/p>\n","protected":false},"author":1,"featured_media":158739,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,722,837,920,846,867],"tags":[1170],"class_list":["post-232009","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-guia-para-iniciantes","category-outro","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/232009","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=232009"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/232009\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/158739"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=232009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=232009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=232009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}