Ontwerppatronen in WordPress het Singleton-patroon

In deze serie kijken we naar de betekenis van ontwerppatronen en de rollen die ze spelen in de ontwikkeling van WordPress.

In het eerste bericht in de serie hebben we een onderzoek op hoog niveau uitgevoerd en zelfs het waarnemerspatroon bekeken om te zien hoe het mogelijk is om verschillende functies of objecten te registreren met bepaalde gebeurtenissen die zich voordoen in de levenscyclus van een toepassing.

In deze post, waar ga je naar het Singleton-patroon kijken.

Concreet gaan we kijken naar de definitie van het patroon en hoe het werkt, we gaan een schema bekijken van hoe de architectuur van het patroon eruit ziet, we bespreken een aantal voorbeeldcodes voor het patroon, en dan bespreken we de voordelen van het patroon in verband met de ontwikkeling van WordPress.


Het Singleton-patroon

Wikipedia definieert het Singleton-patroon als volgt:

In software-engineering is het singleton-patroon een ontwerppatroon dat de instantiatie van een klasse beperkt tot één object.

Misschien is een eenvoudiger manier om het patroon uit te leggen dit: Het Singleton-patroon zorgt ervoor dat een klasse slechts één exemplaar kan hebben en het biedt een enkele manier om een ​​exemplaar van zichzelf op te halen.

Dus waarom doet deze materie in WordPress?

Wat de ontwikkeling van het thema betreft, zie ik er persoonlijk weinig nut van, tenzij je een soort helperklasse of bibliotheek met je thema bundelt; Als u echter plug-ins aan het bouwen bent, kan dit uitzonderlijk handig zijn.

Vanaf nu zijn er eigenlijk maar een paar manieren om plug-ins instantiëren (met uitzondering van widgets - dat is een ander onderwerp) binnen WordPress:

  • U kunt de plug-in onder aan uw plug-inbestand instantiëren, maar dit kan leiden tot een object met zwevende rechten
  • Je kunt de plug-in in PHP steken $ GLOBALS verzamelen, maar dit kan gevaarlijk zijn omdat je iets kunt vernietigen dat al bestaat of het de verzameling onnodig groter maakt
  • Als u een instantiatie uitvoert met, bijvoorbeeld, elke pagina laadt, worden de gegevens niet bewaard tenzij u serialiseert en de database hameert telkens wanneer de plug-in wordt geïnstantieerd

Geen van bovenstaande zijn bijzonder goed strategieën (hoewel je zou kunnen beweren dat ze allemaal werken).

We geven er echter meer om dan alleen maar iets te laten werken, toch? We willen dat het werkt en we willen een elegante oplossing voor het probleem. Dit is waar ontwerppatronen - meer specifiek, het Singleton-patroon - een rol gaan spelen.


Hoe het eruit ziet

Laten we eerst eens kijken naar een diagram van het Singleton-patroon. Bekijk het onderstaande schema, dan zullen we het hebben over de details achter de afbeelding:

Dus hier zijn de belangrijkste kenmerken van het Singleton-patroon:

  • Er is een persoonlijke, statische instantievariabele gedefinieerd in de kenmerken die wordt gebruikt om een ​​verwijzing naar de klasse te behouden
  • De constructor is gemarkeerd als privé
  • Er is een openbare statische functie met de naam get_instance die wordt gebruikt om een ​​exemplaar van de klasse te retourneren

Niets te gecompliceerd, maar ik denk dat het herzien van de code voor het Singleton-patroon een lange weg gaat om het een beetje duidelijker te maken, dus laten we dat nu doen:

 class Foo / * -------------------------------------------- * * Attributen * -------------------------------------------- * / / ** Verwijst naar een enkel exemplaar van deze klasse. * / private static $ instance = null; / * -------------------------------------------- * * Constructor * -------------------------------------------- * / / ** * Creëert of retourneert een exemplaar van deze klasse. * * @ return Foo Een enkel exemplaar van deze klasse. * / public static function get_instance () if (null == self :: $ instance) self :: $ instance = new self;  return self :: $ instance;  // end get_instance; / ** * Initialiseert de plug-in door localisatie, filters en beheerfuncties in te stellen. * / private function __construct ()  // end constructor / * ----------------------------------- --------- * * Functies * ------------------------------------- ------- * / // end class Foo :: get_instance ();

Natuurlijk is dat zo geweest veel van code die is weggelaten uit de bovenstaande klasse, maar de principes van het patroon blijven.

Merk op dat we een private, statische instantievariabele hebben die wordt gebruikt om naar deze klasse te verwijzen. In het bijzonder is het ingesteld in de get_instance functie terwijl de constructor als privé is gemarkeerd.

Doorgaans is bij het instantiëren van klassen de constructor de functie die wordt aangeroepen wanneer we klassen initialiseren; In dit geval is de constructor echter gemarkeerd als privé.

Dus wat geeft?

Merk op dat we een publiek hebben get_instance functie net boven de constructor. Deze functie controleert letterlijk of de statische instantievariabele is nul en, als dat zo is, een nieuw exemplaar van de klasse maakt (wat het kan doen omdat het binnen de context van de klas valt); anders wordt de huidige instantie geretourneerd.

Dit is hoe niet meer dan een enkele instantie van een klasse wordt gemaakt.

Merk tot slot op dat we de klasse instantiëren niet met de standaard nieuwe zoekwoord, maar door te bellen get_instance. Niet alleen dat, maar we krijgen ook toekomstige verwijzingen naar de klas door dezelfde methode te gebruiken.

Laten we dus zeggen dat u in een andere sjabloon werkt en dat u bijvoorbeeld een functie moet noemen bar() - die bestaat in uw plug-in. In dat geval zou u zoiets als dit doen:

 $ foo = Foo :: get_instance (); $ Foo-> bar ();

Behoorlijk netjes, toch??


De voordelen van het Singleton-patroon

Ondanks het feit dat we het Singleton-patroon vanuit een architecturaal en een praktisch standpunt hebben behandeld, hebben we eigenlijk niet gesproken over de voordelen van het patroon.

Over het algemeen:

  • Het Singleton-patroon voorkomt dat andere objecten of clients instanties van de klasse dupliceren. Dit zorgt ervoor dat er op enig moment slechts één exemplaar van de gegevens wordt bijgehouden. Alle toegang tot het object wordt gedaan door de enkele instantie.
  • We hebben een breed scala aan flexibiliteit als het gaat om de implementatie, omdat we het instantiatieproces daadwerkelijk kunnen beïnvloeden (hoewel dit een beetje buiten bereik is voor dit specifieke bericht).

Misschien is het grootste nadeel van het gebruik van het patroon het gebrek aan duidelijkheid dat de plug-in het patroon feitelijk gebruikt. Als iemand de klas probeert te instantiëren, mislukt instantiatie omdat er geen openbare constructor is.

Daarom is documentatie essentieel.


Conclusie

Of je ze nu eerder hebt gezien of dit is je eerste poging tot ontwerppatronen, het Singleton-patroon is misschien wel het eenvoudigste ontwerppatroon dat er is. Het is eenvoudig te implementeren en biedt een belangrijke bron van functionaliteit wanneer het correct wordt geïmplementeerd, vooral als het betrekking heeft op webtoepassingen.

In het volgende bericht bekijken we nog een ander patroon - het Simple Factory Pattern - wat handig is als je een aantal klassen hebt die elk een uniek doel hebben en die nodig zijn op basis van bepaalde inputcriteria.