{"id":230253,"date":"2022-12-08T17:18:00","date_gmt":"2022-12-08T14:18:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230253"},"modified":"2022-12-07T11:56:33","modified_gmt":"2022-12-07T08:56:33","slug":"staraj-sie-dzielic-programy-na-mniejsze-komponenty","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/staraj-sie-dzielic-programy-na-mniejsze-komponenty\/","title":{"rendered":"Staraj si\u0119 dzieli\u0107 programy na mniejsze komponenty"},"content":{"rendered":"\n<p>Jedn\u0105 z rzeczy, o kt\u00f3rych cz\u0119sto m\u00f3wi\u0105 programi\u015bci, jest ch\u0119\u0107 podzielenia program\u00f3w na mniejsze komponenty lub funkcje, aby u\u0142atwi\u0107 ich \u015bledzenie, czytanie i debugowanie.<\/p>\n<p>Ale nie jest niczym niezwyk\u0142ym zobaczy\u0107 monolityczne funkcje z wieloma komentarzami do kodu, kt\u00f3re pomagaj\u0105 wyja\u015bni\u0107, co si\u0119 dzieje w programie.<\/p>\n<p>Naprawd\u0119 tego nie pukam, bo nie znam ogranicze\u0144, pod jakimi pracowa\u0142 programista. To znaczy:<\/p>\n<ul>\n<li>Jaki by\u0142 jego\/jej bud\u017cet buduj\u0105c program?<\/li>\n<li>Ile czasu po\u015bwi\u0119cono na wykonanie projektu?<\/li>\n<li>Czy nad projektem pracowa\u0142o wiele os\u00f3b?<\/li>\n<li>Czy programista mia\u0142 czas na napisanie kodu, aby m\u00f3g\u0142 go przetestowa\u0107 jednostkowo, zrefaktoryzowa\u0107 lub po prostu u\u0142atwi\u0107 czytanie?<\/li>\n<\/ul>\n<p>Kr\u00f3tko m\u00f3wi\u0105c, istnieje wiele powod\u00f3w \u2013 wierz\u0119 \u2013 \u017ce mo\u017cemy czyta\u0107 \u201ez\u0142y kod&quot; i nie zawsze musi to by\u0107 wina programisty (to po prostu najbardziej naturalna rzecz, kt\u00f3r\u0105 musimy wyrzuci\u0107, kiedy czytamy co\u015b, czego nie lubimy).<\/p>\n<p>Czy to jednak oznacza, \u017ce \u200b\u200bnie powinni\u015bmy d\u0105\u017cy\u0107 do refaktoryzacji lub pisania kodu w taki spos\u00f3b, aby by\u0142 \u0142atwiejszy do zrozumienia? Oczywi\u015bcie nie. Zak\u0142adaj\u0105c, \u017ce mamy na to czas, jak mo\u017cemy to zrobi\u0107?<\/p>\n<h2>Podziel programy na mniejsze komponenty<\/h2>\n<p>Je\u015bli chodzi o pisanie na taki temat, zw\u0142aszcza w gospodarce, kt\u00f3ra jest tak aktywna jak eCommerce w WordPressie, mo\u017ce to by\u0107 wyzwaniem.<\/p>\n<h3>\u201eB\u0105d\u017amy konkretni, 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>Oznacza to, \u017ce mog\u0119 o tym pisa\u0107 na bardzo szczeg\u00f3\u0142owym poziomie, korzystaj\u0105c z zestawu wtyczek, patrz\u0105c na dane, analizuj\u0105c zapytania i pokazuj\u0105c, jak to zrobi\u0107. Albo mog\u0119 napisa\u0107 o tym na nieco wy\u017cszym poziomie, a ostatecznym celem jest pokazanie, jak podzieli\u0107 programy na mniejsze komponenty.<\/p>\n<p>Poniewa\u017c istnieje tak wiele sposob\u00f3w, aby to pierwsze osi\u0105gn\u0105\u0107, wybieram to drugie. Oznacza to, \u017ce niekoniecznie b\u0119dzie to u\u017cywanie konkretnych wtyczek, ale bezpo\u015brednie zapytania. B\u0119dzie jednak u\u017cywa\u0142 przyk\u0142ad\u00f3w wysokiego poziomu, kt\u00f3re pomog\u0105 Ci przej\u015b\u0107 przez seri\u0119 zapyta\u0144 i p\u0119tli oraz podzieli\u0107 je na mniejsze funkcje.<\/p>\n<h3>Og\u00f3lny przyk\u0142ad<\/h3>\n<p>Za\u0142\u00f3\u017cmy na przyk\u0142ad, \u017ce pracuj\u0119 nad funkcj\u0105 wtyczki WordPress, kt\u00f3rej ostatecznym celem jest pobranie wszystkich r\u00f3\u017cnych metod p\u0142atno\u015bci zapisanych przez u\u017cytkownika i powi\u0105zanych z jego kontem.<\/p>\n<p>Wyzwanie polega na tym, \u017ce informacje te s\u0105 rozproszone w wielu tabelach bazy danych (z powodu r\u00f3\u017cnych u\u017cywanych wtyczek), wi\u0119c istnieje kilka zapyta\u0144, kt\u00f3re nale\u017cy wykona\u0107, a nast\u0119pnie pobra\u0107.<\/p>\n<p>Kroki tworzenia takich zapyta\u0144 mog\u0105 wygl\u0105da\u0107 mniej wi\u0119cej tak:<\/p>\n<ol>\n<li>uzyska\u0107 identyfikator klienta bie\u017c\u0105cego u\u017cytkownika,<\/li>\n<li>zdob\u0105d\u017a wszystkie numery identyfikacyjne zam\u00f3wienia dla klienta<\/li>\n<li>okre\u015bli\u0107, jakie metody p\u0142atno\u015bci zosta\u0142y u\u017cyte przy ka\u017cdym zam\u00f3wieniu<\/li>\n<li>pobra\u0107 wspomniane metody p\u0142atno\u015bci, a nast\u0119pnie wys\u0142a\u0107 informacje do klienta,<\/li>\n<\/ol>\n<p>W zale\u017cno\u015bci od konfiguracji bazy danych, w zale\u017cno\u015bci od poziomu umiej\u0119tno\u015bci SQL i w zale\u017cno\u015bci od tego, jak r\u00f3\u017cne wtyczki obs\u0142uguj\u0105ce wszystkie powy\u017csze dane dzia\u0142aj\u0105 w tandemie, mo\u017ce by\u0107 \u0142atwo napisa\u0107 jedno du\u017ce zapytanie w celu pobrania tych informacji.<\/p>\n<p>Ale je\u015bli pracowa\u0142e\u015b z eCommerce w WordPressie i r\u00f3\u017cnych wtyczkach, wiesz, \u017ce nie zawsze jest to takie proste.<\/p>\n<p>Zamiast tego patrzysz na co\u015b takiego jak:<\/p>\n<ol>\n<li>musimy uzyska\u0107 profil klienta z metadanych u\u017cytkownika,<\/li>\n<li>musimy znale\u017a\u0107 wszystkie zam\u00f3wienia z\u0142o\u017cone przez u\u017cytkownika, a to cz\u0119sto mo\u017ce by\u0107 powi\u0105zane z postem lub tabel\u0105 metadanych posta,<\/li>\n<li>metody p\u0142atno\u015bci mog\u0105 by\u0107 z du\u017cym prawdopodobie\u0144stwem przechowywane w ich tabeli powi\u0105zanej z u\u017cytkownikiem za pomoc\u0105 pewnego rodzaju tokena,<\/li>\n<li>powy\u017cszy token znajduje si\u0119 w tabeli i jest powi\u0105zany z dan\u0105 informacj\u0105 w innej tabeli, z kt\u00f3rej musisz nast\u0119pnie wywnioskowa\u0107, patrz\u0105c na dane istniej\u0105ce w ca\u0142ej bazie danych.<\/li>\n<\/ol>\n<p>Ostatecznie musisz utworzy\u0107 zestaw zapyta\u0144 tylko przez zrozumienie, w jaki spos\u00f3b wykona\u0107 zapytanie o dane, kt\u00f3rych szukasz. To ju\u017c wystarczaj\u0105co trudne. Ale kiedy ju\u017c to zrobisz, powiedzmy, \u017ce piszesz zapytania sekwencyjnie, a nast\u0119pnie u\u017cywasz wynik\u00f3w ka\u017cdego z nich, aby uzyska\u0107 po\u017c\u0105dany wynik.<\/p>\n<p>Mo\u017ce to spowodowa\u0107 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/7c0c8b50cd361f22b5f777544adc2204#file-00-monolithic-queries-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">co\u015b takiego<\/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>Ale nie musi tak by\u0107.<\/p>\n<p>Po pierwsze, s\u0105 to wszystkie niezale\u017cne zapytania z niezale\u017cnymi zestawami wynik\u00f3w, mimo \u017ce musz\u0105 by\u0107 u\u017cywane w tandemie. Oznacza to, \u017ce mo\u017cemy je rozdzieli\u0107 i oceni\u0107 wyniki ka\u017cdego z nich, zanim przejdziemy do nast\u0119pnego kroku.<\/p>\n<p>Ponadto pozwala nam pisa\u0107 mniejsze, bardziej sp\u00f3jne funkcje. Nawet je\u015bli mog\u0105 one od siebie zale\u017ce\u0107, mo\u017cemy ustawi\u0107 ka\u017cd\u0105 funkcj\u0119 tak, aby akceptowa\u0142a argument (lub zestaw argument\u00f3w, z kt\u00f3rego mo\u017cemy pobra\u0107 wszystkie informacje.<\/p>\n<p>By\u0107 mo\u017ce efekt ko\u0144cowy mo\u017ce wygl\u0105da\u0107 mniej wi\u0119cej <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\">tak<\/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>Oczywi\u015bcie nie mog\u0119 pokaza\u0107 \u017cadnego rzeczywistego SQL \u2013 c\u00f3\u017c, przynajmniej nie wsz\u0119dzie \u2013 poniewa\u017c nie znam og\u00f3lnej konfiguracji ani nie wiem dok\u0142adnie, z jakimi wtyczkami lub schematami pracujesz.<\/p>\n<p>Ale to nigdy nie by\u0142o celem tego postu.<\/p>\n<p>Zamiast tego, ostateczn\u0105 kwesti\u0105, kt\u00f3r\u0105 staram si\u0119 przekaza\u0107, jest to, \u017ce nawet je\u015bli pracujemy pod bardzo ograniczonymi ograniczeniami, nadal mo\u017cemy dzieli\u0107 programy na mniejsze komponenty, kt\u00f3re pomagaj\u0105 nam opisa\u0107, co si\u0119 dzieje, zrozumie\u0107, jak to si\u0119 robi, a nast\u0119pnie wysy\u0142a\u0107 dane tam iz powrotem mi\u0119dzy r\u00f3\u017cnymi funkcjami oraz do i od u\u017cytkownika.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jedn\u0105 z rzeczy, o kt\u00f3rych cz\u0119sto m\u00f3wi\u0105 programi\u015bci, jest ch\u0119\u0107 podzielenia program\u00f3w na mniejsze komponenty lub funkcje, aby u\u0142atwi\u0107 ich \u015bledzenie, czytanie i debugowanie.<\/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":[721,897,805],"tags":[1169],"class_list":["post-230253","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-kod","category-php-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=230253"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230253\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/236233"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=230253"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=230253"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=230253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}