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.
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.
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:
$ GLOBALS
verzamelen, maar dit kan gevaarlijk zijn omdat je iets kunt vernietigen dat al bestaat of het de verzameling onnodig groter maaktGeen 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.
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:
get_instance
die wordt gebruikt om een exemplaar van de klasse te retournerenNiets 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??
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:
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.
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.