Mira a suddividere i programmi in componenti più piccoli
Una delle cose di cui parlano spesso i programmatori è il desiderio di suddividere i programmi in componenti o funzioni più piccoli, in modo che siano più facili da tracciare, più facili da leggere e più facili da eseguire il debug.
Ma non è poi così raro vedere funzioni monolitiche con molti commenti al codice per aiutare a spiegare cosa sta succedendo nel programma.
Non sto bussando, davvero, perché non conosco i vincoli in base ai quali stava lavorando un programmatore. Questo è:
- Qual era il budget che aveva durante la costruzione del programma?
- Quanto tempo è stato concesso per completare il progetto?
- C’erano molte persone che lavoravano al progetto?
- Al programmatore è stato concesso il tempo di scrivere il codice in modo da poterlo testare, refactoring o semplicemente semplificarne la lettura?
In breve, ci sono molte ragioni – credo – per cui possiamo leggere "codice errato" e non deve essere sempre colpa del programmatore (questa è solo la cosa più naturale che dobbiamo buttare via quando leggiamo qualcosa che non ci piace).
Questo significa, tuttavia, che non dovremmo sforzarci di refactoring o scrivere codice in modo tale da renderlo più facile da capire? Ovviamente no. Supponendo che abbiamo il tempo per farlo, come potremmo farlo?
Suddividi i programmi in componenti più piccoli
Quando si tratta di scrivere su un argomento come questo, specialmente in un’economia attiva come l’eCommerce in WordPress, può essere una sfida.
"Diventiamo specifici, Bob."
Cioè, posso scriverne a un livello molto dettagliato usando una suite di plugin, guardando i dati, analizzando le query e mostrando come farlo. Oppure posso scriverne a un livello leggermente superiore con l’obiettivo finale di mostrare come suddividere i programmi in componenti più piccoli.
Poiché ci sono così tanti modi in cui il primo può essere raggiunto, sto optando per il secondo. Cioè, questo non utilizzerà necessariamente plug-in specifici sono query dirette. Tuttavia, utilizzerà esempi di alto livello per aiutarti a esaminare quella che potrebbe essere una serie di query e cicli e suddividerli in funzioni più piccole.
Un esempio generico
Ad esempio, supponiamo che sto lavorando su una funzionalità di un plug-in di WordPress il cui scopo finale è recuperare tutti i vari metodi di pagamento memorizzati da un utente e relativi al proprio account.
La sfida è che queste informazioni sono sparse su più tabelle di database (a causa dei vari plug-in utilizzati), quindi ci sono alcune query che devono essere eseguite e quindi recuperate.
I passaggi per effettuare tali query potrebbero essere simili a questo:
- ottenere l’ID cliente dell’utente corrente,
- ottenere tutti i numeri ID ordine per il cliente
- determinare quali metodi di pagamento sono stati utilizzati per ciascun ordine
- recuperare le suddette modalità di pagamento e quindi inviare le informazioni effettuate al cliente
A seconda di come è impostato il database, in base al tuo livello di abilità SQL e in base al modo in cui i vari plug-in per la gestione di tutti i dati di cui sopra funzionano in tandem, potrebbe essere facile scrivere una query di grandi dimensioni per recuperare queste informazioni.
Ma se hai lavorato con l’eCommerce in WordPress e vari plugin, sai che non è sempre così facile.
Invece, stai guardando qualcosa come:
- dobbiamo ottenere il profilo di un cliente dai metadati dell’utente,
- abbiamo bisogno di trovare tutti gli ordini che l’utente ha fatto, e questo spesso può essere associato al post o alla tabella dei metadati del post,
- molto probabilmente i metodi di pagamento possono essere memorizzati nella loro tabella associata all’utente tramite qualche tipo di token,
- il token sopra si trova in una tabella ed è correlato a una determinata informazione in un’altra tabella da cui devi quindi dedurre osservando i dati esistenti nel database.
In definitiva, devi creare una serie di query solo comprendendo prima come eseguire query per i dati che stai cercando. È già abbastanza impegnativo così com’è. Ma quando riesci a farlo, diciamo che stai scrivendo le tue query in sequenza e quindi utilizzando i risultati di ciascuna per ottenere l’output desiderato.
Ciò può comportare qualcosa del genere :
<?php
// First, read the user ID and meta value to get authorization information
global $wpdb;
$results = $wpdb->get_results(
$wpdb->prepare(
"
SELECT
user_id, meta_value
FROM $wpdb->usermeta
WHERE meta_key LIKE %s
AND user_id = %d
",
'%customer_profile_id%',
filter_input(INPUT_GET, 'customer_id')
),
ARRAY_A
);
$result = isset($results[0])? array_column($results[0], 'meta_value'): [];
if (empty($result)) {
return $result;
}
// Get the ID of the current customer.
$customers = $wpdb->get_results(
$wpdb->prepare(
"", // Your custom query goes here.
filter_input(INPUT_GET, 'customer_id')
),
ARRAY_A
);
$customer = isset($customers[0])? array_column($customers[0], 'customer_id'): [];
if (empty($customer)) {
return $customer;
}
// Get all of the order IDs from the set of orders returned from the previous query.
$orderIds = $wpdb->get_results(
$wpdb->prepare(
"", // Your custom query goes here.
$customer
),
ARRAY_A
);
return $orderIds;
// Finally, get all of the payment methods for the orders based on their Ids.
$orders = [];
foreach ($orderIds as $orderId) {
$results = $wpdb->get_results(
$wpdb->prepare(
"" // The query for retrieving various payment method information based on the $orderId
),
ARRAY_A
);
if (empty($results)) {
continue;
}
$orders[$orderId] = $results;
}
// Now send the information back to the user.
wp_send_json_success($orders);
Ma non deve essere così.
In primo luogo, queste sono tutte query indipendenti con insiemi di risultati indipendenti anche se devono essere utilizzate in tandem. Ciò significa che possiamo dividerli e valutare i risultati di ciascuno prima di procedere con il passaggio successivo.
Inoltre, ci consente di scrivere funzioni più piccole e più coese. Anche se possono dipendere l’uno dall’altro, possiamo impostare ogni funzione per accettare un argomento (o un insieme di argomenti da cui possiamo recuperare tutte le informazioni.
Forse il risultato finale potrebbe assomigliare a questo :
<?php
public function getPaymentMethods()
{
$authInfo = $this->getAuthorizationInformation();
$currentCustomerId = $this->getCurrentCustomerId($authInfo);
$orders = $this->getCustomerOrders($currentCustomerId);
$paymentMethods = $this->getPaymentMethodsFromOrders($orders);
wp_send_json_success($orders);
}
private function getAuthorizationInformation()
{
global $wpdb;
$authInfo = $wpdb->get_results(
$wpdb->prepare(
"
SELECT
user_id, meta_value
FROM $wpdb->usermeta
WHERE meta_key LIKE %s
AND user_id = %d
",
'%customer_profile_id%',
filter_input(INPUT_GET, 'customer_id')
),
ARRAY_A
);
return isset($authInfo[0])? array_column($authInfo[0], 'meta_value'): [];
}
private function getCurrentCustomerIdFromAuthInfo($authInfo)
{
global $wpdb;
$customers = $wpdb->get_results(
$wpdb->prepare(
"", // Your custom query goes here.
$authInfo;
),
ARRAY_A
);
return isset($customerId[0])? array_column($customerId[0], 'meta_value'): [];
}
private function getCustomerOrders($customerId)
{
global $wpdb;
$orderIds = $wpdb->get_results(
$wpdb->prepare(
"", // Your custom query goes here.
$customerId
),
ARRAY_A
);
return empty($orderIds)? []: $orderIds;
}
private function getPaymentMethodsFromOrders($orderIds)
{
$paymentMethods = [];
foreach ($orderIds as $orderId) {
$results = $wpdb->get_results(
$wpdb->prepare(
"" // The query for retrieving various payment method information based on the $orderId
),
ARRAY_A
);
if (empty($results)) {
continue;
}
$paymentMethods[$orderId] = $results;
}
return $paymentMethods;
}
Ovviamente, non posso mostrare alcun SQL reale – beh, almeno non ovunque – perché non conosco l’impostazione generale né so esattamente con quali plugin o schemi stai lavorando.
Ma non è mai stato questo il punto di questo post.
Invece, il punto finale che sto cercando di trasmettere è questo: anche se possiamo lavorare con vincoli molto limitati, possiamo comunque suddividere i programmi in componenti più piccoli che ci aiutano a descrivere cosa sta succedendo, capire come è fatto e quindi inviare i dati avanti e indietro tra le varie funzioni e da e verso l’utente.