Olemme tehneet huomattavan määrän muutoksia WordPress Widget Boilerplateen. Jos et ole seurannut, suosittelen aloittamaan sarjan alusta ja kuromaan kiinni.
Jos olet kuitenkin seurannut mukana ja käytät myös joitain koodinlaatutyökaluja, jotka tutkivat projektin tilaa, huomaat konsolissa kourallisen virheitä.
Normaalisti tämä on kohta, jossa suosittelen kiinnittämään huomiota siihen, mitä se jakaa, ja korjaamaan sitten sen ilmoittaman, mutta emme ole vielä siellä.
Esimerkiksi jotkut työkalumme tällä hetkellä näyttämistä virheistä perustuvat siihen, että meillä on käyttämättömiä muuttujia. Tietysti näin on kuitenkin, koska emme ole aloittaneet widgetin rakentamista.
Mutta meidän on vielä toteutettava muutamia konkreettisia luokkia.
WordPress Widget Boilerplate: Refactoring, osa 4
Yksi ongelmista, jotka ovat edelleen olemassa koodissa sellaisena kuin se tällä hetkellä on, on se, että widgetin rakentaja rekisteröi toimintoja, mikä ei ole hyvä asia.
Konstruktorin tarkoitus on asettaa luokan ominaisuuksien arvot, ei toteuttaa minkäänlaista logiikkaa. Tämä johtuu muutamista syistä:
- se luo vahvaa kytkentää tai riippuvuuksia luokkien välille projektissa aina, kun tietty luokka instantoidaan,
- se tuo liiketoimintalogiikkaa toimintoon, jonka ei ole tarkoitus sisältää mainittua toimintoa,
- se vaikeuttaa luokan testaamista erikseen.
Tapa käsitellä tämä on kaksitahoinen:
- lisää rekisteri, jonka avulla voimme rekisteröidä luokkia sovelluksessa (ja välittää ne mahdollisimman vähillä riippuvuuksilla, jotka selitän myöhemmin),
- luoda tilaajia, jotka voivat käsitellä liiketoimintalogiikkaa koukkukohtaisesti.
Kolmen seuraavan postauksen aikana:
- harkitsemme rekisterin luomista,
- kuinka voimme lisätä sen bootstrap-tiedostoon,
- ja katso sitten tilaajien luomista jokaiselle toiminnollemme (sen ei pitäisi olla liian vaikeaa ottaen huomioon, mitä teimme edellisessä viestissä ja mitä teemme tässä viestissä).
Luo rekisteri
Ennen kuin kirjoitat rekisterin koodin, on tärkeää huomata, mikä sen ensisijainen tarkoitus on. Yksinkertaisesti sanottuna luokan on tarkoitus sisältää viittaus mihin tahansa luokkaan, joka on rekisteröity siihen.
Tämä tehdään välittämällä viittaus annettuun objektiin funktiolle ja sitomalla se myös avaimeen, jotta voimme helposti hakea sen myöhemmin.
Alustavia huomioita
Mutta joitain asioita on otettava huomioon. Esimerkiksi:
jos objekti on jo olemassa rekisterissä tietylle avaimelle, meidän on tehtävä poikkeus – jos käyttäjä yrittää napata objektin rekisteristä annetulla avaimella, sen pitäisi heittää poikkeus
Poikkeuksia ei tietenkään välttämättä tarvitse tehdä. Sen sijaan se voi myös näyttää virheilmoituksia, palauttaa nolla- tai tyhjiä arvoja tai mitä tahansa valitsemasi.
Toiseksi rekisterin on voitava palauttaa luettelo kaikista sen sisältämistä tilaajista, jotta heidät voidaan rekisteröidä WordPressiin (jonka tulemme näkemään seuraavassa viestissä).
Tätä varten meidän on kuitenkin varmistettava, että se tukee kaikkia tilaajia, ja tässä tulee esiin edellisen viestin käsite AbstractSubscriber. Eli niin kauan kuin luokka on tuon luokan lapsiluokka, olemme kunnossa.
Rekisterin luominen
Tämän jälkeen suunnitellaan seuraavaa:
- Luomme rekisteriluokan ja sijoitamme sen Utilities-nimiavaruuteen (ja siten hakemistoon), jos sitä ei vielä ole työssäsi.
- Rekisterin pitää ylläpitää viittausta kaikkiin assosiatiivisessa taulukossa oleviin objekteihinsa.
- Tarvitsemme menetelmiä yksittäisen tilaajan lisäämiseksi ja hankkimiseksi ja sitten yhden kokonaisten tilaajien luettelon hakemiseksi.
Luokan tynkä näyttää suunnilleen tältä:
<?php
class Registry extends AbstractSubscriber
{
public function __construct()
{
}
public function add($id, $obj)
{
}
public function get($id)
{
}
public function getRegisteredSubscribers()
{
}
}
Seuraavaksi voimme määrittää perusominaisuuden, taulukon ja alustaa sen konstruktorissa:
<?php
class Registry
{
private $registry;
public function __construct()
{
$this->registry = [];
}
// ...
}
Tämän jälkeen voimme luoda lisäysmenetelmän. Muista, että toteutuksessani valitsen poikkeuksen, jos avain on jo määritetty, mutta sinun ei tarvitse tehdä sitä.
<?php
public function add($id, $obj)
{
if (isset($this->registry[$id])) {
throw new Exception('An object already exists for this given key.');
}
$this->registry[$id] = $obj;
}
Vastaavasti get-menetelmä palauttaa viittauksen kyseisellä avaimella tunnistetun objektin esiintymään. Jos avainta ei ole asetettu, se tekee poikkeuksen. Jos se on asetettu, mutta objektia ei ole, palautetaan null.
<?php
public function get($id)
{
if (!isset($this->registry[$id])) {
throw new Exception('No object exists for the specified key.');
}
return $this->registry[$id] ?? null;
}
Lopuksi tarvitsemme menetelmän kaikkien rekisteröityjen tilaajien palauttamiseksi. Tulevassa viestissä tämän käyttö tulee paljon ilmeisemmäksi, mutta toistaiseksi huomaa, että luomme taulukon mistä tahansa luokasta, joka on AbstractSubscriber – luokan esiintymä, ja sitten palautamme suodatetun taulukon.
<?php
public function getRegisteredSubscribers()
{
$subscribers = [];
foreach ($this->registry as $object) {
if ($object instanceof AbstractSubscriber) {
$subscribers[] = $object;
}
}
return array_filter($subscribers);
}
Tässä vaiheessa meillä on koko luokka (dokumentaatioineen):
<?php
/*
* This file is part of the WordPress Widget Boilerplate
*
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
namespace WordPressWidgetBoilerplateUtilities;
use Exception;
use WordPressWidgetBoilerplateSubscriberAbstractSubscriber;
/**
* This class services as a simple container that can be used to pass objects
* around the plugin.
*
* To use this class you'd make a call to the registry by saying Registry->get(),
* then making a class to `register()` and `retrieve()` on an instance of the object.
*/
class Registry
{
/**
* @var array an array used to maintain the objects registered with the plugin
*/
private $registry;
/**
* Initializes the class by setting up the registry.
*/
public function __construct()
{
$this->registry = [];
}
/**
* Registers an object with the registry with the specified ID; however, will throw an
* exception if the ID is already referencing an object.
*
* @param string $id an ID by which the specified object will be referenced
* @param mixed $obj an instance of an object to store in the registry
*
* @throws Exception if an object already exists for the specified key
*/
public function add($id, $obj)
{
if (isset($this->registry[$id])) {
throw new Exception('An object already exists for this given key.');
}
$this->registry[$id] = $obj;
}
/**
* @param string $id the ID for the object that we wish to retrieve
*
* @throws Exception if no object exists for the specified key
*
* @return mixed a reference to the object or null
*/
public function get($id)
{
if (!isset($this->registry[$id])) {
throw new Exception('No object exists for the specified key.');
}
return $this->registry[$id] ?? null;
}
/**
* @return array all of the the Subscribers that should be registered with WordPress
*/
public function getRegisteredSubscribers()
{
$subscribers = [];
foreach ($this->registry as $object) {
if ($object instanceof AbstractSubscriber) {
$subscribers[] = $object;
}
}
return array_filter($subscribers);
}
}
Nyt meidän on lisättävä se laajennuksen bootstrapiin.
Kuitenkin ennen The Bootstrapia
Kuten aiemmin viestissä mainittiin, meidän on lisättävä tämä laajennuksen käynnistyspalkkiin. Tätä varten meidän on kuitenkin määritettävä oma suodattimemme, jotta voimme helposti siirtää rekisterin muun laajennuksen ympärille (kun sen aika tulee).
Ennen kuin teemme sen, on kuitenkin tärkeää varmistaa, että sinulla on hyvä käsitys juuri luomastamme rekisteristä, että se sopii laajennukseen ja että seuraat kehityshaaraa, joka meillä on tähän mennessä.