{"id":230914,"date":"2022-12-08T17:03:00","date_gmt":"2022-12-08T14:03:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230914"},"modified":"2022-12-07T11:56:34","modified_gmt":"2022-12-07T08:56:34","slug":"objetivo-de-quebrar-programas-em-componentes-menores","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/objetivo-de-quebrar-programas-em-componentes-menores\/","title":{"rendered":"Objetivo de quebrar programas em componentes menores"},"content":{"rendered":"\n<p>Uma das coisas sobre as quais os programadores costumam falar \u00e9 o desejo de dividir os programas em componentes menores, ou fun\u00e7\u00f5es, para torn\u00e1-los mais f\u00e1ceis de rastrear, ler e depurar.<\/p>\n<p>Mas n\u00e3o \u00e9 t\u00e3o incomum ver fun\u00e7\u00f5es monol\u00edticas com muitos coment\u00e1rios de c\u00f3digo para ajudar a explicar o que est\u00e1 acontecendo no programa.<\/p>\n<p>Eu n\u00e3o estou criticando isso, realmente, porque eu n\u00e3o conhe\u00e7o as restri\u00e7\u00f5es sob as quais um programador estava trabalhando. Aquilo \u00e9:<\/p>\n<ul>\n<li>Qual era o or\u00e7amento que ele\/ela tinha ao construir o programa?<\/li>\n<li>Quanto tempo foi dado para concluir o projeto?<\/li>\n<li>Havia muitas pessoas trabalhando no projeto?<\/li>\n<li>O programador teve tempo para escrever o c\u00f3digo para que pudesse test\u00e1-lo, refator\u00e1-lo ou simplesmente torn\u00e1-lo mais f\u00e1cil de ler?<\/li>\n<\/ul>\n<p>Resumindo, h\u00e1 muitas raz\u00f5es \u2013 acredito \u2013 para que possamos ler &#8220;c\u00f3digos ruins&quot;, e nem sempre tem que ser culpa do programador (essa \u00e9 a coisa mais natural que temos que jogar fora quando lemos algo que n\u00e3o gostamos).<\/p>\n<p>Isso significa, por\u00e9m, que n\u00e3o devemos nos esfor\u00e7ar para refatorar ou escrever c\u00f3digo de tal forma que o torne mais f\u00e1cil de entender? Claro que n\u00e3o. Supondo que tenhamos tempo para faz\u00ea-lo, como poder\u00edamos faz\u00ea-lo?<\/p>\n<h2>Divida os programas em componentes menores<\/h2>\n<p>Quando se trata de escrever sobre um t\u00f3pico como esse, especialmente em uma economia t\u00e3o ativa quanto o com\u00e9rcio eletr\u00f4nico no WordPress, pode ser um desafio.<\/p>\n<h3>&#8220;Vamos ser espec\u00edficos, Bob.&#8221;<\/h3>\n<div class=\"sds-iframe-wrapper fitvidsignore\" style=\"position:relative;padding-top:56.25%;max-width:100%;\"><iframe allowfullscreen style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" src=\"\/\/www.youtube.com\/embed\/4M2kEiLHKhs\" frameborder=\"0\"><\/iframe><\/div>\n<p>Ou seja, posso escrever sobre isso em um n\u00edvel muito detalhado usando um conjunto de plugins, analisando os dados, dissecando consultas e mostrando como faz\u00ea-lo. Ou posso escrever sobre isso em um n\u00edvel um pouco mais alto, com o objetivo final de mostrar como dividir programas em componentes menores.<\/p>\n<p>Como h\u00e1 tantas maneiras de alcan\u00e7ar o primeiro, estou optando pelo \u00faltimo. Ou seja, isso n\u00e3o necessariamente usar\u00e1 plugins espec\u00edficos, s\u00e3o consultas diretas. No entanto, ele usar\u00e1 exemplos de alto n\u00edvel para ajud\u00e1-lo a percorrer o que poderia ser uma s\u00e9rie de consultas e loops e dividi-los em fun\u00e7\u00f5es menores.<\/p>\n<h3>Um exemplo gen\u00e9rico<\/h3>\n<p>Por exemplo, digamos que estou trabalhando em um recurso de um plugin do WordPress cujo objetivo final \u00e9 recuperar todos os v\u00e1rios m\u00e9todos de pagamento que um usu\u00e1rio armazenou e que est\u00e3o relacionados \u00e0 sua conta.<\/p>\n<p>O desafio \u00e9 que essas informa\u00e7\u00f5es est\u00e3o espalhadas por v\u00e1rias tabelas de banco de dados (por causa de v\u00e1rios plugins que s\u00e3o usados), ent\u00e3o h\u00e1 algumas consultas que devem ser executadas e depois recuperadas.<\/p>\n<p>As etapas para fazer essas consultas podem ser mais ou menos assim:<\/p>\n<ol>\n<li>obter o ID de cliente do usu\u00e1rio atual,<\/li>\n<li>obter todos os n\u00fameros de identifica\u00e7\u00e3o do pedido para o cliente<\/li>\n<li>determinar quais m\u00e9todos de pagamento foram usados \u200b\u200bpara cada pedido<\/li>\n<li>recuperar os referidos m\u00e9todos de pagamento e enviar a informa\u00e7\u00e3o ao cliente<\/li>\n<\/ol>\n<p>Dependendo de como o banco de dados est\u00e1 configurado, dependendo do seu n\u00edvel de proeza SQL e dependendo de como os v\u00e1rios plugins para lidar com todos os dados acima funcionam em conjunto, pode ser f\u00e1cil escrever uma consulta grande para recuperar essas informa\u00e7\u00f5es.<\/p>\n<p>Mas se voc\u00ea j\u00e1 trabalhou com com\u00e9rcio eletr\u00f4nico no WordPress e v\u00e1rios plugins, sabe que nem sempre \u00e9 t\u00e3o f\u00e1cil.<\/p>\n<p>Em vez disso, voc\u00ea est\u00e1 olhando para algo como:<\/p>\n<ol>\n<li>precisamos obter o perfil de um cliente dos metadados do usu\u00e1rio,<\/li>\n<li>precisamos encontrar todos os pedidos que o usu\u00e1rio fez, e isso geralmente pode ser associado \u00e0 postagem ou \u00e0 tabela de metadados da postagem,<\/li>\n<li>os m\u00e9todos de pagamento muito provavelmente podem ser armazenados em sua tabela associada ao usu\u00e1rio por meio de algum tipo de token,<\/li>\n<li>o token acima fica em uma tabela e est\u00e1 relacionado a uma determinada informa\u00e7\u00e3o em outra tabela da qual voc\u00ea deve deduzir observando os dados que existem em todo o banco de dados.<\/li>\n<\/ol>\n<p>Em \u00faltima an\u00e1lise, voc\u00ea precisa criar um conjunto de consultas apenas entendendo primeiro como consultar os dados que est\u00e1 procurando. Isso \u00e9 desafiador o suficiente como \u00e9. Mas quando voc\u00ea fizer isso, digamos que voc\u00ea esteja escrevendo suas consultas sequencialmente e, em seguida, usando os resultados de cada uma para obter a sa\u00edda desejada.<\/p>\n<p>Isso pode resultar em <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/7c0c8b50cd361f22b5f777544adc2204#file-00-monolithic-queries-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">algo assim<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\n\/\/ First, read the user ID and meta value to get authorization information\nglobal $wpdb;\n$results = $wpdb-&gt;get_results(\n    $wpdb-&gt;prepare(\n        \"\n        SELECT\n            user_id, meta_value\n        FROM $wpdb-&gt;usermeta\n        WHERE meta_key LIKE %s\n        AND user_id = %d\n        \",\n        '%customer_profile_id%',\n        filter_input(INPUT_GET, 'customer_id')\n    ),\n    ARRAY_A\n);\n\n$result = isset($results[0])? array_column($results[0], 'meta_value'): [];\nif (empty($result)) {\n    return $result;\n}\n\n\/\/ Get the ID of the current customer.\n$customers = $wpdb-&gt;get_results(\n    $wpdb-&gt;prepare(\n        \"\", \/\/ Your custom query goes here.\n        filter_input(INPUT_GET, 'customer_id')\n    ),\n    ARRAY_A\n);\n\n$customer = isset($customers[0])? array_column($customers[0], 'customer_id'): [];\nif (empty($customer)) {\n    return $customer;\n}\n\n\/\/ Get all of the order IDs from the set of orders returned from the previous query.\n$orderIds = $wpdb-&gt;get_results(\n    $wpdb-&gt;prepare(\n        \"\", \/\/ Your custom query goes here.\n        $customer\n    ),\n    ARRAY_A\n);\n\nreturn $orderIds;\n\n\/\/ Finally, get all of the payment methods for the orders based on their Ids.\n$orders = [];\nforeach ($orderIds as $orderId) {\n    $results = $wpdb-&gt;get_results(\n        $wpdb-&gt;prepare(\n            \"\" \/\/ The query for retrieving various payment method information based on the $orderId\n        ),\n        ARRAY_A\n    );\n\n    if (empty($results)) {\n        continue;\n    }\n\n    $orders[$orderId] = $results;\n}\n\n\/\/ Now send the information back to the user.\nwp_send_json_success($orders);\n<\/code><\/pre>\n<p>Mas n\u00e3o precisa ser assim.<\/p>\n<p>Primeiro, todas essas s\u00e3o consultas independentes com conjuntos de resultados independentes, embora tenham que ser usadas em conjunto. Isso significa que podemos separ\u00e1-los e avaliar os resultados de cada um antes de avan\u00e7ar com a pr\u00f3xima etapa.<\/p>\n<p>Al\u00e9m disso, nos permite escrever fun\u00e7\u00f5es menores e mais coesas. Mesmo que eles dependam um do outro, podemos configurar cada fun\u00e7\u00e3o para aceitar um argumento (ou conjunto de argumentos do qual podemos recuperar todas as informa\u00e7\u00f5es.<\/p>\n<p>Talvez o resultado final seja algo <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/7c0c8b50cd361f22b5f777544adc2204#file-01-breaking-apart-the-queries-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\npublic function getPaymentMethods()\n{\n  $authInfo = $this-&gt;getAuthorizationInformation();\n  $currentCustomerId = $this-&gt;getCurrentCustomerId($authInfo);\n  $orders = $this-&gt;getCustomerOrders($currentCustomerId);\n  $paymentMethods = $this-&gt;getPaymentMethodsFromOrders($orders);\n  wp_send_json_success($orders);\n}\n\nprivate function getAuthorizationInformation()\n{\n  global $wpdb;\n  $authInfo = $wpdb-&gt;get_results(\n      $wpdb-&gt;prepare(\n          \"\n          SELECT\n              user_id, meta_value\n          FROM $wpdb-&gt;usermeta\n          WHERE meta_key LIKE %s\n          AND user_id = %d\n          \",\n          '%customer_profile_id%',\n          filter_input(INPUT_GET, 'customer_id')\n      ),\n      ARRAY_A\n  );\n\n  return isset($authInfo[0])? array_column($authInfo[0], 'meta_value'): [];\n}\n\nprivate function getCurrentCustomerIdFromAuthInfo($authInfo)\n{\n  global $wpdb;\n  $customers = $wpdb-&gt;get_results(\n      $wpdb-&gt;prepare(\n          \"\", \/\/ Your custom query goes here.\n          $authInfo;\n      ),\n      ARRAY_A\n  );\n\n  return isset($customerId[0])? array_column($customerId[0], 'meta_value'): [];\n}\n\nprivate function getCustomerOrders($customerId)\n{\n  global $wpdb;\n  $orderIds = $wpdb-&gt;get_results(\n      $wpdb-&gt;prepare(\n          \"\", \/\/ Your custom query goes here.\n          $customerId\n      ),\n      ARRAY_A\n  );\n\n  return empty($orderIds)? []: $orderIds;\n}\n\nprivate function getPaymentMethodsFromOrders($orderIds)\n{\n  $paymentMethods = [];\n  foreach ($orderIds as $orderId) {\n      $results = $wpdb-&gt;get_results(\n          $wpdb-&gt;prepare(\n              \"\" \/\/ The query for retrieving various payment method information based on the $orderId\n          ),\n          ARRAY_A\n      );\n\n      if (empty($results)) {\n          continue;\n      }\n\n      $paymentMethods[$orderId] = $results;\n  }\n\n  return $paymentMethods;\n}\n<\/code><\/pre>\n<p>Claro, n\u00e3o posso mostrar nenhum SQL real \u2013 bem, pelo menos n\u00e3o em todos os lugares \u2013 porque n\u00e3o conhe\u00e7o a configura\u00e7\u00e3o geral nem sei exatamente com quais plugins ou esquemas voc\u00ea est\u00e1 trabalhando.<\/p>\n<p>Mas esse nunca foi o objetivo deste post.<\/p>\n<p>Em vez disso, o ponto final que estou tentando transmitir \u00e9 o seguinte: embora possamos estar trabalhando sob restri\u00e7\u00f5es altamente limitadas, ainda podemos dividir os programas em componentes menores que nos ajudam a descrever o que est\u00e1 acontecendo, entender como \u00e9 feito e, em seguida, enviar dados para frente e para tr\u00e1s entre v\u00e1rias fun\u00e7\u00f5es e de e para o usu\u00e1rio.<\/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>Uma das coisas sobre as quais os programadores costumam falar \u00e9 o desejo de dividir os programas em componentes menores, ou fun\u00e7\u00f5es, para torn\u00e1-los mais f\u00e1ceis de rastrear, ler e depurar.<\/p>\n","protected":false},"author":1,"featured_media":236233,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,722,806],"tags":[1170],"class_list":["post-230914","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-php-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230914","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=230914"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230914\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/236233"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}