Change log

Home

Gebruik geen globale variabelen.

Globale variabelen zou je willen gebruiken voor gegevens die in de hele applicatie gelijk zijn, en ook overal in de applicatie worden aangesproken dan wel geraadpleegd. Een voorbeeld hiervoor zou kunnen zijn de achtergrondkleur van verschillende windows waarbij de gebruiker een eigen kleur kan kiezen. Maar ook aanlog gegevens van de gebruiker, zodat zijn persoonlijk profiel wordt gebruikt, of waarmee hij zich aanmeldt bij een server op het web die aangesproken wordt door de applicatie (bijv. een newsserver, messenger-server).

Een eerste , maar voor de hand liggende methode om globale variabelen te vermijden zou zijn, om deze gegevens mee te geven aan objecten, zodat deze hiervan op de hoogte zijn. Nadelen van deze oplossing:

  • Het is arbeidsintensief
  • Het object weet nooit of de gegevens up-to-date zijn
  • Als de gegevens via een ander object (waar deze gegevens als een verzameling in zitten) worden doorgegeven met een reference, je nooit weet of het object waar je naar toe verwijst nog bestaat.

Een andere manier is een object in het leven te roepen, dat maar een maal in de applicatie kan bestaan.

  • De class kan slechts een maal en niet meer dan een maal worden geinstantieërd.

Dit kun je realiseren door een class een instance van zichzelf te laten teruggeven. Als dit object op dat moment nog niet bestaat dan maakt het zichzelf aan, in het andere geval geeft het zichzelf terug.

Het typische van zo'n class is dat het geen public constructor heeft, je kunt het alleen aanspreken via z'n Instance method of property/getter

De oplossing waarbij een class slechts een maal kan worden gecreeërd, wordt een Singleton pattern genoemd.

Opmerkingen bij de Singleton implementaties.

Wat opvalt bij een inheritable Singleton, zoals hier geimplementeerd, is dat de Factory verantwoordelijk is voor het bijhouden van de static variabele, niet de Singleton zelf, hierdoor heeft het Singleton pattern op zich geen interne functionaliteit. Het is een abstract begrip geworden.

Creational versus behavioral

Alhoewel de Singleton vrijwel altijd als creational wordt gezien, het draait om de instantiëring, wordt het soms beschouwd als een behavioral pattern, het laat zich slechts een maal instantiëren, dus de manier waarop. Met de implementatie zoals hier beschreven ligt de nadruk eigenlijk alleen nog maar op het gedrag, het creationele deel is naar de Factory verschoven.

Scope.
  • Binnen een method heeft het begrip Singleton geen betekenis.
  • Binnen een class wordt de rol van Singleton gespeeld door static variabelen. Als deze variabele een object representeerd, dan moet dit er een zijn die binnen de class is geinstantieërd.
  • Binnen een applicatie is dit het Singleton pattern.
  • Op een netwerk (eventueel wereldwijd) zijn dit Singletons die in een Web-service (instances van objecten), Applicatie-server (instances van objecten), Sql-server(rijen in tabellen), of iedere willekeurige andere server aanwezig zijn. Zo een Singleton is (meestal) niet rechtstreeks te benaderen, een gebruikelijke oplossing hiervoor is een proxy pattern (remote) of een facade (tabel in een database), hierdoor is het alsof de Singleton zich binnen de applicatie zelf bevindt.
De SingletonFactory.

Deze wordt in de voorbeelden niet geïnstanteërd, dit is ook niet nodig, omdat de methods waarmee de Singeltons worden aangemaakt zelf ook static zijn, het zijn class methods. Dit maakt de SingletonFactory een uitzonderlijke Factory. Er is echter niets wat het creëren van de Factory tegenhoudt, omdat deze impliciet zelf ook het gedrag van een Singleton vertoond. Wat er dan gebeurt is dat je meerdere deurtjes naar een en hetzelfde object aanmaakt. Een soort van wormholes in applicatie-space die allemaal op dezelfde plek terechtkomen, waardoor de Singleton min of meer omni-present wordt.

Het afschermen van de implementatie details.

Dit wordt vaak aangedragen als noodzakelijk, om misbruik van de Singleton tegen te gaan, zoals het aanmaken van een tweede instance van een Singleton, of het clonen van een instance. Met andere woorden, kwade opzet. Onzin, als je dit probeert heb je niet in de gaten wat je aan het doen bent, er is geen enkele reden om zoiets te doen, simpelweg omdat het geen meerwaarde heeft en er alleen maar fouten in de applicatie worden geintroduceerd. Het afschermen is bedoeld om te voorkomen dat er per ongeluk fouten worden gemaakt, door dit soort acties onmogelijk te maken.

Alhoewel de Delphi en C# uitvoeringen vrijwel identiek zijn, kunnen er toch verschillen aangewezen worden.
  • De basis Factory in delphi geeft een TSingleton terug ipv een ISingleton, dit komt doordat in delphi een interface niet rijker kan worden gecast. Omdat in delphi een com-interface wordt teruggegeven, is er eenvoudigweg niets aanwezig om te casten, bij een class is dit wel het geval. Opgemerkt moet worden dat een interface in Delphi niet 'zuiver' is. 
  • Verder is een concreet classType nodig om te instantiëren, het gevolg daarvan is weer dat de class die we doorgeven aan de factory om te creëren ook echt afgeleid moet zijn van een TSingleton. Dit scheelt weer een check en een exception, maar kan het lastiger maken om een bestaande class van een Singleton af te leiden.
  • Daarnaast moet de Singleton instance een verwijzing naar zijn eigen interface vasthouden. Dit om te voorkomen dat de Singleton op een reference=0 terechtkomt en wordt vrijgegeven.
Top
10 oktober 2004 Opmerkingen implementatie toegevoegd.
3 oktober 2004 Singleton page naar nieuwe url overgezet, design aangepast.

24-10-2017/04-05-2024

konfidence in it (c) 2004