{"id":230928,"date":"2022-12-08T17:49:00","date_gmt":"2022-12-08T14:49:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230928"},"modified":"2022-12-07T11:56:30","modified_gmt":"2022-12-07T08:56:30","slug":"pyri-jakamaan-ohjelmat-pienempiin-osiin","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/pyri-jakamaan-ohjelmat-pienempiin-osiin\/","title":{"rendered":"Pyri jakamaan ohjelmat pienempiin osiin"},"content":{"rendered":"\n<p>Yksi niist\u00e4 asioista, joista ohjelmoijat usein puhuvat, on halu jakaa ohjelmat pienempiin komponentteihin tai toimintoihin, jotta ne olisi helpompi j\u00e4ljitt\u00e4\u00e4, lukea ja virheenkorjaus helpottaa.<\/p>\n<p>Mutta ei ole kovinkaan harvinaista n\u00e4hd\u00e4 monoliittisia toimintoja, joissa on paljon koodikommentteja, jotka auttavat selitt\u00e4m\u00e4\u00e4n, mit\u00e4 ohjelmassa tapahtuu.<\/p>\n<p>En tyrm\u00e4\u00e4 t\u00e4t\u00e4, koska en tied\u00e4 rajoituksia, joiden alla ohjelmoija ty\u00f6skenteli. Tuo on:<\/p>\n<ul>\n<li>Mik\u00e4 oli h\u00e4nen budjettinsa ohjelmaa rakentaessaan?<\/li>\n<li>Kuinka paljon aikaa hankkeen loppuun saattamiseen annettiin?<\/li>\n<li>Oliko projektin parissa paljon ihmisi\u00e4?<\/li>\n<li>Annettiinko ohjelmoijalle aikaa kirjoittaa koodi, jotta he voisivat testata sen, muuttaa sen uudelleen tai vain helpottaa sen lukemista?<\/li>\n<\/ul>\n<p>Lyhyesti sanottuna, uskon, ett\u00e4 on monia syit\u00e4 siihen, ett\u00e4 voimme lukea &quot;huonoa koodia&quot;, eik\u00e4 sen aina tarvitse olla ohjelmoijan vika (se on vain luonnollisin asia, joka meid\u00e4n t\u00e4ytyy heitt\u00e4\u00e4 pois lukiessamme josta emme pid\u00e4).<\/p>\n<p>Tarkoittaako t\u00e4m\u00e4 kuitenkin sit\u00e4, ett\u00e4 meid\u00e4n ei pit\u00e4isi pyrki\u00e4 refaktoimaan tai kirjoittamaan koodia tavalla, joka helpottaa sen ymm\u00e4rt\u00e4mist\u00e4? Ei tietenk\u00e4\u00e4n. Olettaen, ett\u00e4 meill\u00e4 on aikaa tehd\u00e4 niin, miten voisimme tehd\u00e4 sen?<\/p>\n<h2>Purkaa ohjelmat pienempiin osiin<\/h2>\n<p>Kirjoittaminen t\u00e4llaisesta aiheesta voi olla haaste, etenkin taloudessa, joka on yht\u00e4 aktiivinen kuin WordPressin verkkokauppa.<\/p>\n<h3>&quot;Ollaan tarkkoja, 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>Toisin sanoen voin kirjoittaa siit\u00e4 eritt\u00e4in yksityiskohtaisesti k\u00e4ytt\u00e4m\u00e4ll\u00e4 laajennussarjaa, tarkastelemalla tietoja, analysoimalla kyselyit\u00e4 ja osoittamalla, kuinka se tehd\u00e4\u00e4n. Tai voin kirjoittaa siit\u00e4 hieman korkeammalla tasolla perimm\u00e4isen\u00e4 tavoitteena n\u00e4ytt\u00e4\u00e4, kuinka ohjelmat jaetaan pienempiin osiin.<\/p>\n<p>Koska edellinen voidaan saavuttaa niin monella tavalla, valitsen j\u00e4lkimm\u00e4isen. T\u00e4m\u00e4 tarkoittaa, ett\u00e4 t\u00e4m\u00e4 ei v\u00e4ltt\u00e4m\u00e4tt\u00e4 k\u00e4yt\u00e4 mit\u00e4\u00e4n tiettyj\u00e4 laajennuksia ovat suoria kyselyit\u00e4. Se k\u00e4ytt\u00e4\u00e4 kuitenkin korkean tason esimerkkej\u00e4, jotka auttavat sinua k\u00e4ym\u00e4\u00e4n l\u00e4pi sarjan kyselyit\u00e4 ja silmukoita ja jakamaan ne pienempiin funktioihin.<\/p>\n<h3>Yleinen esimerkki<\/h3>\n<p>Oletetaan esimerkiksi, ett\u00e4 ty\u00f6skentelen WordPress-laajennuksen ominaisuuden parissa, jonka perimm\u00e4inen tarkoitus on noutaa kaikki k\u00e4ytt\u00e4j\u00e4n tallentamat eri maksutavat, jotka liittyv\u00e4t h\u00e4nen tiliins\u00e4.<\/p>\n<p>Haasteena on, ett\u00e4 n\u00e4m\u00e4 tiedot ovat hajallaan useissa tietokantataulukoissa (k\u00e4ytett\u00e4vien eri lis\u00e4osien takia), joten on joitain kyselyj\u00e4, jotka on suoritettava ja sitten haettava.<\/p>\n<p>T\u00e4llaisten kyselyjen tekemisen vaiheet voivat menn\u00e4 suunnilleen n\u00e4in:<\/p>\n<ol>\n<li>saada nykyisen k\u00e4ytt\u00e4j\u00e4n asiakastunnus,<\/li>\n<li>saada kaikki asiakkaan tilaustunnusnumerot<\/li>\n<li>m\u00e4\u00e4ritt\u00e4\u00e4, mit\u00e4 maksutapoja kullekin tilaukselle k\u00e4ytettiin<\/li>\n<li>noutaa mainitut maksutavat ja l\u00e4hett\u00e4\u00e4 sitten asiakkaalle valmistajan tiedot<\/li>\n<\/ol>\n<p>Riippuen siit\u00e4, miten tietokanta on m\u00e4\u00e4ritetty, riippuen SQL-taitosi tasosta ja sen mukaan, kuinka kaikki edell\u00e4 mainitut tiedot k\u00e4sittelev\u00e4t eri laajennukset toimivat samanaikaisesti, voi olla helppoa kirjoittaa yksi suuri kysely n\u00e4iden tietojen hakemiseksi.<\/p>\n<p>Mutta jos olet ty\u00f6skennellyt verkkokaupan kanssa WordPressiss\u00e4 ja useissa laajennuksissa, tied\u00e4t, ett\u00e4 se ei aina ole niin helppoa.<\/p>\n<p>Sen sijaan katsot jotain, kuten:<\/p>\n<ol>\n<li>meid\u00e4n on saatava asiakkaan profiili k\u00e4ytt\u00e4j\u00e4n metatiedoista,<\/li>\n<li>meid\u00e4n on l\u00f6ydett\u00e4v\u00e4 kaikki k\u00e4ytt\u00e4j\u00e4n tekem\u00e4t tilaukset, ja t\u00e4m\u00e4 voi usein liitty\u00e4 viestiin tai viestin metatietotaulukkoon,<\/li>\n<li>maksutavat voidaan hyvin todenn\u00e4k\u00f6isesti tallentaa niiden taulukkoon, joka liittyy k\u00e4ytt\u00e4j\u00e4\u00e4n jonkin tyyppisen tunnuksen kautta,<\/li>\n<li>yll\u00e4 oleva tunnus sijaitsee taulukossa ja liittyy tiettyyn tietoon toisessa taulukossa, josta sinun on sitten p\u00e4\u00e4tett\u00e4v\u00e4 tarkastelemalla kaikkialla tietokannassa olevia tietoja.<\/li>\n<\/ol>\n<p>Viime k\u00e4dess\u00e4 sinun on luotava joukko kyselyit\u00e4 vain ymm\u00e4rt\u00e4m\u00e4ll\u00e4 ensin, kuinka etsim\u00e4si tiedot tehd\u00e4\u00e4n. Se on riitt\u00e4v\u00e4n haastavaa sellaisenaan. Mutta kun saat sen aikaan, oletetaan, ett\u00e4 kirjoitat kyselysi per\u00e4kk\u00e4in ja k\u00e4yt\u00e4t sitten kunkin tuloksia p\u00e4\u00e4st\u00e4ksesi haluttuun tulokseen.<\/p>\n<p>T\u00e4st\u00e4 voi seurata <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/7c0c8b50cd361f22b5f777544adc2204#file-00-monolithic-queries-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jotain t\u00e4llaista<\/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>Mutta sen ei tarvitse olla n\u00e4in.<\/p>\n<p>Ensinn\u00e4kin n\u00e4m\u00e4 ovat kaikki itsen\u00e4isi\u00e4 kyselyit\u00e4, joissa on riippumattomia tulosjoukkoja, vaikka niit\u00e4 on k\u00e4ytett\u00e4v\u00e4 rinnakkain. T\u00e4m\u00e4 tarkoittaa, ett\u00e4 voimme hajottaa ne osiin ja arvioida kunkin tulokset ennen kuin siirrymme seuraavaan vaiheeseen.<\/p>\n<p>Lis\u00e4ksi sen avulla voimme kirjoittaa pienempi\u00e4, yhten\u00e4isempi\u00e4 funktioita. Vaikka ne saattavat riippua toisistaan, voimme asettaa jokaisen funktion hyv\u00e4ksym\u00e4\u00e4n argumentin (tai joukon argumentteja, joista voimme hakea kaikki tiedot.<\/p>\n<p>Ehk\u00e4 lopputulos n\u00e4ytt\u00e4\u00e4 <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\">t\u00e4lt\u00e4<\/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>En tietenk\u00e4\u00e4n voi n\u00e4ytt\u00e4\u00e4 varsinaista SQL:\u00e4\u00e4 \u2013 no, en ainakaan kaikkialla \u2013 koska en tunne yleist\u00e4 asetuksia enk\u00e4 tied\u00e4 tarkalleen, mit\u00e4 laajennuksia tai skeemoja se on, joiden kanssa ty\u00f6skentelet.<\/p>\n<p>Mutta se ei ole koskaan ollut t\u00e4m\u00e4n postauksen tarkoitus.<\/p>\n<p>Sen sijaan perimm\u00e4inen pointti, jonka yrit\u00e4n v\u00e4litt\u00e4\u00e4, on t\u00e4m\u00e4: Vaikka saatamme ty\u00f6skennell\u00e4 eritt\u00e4in rajoitetuissa rajoituksissa, voimme silti jakaa ohjelmia pienempiin osiin, jotka auttavat meit\u00e4 kuvailemaan, mit\u00e4 tapahtuu, ymm\u00e4rt\u00e4m\u00e4\u00e4n, miten se tehd\u00e4\u00e4n, ja sitten l\u00e4hett\u00e4m\u00e4\u00e4n tietoja. edestakaisin eri toimintojen v\u00e4lill\u00e4 ja k\u00e4ytt\u00e4j\u00e4lle ja takaisin.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yksi niist\u00e4 asioista, joista ohjelmoijat usein puhuvat, on halu jakaa ohjelmat pienempiin komponentteihin tai toimintoihin, jotta ne olisi helpompi j\u00e4ljitt\u00e4\u00e4, lukea ja virheenkorjaus helpottaa.<\/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":[719,895,803],"tags":[1166],"class_list":["post-230928","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kehittaejae","category-koodi","category-php-5","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/230928","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/comments?post=230928"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/230928\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/236233"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=230928"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=230928"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=230928"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}