{"id":230528,"date":"2022-12-08T17:04:00","date_gmt":"2022-12-08T14:04:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230528"},"modified":"2022-12-07T11:56:28","modified_gmt":"2022-12-07T08:56:28","slug":"apunte-a-dividir-los-programas-en-componentes-mas-pequenos","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/apunte-a-dividir-los-programas-en-componentes-mas-pequenos\/","title":{"rendered":"Apunte a dividir los programas en componentes m\u00e1s peque\u00f1os"},"content":{"rendered":"\n<p>Una de las cosas de las que los programadores suelen hablar es el deseo de dividir los programas en componentes o funciones m\u00e1s peque\u00f1os, para que sea m\u00e1s f\u00e1cil de rastrear, leer y depurar.<\/p>\n<p>Pero no es tan raro ver funciones monol\u00edticas con muchos comentarios de c\u00f3digo para ayudar a explicar lo que est\u00e1 pasando en el programa.<\/p>\n<p>No estoy criticando esto, realmente, porque no conozco las restricciones bajo las cuales trabajaba un programador. Eso es:<\/p>\n<ul>\n<li>\u00bfCu\u00e1l fue el presupuesto que ten\u00eda al construir el programa?<\/li>\n<li>\u00bfCu\u00e1nto tiempo se dio para completar el proyecto?<\/li>\n<li>\u00bfHab\u00eda mucha gente trabajando en el proyecto?<\/li>\n<li>\u00bfSe le dio tiempo al programador para escribir el c\u00f3digo para que pudiera probarlo unitariamente, refactorizarlo o simplemente hacerlo m\u00e1s f\u00e1cil de leer?<\/li>\n<\/ul>\n<p>En resumen, hay muchas razones, creo, por las que podemos leer &quot;c\u00f3digo incorrecto&quot;, y no siempre tiene que ser culpa del programador (eso es lo m\u00e1s natural que tenemos que descartar cuando leemos algo que no nos gusta).<\/p>\n<p>Sin embargo, \u00bfsignifica esto que no debemos esforzarnos por refactorizar o escribir c\u00f3digo de tal manera que sea m\u00e1s f\u00e1cil de entender? Por supuesto que no. Suponiendo que tenemos el tiempo para hacerlo, \u00bfc\u00f3mo podr\u00edamos hacerlo?<\/p>\n<h2>Divida los programas en componentes m\u00e1s peque\u00f1os<\/h2>\n<p>Cuando se trata de escribir sobre un tema como este, especialmente en una econom\u00eda tan activa como el comercio electr\u00f3nico en WordPress, puede ser un desaf\u00edo.<\/p>\n<h3>\u00abSeamos espec\u00edficos, Bob&quot;.<\/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>Es decir, puedo escribir sobre ello a un nivel muy detallado utilizando un conjunto de complementos, observando los datos, diseccionando consultas y mostrando c\u00f3mo hacerlo. O puedo escribirlo a un nivel ligeramente superior con el objetivo final de mostrar c\u00f3mo dividir los programas en componentes m\u00e1s peque\u00f1os.<\/p>\n<p>Debido a que hay tantas formas en que se puede lograr lo primero, estoy optando por lo segundo. Es decir, esto no necesariamente usar\u00e1 complementos espec\u00edficos, son consultas directas. Sin embargo, utilizar\u00e1 ejemplos de alto nivel para ayudarlo a recorrer lo que podr\u00eda ser una serie de consultas y bucles y dividirlos en funciones m\u00e1s peque\u00f1as.<\/p>\n<h3>Un ejemplo gen\u00e9rico<\/h3>\n<p>Por ejemplo, supongamos que estoy trabajando en una caracter\u00edstica de un complemento de WordPress cuyo objetivo final es recuperar todos los diversos m\u00e9todos de pago que un usuario ha almacenado y que est\u00e1n relacionados con su cuenta.<\/p>\n<p>El desaf\u00edo es que esta informaci\u00f3n est\u00e1 dispersa en varias tablas de la base de datos (debido a los diversos complementos que se utilizan), por lo que hay algunas consultas que deben ejecutarse y luego recuperarse.<\/p>\n<p>Los pasos para hacer tales consultas podr\u00edan ser algo como esto:<\/p>\n<ol>\n<li>obtener el ID de cliente del usuario actual,<\/li>\n<li>obtener todos los n\u00fameros de identificaci\u00f3n del pedido del cliente<\/li>\n<li>determinar qu\u00e9 m\u00e9todos de pago se utilizaron para cada pedido<\/li>\n<li>recuperar dichos m\u00e9todos de pago y luego enviar la informaci\u00f3n al cliente<\/li>\n<\/ol>\n<p>Seg\u00fan c\u00f3mo est\u00e9 configurada la base de datos, seg\u00fan su nivel de destreza en SQL y seg\u00fan c\u00f3mo funcionen en conjunto los diversos complementos para manejar todos los datos anteriores, puede ser f\u00e1cil escribir una consulta grande para recuperar esta informaci\u00f3n.<\/p>\n<p>Pero si ha trabajado con comercio electr\u00f3nico en WordPress y varios complementos, sabe que no siempre es tan f\u00e1cil.<\/p>\n<p>En cambio, est\u00e1s viendo algo como:<\/p>\n<ol>\n<li>necesitamos obtener el perfil de un cliente de los metadatos del usuario,<\/li>\n<li>necesitamos encontrar todos los pedidos que ha realizado el usuario, y esto a menudo se puede asociar con la publicaci\u00f3n o la tabla de metadatos de la publicaci\u00f3n,<\/li>\n<li>los m\u00e9todos de pago muy probablemente pueden almacenarse en su tabla asociada al usuario a trav\u00e9s de alg\u00fan tipo de token,<\/li>\n<li>el token anterior se encuentra en una tabla y est\u00e1 relacionado con una informaci\u00f3n determinada en otra tabla de la que luego debe deducir al observar los datos que existen en toda la base de datos.<\/li>\n<\/ol>\n<p>En \u00faltima instancia, debe crear un conjunto de consultas solo al comprender primero c\u00f3mo consultar los datos que est\u00e1 buscando. Ya es bastante desafiante. Pero cuando pueda hacer eso, digamos que est\u00e1 escribiendo sus consultas secuencialmente y luego usando los resultados de cada una para obtener el resultado deseado.<\/p>\n<p>Esto puede resultar en <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/7c0c8b50cd361f22b5f777544adc2204#file-00-monolithic-queries-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">algo como esto<\/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>Pero no tiene por qu\u00e9 ser as\u00ed.<\/p>\n<p>En primer lugar, todas estas son consultas independientes con conjuntos de resultados independientes, aunque deben usarse en conjunto. Esto significa que podemos separarlos y evaluar los resultados de cada uno antes de continuar con el siguiente paso.<\/p>\n<p>Adem\u00e1s, nos permite escribir funciones m\u00e1s peque\u00f1as y m\u00e1s cohesivas. Aunque pueden depender unos de otros, podemos configurar cada funci\u00f3n para que acepte un argumento (o un conjunto de argumentos de los que podemos recuperar toda la informaci\u00f3n).<\/p>\n<p>Quiz\u00e1s el resultado final sea 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\">como esto<\/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>Por supuesto, no puedo mostrar ning\u00fan SQL real, bueno, al menos no en todas partes, porque no conozco la configuraci\u00f3n general ni s\u00e9 exactamente qu\u00e9 complementos o esquemas son con los que est\u00e1 trabajando.<\/p>\n<p>Pero ese nunca ha sido el punto de esta publicaci\u00f3n.<\/p>\n<p>En cambio, el punto final que estoy tratando de transmitir es este: aunque podemos estar trabajando bajo restricciones muy limitadas, a\u00fan podemos dividir los programas en componentes m\u00e1s peque\u00f1os que nos ayuden a describir lo que est\u00e1 sucediendo, comprender c\u00f3mo se hace y luego enviar datos de ida y vuelta entre varias funciones y hacia y desde el usuario.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Una de las cosas de las que los programadores suelen hablar es el deseo de dividir los programas en componentes o funciones m\u00e1s peque\u00f1os, para que sea m\u00e1s f\u00e1cil de rastrear, leer y 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":[892,716,800],"tags":[1172],"class_list":["post-230528","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-desarrollador","category-php-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230528","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230528"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230528\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236233"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230528"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230528"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230528"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}