Toon posts:

Singleton: vermijden of juist niet?

Pagina: 1
Acties:

Onderwerpen


  • jexus
  • Registratie: maart 2010
  • Laatst online: 26-05-2014
Modbreak:Dit topic is afgesplitst van php globale var doet erg moeilijk.

Dat klinkt als singleton en singleton is bah...

[Voor 37% gewijzigd door NMe op 23-10-2010 17:55]


  • NMe
  • Registratie: februari 2004
  • Laatst online: 18:56

NMe

Quia Ego Sic Dico.

jexus schreef op zaterdag 23 oktober 2010 @ 00:03:
Dat klinkt als singleton en singleton is bah...
Omdat PHP Freakz, 's land's slechtste PHP-site, het zegt? Singletons zijn een valide design pattern en zeker niet per definitie bah. Iets dat je eenmalig wil instantiëren en overal in je code beschikbaar wil hebben in een singleton zetten is zelfs best practice als je het mij vraagt...

De argumenten in die post zijn sowieso weinig steekhoudend en tonen eigenlijk alleen maar aan dat de schrijver de klok heeft horen luiden maar niet weet waar de klepel hangt.

[Voor 15% gewijzigd door NMe op 23-10-2010 00:55]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • RobIII
  • Registratie: december 2001
  • Laatst online: 19:41

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

NMe schreef op zaterdag 23 oktober 2010 @ 00:52:
Singletons zijn een valide design pattern en zeker niet per definitie bah. Iets dat je eenmalig wil instantiëren en overal in je code beschikbaar wil hebben in een singleton zetten is zelfs best practice als je het mij vraagt...
Singletons worden wel flink bekritiseerd en wordt zelfs soms als anti-pattern beschouwd. Maar een beetje devver maakt voor zichzelf wel uit of 'ie vervolgens een singleton wel of niet wil gebruiken ;) Ik moet bekennen bij een aantal projecten halverwege wel eens gruwelijk spijt te hebben gekregen van een singleton maar dat lag meer mij dan aan een singleton an-sich. Ze hebben zeker hun nut maar ik probeer 't wel te vermijden waar mogelijk.

[Voor 67% gewijzigd door RobIII op 23-10-2010 01:06]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • NMe
  • Registratie: februari 2004
  • Laatst online: 18:56

NMe

Quia Ego Sic Dico.

RobIII schreef op zaterdag 23 oktober 2010 @ 00:53:
[...]

Singletons worden wel flink bekritiseerd en er zitten nogal wat haken en ogen aan. Maar een beetje devver maakt voor zichzelf wel uit of 'ie vervolgens een singleton wel of niet wil gebruiken ;)
Mja, maar voor een databaseconnectie waarvan je weet dat je er nooit meer dan één nodig gaat hebben in dezelfde request, of (zoals in dit topic) voor een security context-object waarvan je er maar één nodig gaat hebben omdat er altijd maar één gebruiker is die de site gebruikt is een singleton prima te verdedigen. Iemand die dan roept dat een singleton per definitie fout is heeft geen flauw benul van wat hij nu eigenlijk zegt. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • orf
  • Registratie: augustus 2005
  • Laatst online: 19:28
Omdat PHP Freakz, 's land's slechtste PHP-site, het zegt?
...
De argumenten in die post zijn sowieso weinig steekhoudend en tonen eigenlijk alleen maar aan dat de schrijver de klok heeft horen luiden maar niet weet waar de klepel hangt.
Er staan toch geen onwaarheden in het artikel? Er wordt een goed code voorbeeld gegeven en er worden valide redenen gegeven om het niet te gebruiken.

Het artikel is geschreven door iemand met flinke kennis van zaken. Kijk eens naar de overige artikelen van zijn naam of workshops die hij geeft. 's land's slechtste PHP site is niet zo aardig om zo maar als stelling de deponeren zonder onderbouwing.

Zomaar roepen dat een singleton bah is vind ik ook van weinig inzicht blijken overigens.

[Voor 6% gewijzigd door orf op 23-10-2010 01:05]


  • NMe
  • Registratie: februari 2004
  • Laatst online: 18:56

NMe

Quia Ego Sic Dico.

orf schreef op zaterdag 23 oktober 2010 @ 01:04:
[...]

Er staan toch geen onwaarheden in het artikel? Er wordt een goed code voorbeeld gegeven en er worden valide redenen gegeven om het niet te gebruiken.
Valide redenen? Laten we eens kijken. ;)
Pas op het moment dat je 100% zeker bent dat je verplicht bent om het instantieren van het object te limiteren, is het gebruik gerechtvaardigd.
Onzin. Neem mijn databaseverhaal als voorbeeld. Je kan prima meerdere connecties leggen naar de database, ligt niemand wakker van...totdat je meer bezoekers krijgt en je erachter komt dat je misschien toch wat veel rekentijd verspilt in het leggen van connecties. Gewoon lekker een singleton gebruiken.
Bij het gebruik van het Singleton pattern is het lastig om polymorphisme te implementeren.
Waarom dan? Zegt hij nergens. Maar goed, ook dat is een non-argument. Dat iets lastig is maakt het niet onmogelijk, en als er goede redenen zijn om een singleton te gebruiken zou ik me niet laten weerhouden door een "lastigheidje".
Het geeft een te harde koppeling tussen klassen, omdat je ze onlosmakelijk verbind. Wil je een klasse gebruiken in een ander project, moet dat andere project ook verplicht de singleton hebben, anders werkt de klasse niet meer en moet je deze dus ombouwen. (breken van herbruikbaarheid)
Onzin. Afhankelijkheid van andere klassen is helemaal gaan probleem, dat is juist een van de mooie dingen van OO. En de herbruikbaarheid komt ook niet in het geding, want of je nu een singleton aanroept of een constructor boeit geen klote.
Het is niet duidelijk. Zonder de klassen te openen, is het niet mogelijk om te zien of een bepaalde klasse de singleton gebruikt.
Non-argument. Als het niet in één oogopslag duidelijk is aan de code hoe je hem moet gebruiken, dan schrijf je daar comments voor. Luiheid van een programmeur om vooral geen comments te schrijven is geen excuus om dan maar af te zien van een valide design pattern omdat het "onduidelijk" zou zijn.
Niet te testen. Doordat je zo'n harde koppeling is, is het lastig om een object stand-alone te testen. Bovendien kan ongewenst gedrag zich afspelen binnen de singleton implementatie, in plaats van de concrete klasse. Uiteindelijk ben je dus langer bezig met testen en met bugfixen.
Als je dat meer dan 5 minuten langer kost dan vind ik dat knap. Nog een non-argument dus.

Waar staan die valide argumenten dan? ;)
Het artikel is geschreven door iemand met flinke kennis van zaken. Kijk eens naar de overige artikelen van zijn naam of workshops die hij geeft.
Ik zou het graag doen, maar dat gaat zo lastig... Google vertelt me dat hij een 27-jarige software developer is die intussen misschien wat betere artikelen schrijft, maar dit artikel uit 2007 klopt gewoon niet.
's land's slechtste PHP site is niet zo aardig om zo maar als stelling de deponeren zonder onderbouwing.
Dit artikel is onderbouwing genoeg. Er wordt door PFZ (zoals wel vaker) een stelling geponeerd en die slaat gewoon als een tang op een varken zonder verdere onderbouwing. En dan krijg je dus mensen zoals jexus (no offense :) ) die dat verhaal lezen en ineens in topics op GoT als absolute waarheid gaan lopen verkondigen, zonder verdere nuance of enige blijk van eigen inzicht.

Een tijd geleden heb ik het hier ook over gehad met de mensen achter PFZ zelf, destijds hadden ze nog artikelen prominent op de site staan die uitgingen van de aanwezigheid van register globals. Sindsdien is de site verbeterd maar zolang er dus artikelen zoals het hier aangehaalde artikel op die site blijven staan zonder verder enige vorm van redenering of nuance, dan blijf ik bij mijn mening: die site doet meer kwaad dan goed.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • orf
  • Registratie: augustus 2005
  • Laatst online: 19:28
Onzin. Neem mijn databaseverhaal als voorbeeld. Je kan prima meerdere connecties leggen naar de database, ligt niemand wakker van...totdat je meer bezoekers krijgt en je erachter komt dat je misschien toch wat veel rekentijd verspilt in het leggen van connecties. Gewoon lekker een singleton gebruiken.
Waarom zou je meerdere connecties gebruiken zonder singleton? Het artikel beschrijft dat je beter gewoon een connectie construct en deze vervolgens doorgeeft aan je overige objecten. Daarmee heb je nog steeds 1 verbinding, maar voorkom je afhankelijkheid. Unittesting is dan ook iets makkelijker. Dat heeft dus niets met rekentijd te maken.
Onzin. Afhankelijkheid van andere klassen is helemaal gaan probleem, dat is juist een van de mooie dingen van OO. En de herbruikbaarheid komt ook niet in het geding, want of je nu een singleton aanroept of een constructor boeit geen klote.
Je knoopt een object hard aan een databaseconnectie, terwijl dat object niet perse aan een database geknoopt hoeft te worden.
Het is niet duidelijk. Zonder de klassen te openen, is het niet mogelijk om te zien of een bepaalde klasse de singleton gebruikt.

Non-argument. Als het niet in één oogopslag duidelijk is aan de code hoe je hem moet gebruiken, dan schrijf je daar comments voor. Luiheid van een programmeur om vooral geen comments te schrijven is geen excuus om dan maar af te zien van een valide design pattern omdat het "onduidelijk" zou zijn.
Als je het in de constructor meegeeft, dan wéét je dat er een database connectie nodig is. Als je in de documentatie moet kijken of in de code van het object, dan weet je het niet. Dat heeft niets met comments te maken.
Waar staan die valide argumenten dan?
Volgens mij vat je een aantal zaken in het artikel verkeerd op.

Nogmaals, ik vind het geen slecht artikel. Er staat een uitstekend voorbeeld van een singleton, met argumenten om het niet zomaar te gebruiken.

Ik gebruik regelmatig singletons, maar het kan geen kwaad stil te staan bij de nadelen.

Hier grofweg dezelfde argumenten op een msdn blog:
  1. Singletons frequently are used to provide a global access point for some service.
    True, they do this, but at what cost? They provide a well-known point of access to some service in your application so that you don't have to pass around a reference to that service. How is that different from a global variable? (remember, globals are bad, right???) What ends up happening is that the dependencies in your design are hidden inside the code, and not visible by examining the interfaces of your classes and methods. You have to inspect the code to understand exactly what other objects your class uses. This is less clear than it could be. The urge to create something as a global to avoid passing it around is a smell in your design; it is not a feature of globals/singletons. If you examine your design more closely, you can almost always come up with a design that it is better and does not have to pass around tramp data to every object and method.
  2. Singletons allow you to limit creation of your objects.
    This is true, but now you are mixing two different responsibilities into the same class, which is a violation of the Single Responsibility Principle. A class should not care whether or not it is a singleton. It should be concerned with its business responsibilities only. If you want to limit the ability to instantiate some class, create a factory or builder object that encapsulates creation, and in there, limit creation as you wish. Now the responsibilities of creation are partitioned away from the responsibilities of the business entity.

  3. Singletons promote tight coupling between classes
    One of the underlying properties that makes code testable is that it is loosely coupled to its surroundings. This property allows you to substitute alternate implementations for collaborators during testing to achieve specific testing goals (think mock objects). Singletons tightly couple you to the exact type of the singleton object, removing the opportunity to use polymorphism to substitute an alternative. A better alternative, as discussed in the first point above, is to alter your design to allow you to pass references to objects to your classes and methods, which will reduce the coupling issues described above.
  4. Singletons carry state with them that last as long as the program lasts
    Persistent state is the enemy of unit testing. One of the things that makes unit testing effective is that each test has to be independent of all the others. If this is not true, then the order in which the tests run affects the outcome of the tests. This can lead to cases where tests fail when they shouldn't, and even worse, it can lead to tests that pass just because of the order in which they were run. This can hide bugs and is evil. Avoiding static variables is a good way to prevent state from being carried from test to test. Singletons, by their very nature, depend on an instance that is held in a static variable. This is an invitation for test-dependence. Avoid this by passing references to objects to your classes and methods.
Bron: http://blogs.msdn.com/b/s...ve/2004/05/25/140827.aspx

  • Freeaqingme
  • Registratie: april 2006
  • Laatst online: 18:37
In het kort dan.
1
(remember, globals are bad, right???)
Uiteraard is een singleton een global. Daar hebben we 't hier juist over, om 't dan af te doen met "... are bad, right???' komt op mij niet over als een super argument. Ik zeg niet dat globals supergoed zijn, maar aangezien classnames in principe uniek zijn, heb je geen probleem met het feit dat je dubbele variablenames zou kunnen hebben in je globalscope - zoals je dat met "normale" globals wel hebt.

2 Je combineert geen verantwoordelijkheden in 1 class. De class doet nog steeds X, en is nog steeds verantwoordelijk voor Y. Je definieert ook de visibility van een method of property in een class, en de argumenten die de methods accepteren (dat kan vaak ook in een interface, maar that's not the point). Dat zorgt er nog niet voor dat de class meerdere verantwoordelijkheden krijgt.

3 Wil je een class volledig los wil halen uit z'n "surroundings" op een flexibele manier moet je een fullblown DI-Solution of IoC introduceren, ook dat heeft zo z'n nadelen, en is zeker niet sneller. Vaak kan dit ook met een hoop getters&setters, maar dan moet je weer gaan controleren of de gegeven parameters correct zijn, gezien punt 2 van zijn betoog ga je dan ook verantwoordelijkheden mixen.

4 Ja, singletons houden hun staat zolang 't programma duurt. WHO CARES in een stateless omgeving (en we hadden/begonnen hier over php)? Het idee achter singleton is juist dat een object zijn state houdt nadat dit eenmaal geinitieerd is, dus da's mooi :D. Dat je 't vervolgens wat moeilijker kan unittesten is jammer, maar ik maak mijn applicaties om mooi in elkaar te zitten en effectief te kunnen werken. Niet omdat ik uiteindelijk alleen de unittests moet opleveren. En al ga je unittesten (wat uiteraard iedereen hier doet), dan kan je natuurlijk met gearman ofzo iedere test of groep testen in een aparte thread draaien, of desnoods een resetInstance() method gebruiken in je singleton om 't object te unsetten.

Ik zeg niet dat singletons per definitie goed zijn, maar ik gebruik ze graag - soms.

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


  • Hillie
  • Registratie: januari 2000
  • Laatst online: 17-02 23:06

Hillie

Poepen = ultieme ontspanning

Is het feit dat programmeurs er niet mee om kunnen gaan een reden om er dan maar tegen te zijn? Punt 1 en 2 zijn m.i. alleen in de titel al vooral een user discretion probleem, 3 m.i. ook (maar misschien mis ik iets), 4 geeft m.i. vooral een testprobleem aan.

Liefhebber van schieten en schijten. Ouwehoer en niet-evangelisch atheist.

Camacha: Je hebt nog gelijk ook.


  • Freeaqingme
  • Registratie: april 2006
  • Laatst online: 18:37
Hillie schreef op zaterdag 23 oktober 2010 @ 02:45:
Is het feit dat programmeurs er niet mee om kunnen gaan een reden om er dan maar tegen te zijn? Punt 1 en 2 zijn m.i. alleen in de titel al vooral een user discretion probleem, 3 m.i. ook (maar misschien mis ik iets), 4 geeft m.i. vooral een testprobleem aan.
En dan dacht ik en probeerde ik 't nog kort te houden :(

Nu ik 't nog een keer lees (jaja, 't is al laat) neem ik aan dat er met punt 3 gedoeld wordt op 't gebruik van mock objects (wanneer zou je anders een object uit z'n surroundings willen halen?). Dat zou dan ook weer overeenkomen met punt 4, en 't zou duiden op dat wanneer je singletons gebruikt je alles in de vorm van een singleton giet - iets wat in een grotere applicatie uiteraard verwerpelijk is.

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


  • Lethalis
  • Registratie: april 2002
  • Niet online
Zoals met zoveel dingen in deze wereld hebben singletons hun nut in bepaalde situaties en zijn ze onhandig in andere.

Even a broken clock is right twice a day.


  • EfBe
  • Registratie: januari 2000
  • Niet online
Ach, het aloude gel*l van online betweters die hun ego willen oppoetsen met artikelen online omtrent een pattern dat ze kennelijk niet begrijpen.

Een singleton is soms erg nuttig, vooral wanneer je globale state hebt die je wilt accessen vanuit veel verschillende delen van je applicatie. Het aloude 'beste stuurlui staan aan wal' argument van "dat is fout", daar word ik toch zo moe van; hoe wil je dan in een OO programma oplossen dat je (global accessable) data beschikbaar hebt voor veel delen van de applicatie? Die moet ERGENS leven. Dus stop je dat in een object, wat dan weer ergens ingeplaatst moet worden, anders kun je er niet bij. Dit levert dus een probleem op: de houder van je state object moet dat state object aanbieden, en iedereen moet die houder benaderen. Dit is veelal ongewenst en een singleton kan dan een solide oplossing zijn.

Dat singletons nadelen hebben is ook duidelijk, maar welk pattern heeft dat niet? Singletons zijn static, global en hebben state. Dit levert dus in multi-threaded (en een web applicatie is multithreaded!) omgevingen problemen op, maar het op een andere manier oplossen had dezelfde problematiek gegeven: locking van access op de global data. In onze O/R mapper gebruiken we een aantal singletons, allemaal voor global meta-data die gebruikt wordt tijdens de acties op de db: zoals mapping data, inheritance graphs data, dependency injection meta-data etc., geen per-thread data, want dat is niet data dat je in een singleton moet stoppen: immers, de singleton is voor global data dat overal bereikbaar moet zijn.

Lead developer of LLBLGen Pro.
https://fransbouma.com


  • _Erikje_
  • Registratie: januari 2005
  • Laatst online: 30-08 16:01

_Erikje_

Tweaker in Spanje

d:)b Efbe

Elk design pattern heeft een toepassing en ja, je kunt alles misbruiken (O+) waardoor je als minder begaafd programmeur kan zeggen: "<insert pattern> Sux, nooit gebruiken, dat is evil want iemand heeft dit gezegd op the Interwebz".

;w triest topic ;w

  • R4gnax
  • Registratie: maart 2009
  • Laatst online: 13-09 19:02
EfBe schreef op zondag 24 oktober 2010 @ 11:00:

Een singleton is soms erg nuttig, vooral wanneer je globale state hebt die je wilt accessen vanuit veel verschillende delen van je applicatie. Het aloude 'beste stuurlui staan aan wal' argument van "dat is fout", daar word ik toch zo moe van; hoe wil je dan in een OO programma oplossen dat je (global accessable) data beschikbaar hebt voor veel delen van de applicatie?
Hoe dan? Nou, bijvoorbeeld met dependency injection: je IoC initialisatie code maakt één state object aan, wat vervolgens in de constructors geinjecteerd wordt van alle classes die hem moeten gebruiken. De wat stevigere IoC frameworks als Unity kunnen nog een stapje verder met lifetime managers en automatische injectie en op die manier alles compleet ontkoppelen.

Singleton is 9 van de 10 keer een zwaktebod, waarbij je zonder IoC geen beter alternatief hebt.

  • ReenL
  • Registratie: augustus 2010
  • Laatst online: 22-03-2015
Omdat PHP Freakz, 's land's slechtste PHP-site, het zegt?
Dit heb je zelf ook niet onderbouwd... Beleid is erg anders en niveau van de meeste vragen ook, maar om zeggen dat het de slechtste site is vind ik erg kort door de bocht. Ik denk dat phpfreakz een heel goed initiatief is voor startende phpers, ik heb er in elk geval in een ver verleden veel kunnen leren.

Ik zie de waarheid wel in het artikel. Gevolg van een singleton is dat de classe globaal beschikbaar is, dus ook in bijvoorbeeld je view als je een mvc pattern gebruikt. Wil jij dat je designer die een beetje html/php kan toegang geven tot je database? Ik in elk geval niet.

  • momania
  • Registratie: mei 2000
  • Laatst online: 19:02

momania

iPhone 30! Bam!

R4gnax schreef op zondag 24 oktober 2010 @ 13:29:
[...]


Hoe dan? Nou, bijvoorbeeld met dependency injection: je IoC initialisatie code maakt één state object aan, wat vervolgens in de constructors geinjecteerd wordt van alle classes die hem moeten gebruiken. De wat stevigere IoC frameworks als Unity kunnen nog een stapje verder met lifetime managers en automatische injectie en op die manier alles compleet ontkoppelen.

Singleton is 9 van de 10 keer een zwaktebod, waarbij je zonder IoC geen beter alternatief hebt.
Aan de andere kant, Singletons zijn vaak gewoon valide oplossing en het lijkt wel of elke devver tegenwoordig voor een stuk programma van 100 regels standaard ook maar een IoC container erbij pakt, want dat hoort zo. Ja joh, lekker een paar MB aan overhead voor een simpel programma. KISS ;)

Key als altijd: juiste pattern/tool/design voor je probleem kiezen. Singleton hoeft daarin niet perse altijd slecht te zijn :Y)

Neem je whisky mee, is het te weinig... *zucht*


  • BlackHawkDesign
  • Registratie: maart 2005
  • Laatst online: 15:53
Het singleton pattern is een elegante oplossing voor het probleem als je ALTIJD maar 1 instance van een class wilt hebben. Niets meer, niets minder.

Vind je een singleton niet geschikt voor jouw probleem, dan is jouw probleem niet gelijk aan het probleem waarvoor de singleton ontworpen is. Dat maakt de singleton pattern niet slecht.

[Voor 38% gewijzigd door BlackHawkDesign op 24-10-2010 15:12]


  • Anoniem: 241683
  • Registratie: november 2007
  • Niet online
ReenL schreef op zondag 24 oktober 2010 @ 13:52:

Ik zie de waarheid wel in het artikel. Gevolg van een singleton is dat de classe globaal beschikbaar is, dus ook in bijvoorbeeld je view als je een mvc pattern gebruikt. Wil jij dat je designer die een beetje html/php kan toegang geven tot je database? Ik in elk geval niet.
Hahaha die geef je toch uberhaupt geen toegang? Met een simpel unlink methode of een file_get_contents kan die persoon ook genoeg schade toebrengen. Dus dat argument slaat als een tang op een varken...

  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
Ik neem aan dat iedereen beseft dat de topic title berust op een valse dichotomie van "Singletons worden altijd goed gebruikt" óf "Singletons mogen nooit gebruikt worden". De waarheid ligt in het midden.
BlackHawkDesign schreef op zondag 24 oktober 2010 @ 15:11:
Het singleton pattern is een elegante oplossing voor het probleem als je ALTIJD maar 1 instance van een class wilt hebben. Niets meer, niets minder.
Dat vind ik dus te simpel gesteld. Feit blijft dat een Singleton een soort veredelde globale variabele is en daarmee dus ook de nadelen van een globale variabele heeft. Het is toevallig de makkelijkste methode om gebruik van een globale variabele (waarbij veel programmeurs wel aanvoelen dat het in veel situaties geen nette oplossing is) om te zetten in een officieel erkend Design Pattern™.

Juist het feit dat het de makkelijkste manier is om het probleem weg te werken zonder daadwerkelijk iets te veranderen zorgt ervoor dat het patroon een groot risico loopt verkeerd gebruikt te worden. En nadat je 'm eenmaal geintroduceerd hebt, kom je er moeilijk vanaf, want met code die op Design Patterns gebaseerd is kan toch niets mis zijn?

In sommige situaties is een globale variabele of een statische methode écht de beste oplossing voor het probleem. Het is dan onzinnig om er een singleton voor te introduceren. Daar win je niets mee. In andere situaties is het feit dat een klasse een ander oject nodig heeft zo essentieel dat het beter is dat tweede object expliciet mee te geven in de constructor (dat is wat R4gnax ook noemde). Ook dan gebruik je dus geen singleton.

Soms wil je wel een statische variabele of functie gebruiken maar legt de taal je beperkingen op. In C++ is de initialisatievolgorde van globale variabelen in verschillende translation units ongedefinieerd, waardoor je dus bij de initialisatie van het ene object geen gebruik kunt maken van een ander. In dat soort situaties kan ik me voorstellen dat je kiest voor een Singleton.
Vind je een singleton niet geschikt voor jouw probleem, dan is jouw probleem niet gelijk aan het probleem waarvoor de singleton ontworpen is.
Wat als ik een singleton niet geschikt vind, en mijn collega wel? Een ontwerpkeuze kan natuurlijk nooit gemotiveerd worden met ik vind.... Intuïtie speelt een grote rol bij OO ontwerp, maar juiste beslissingen zijn gebaseerd op impliciete of explicitiete belangenafwegingen. "Ik vind het wel leuk, dus is het goed." slaat nergens op.
EfBe schreef op zondag 24 oktober 2010 @ 11:00:
Een singleton is soms erg nuttig, vooral wanneer je globale state hebt die je wilt accessen vanuit veel verschillende delen van je applicatie.
Ofwel: om afhankelijkheden tussen classes te verdoezelen. Dat is een foutieve manier om problemen in het ontwerp aan de aandacht te onttrekken. Ja, ik snap dat het soms praktisch is. De eerder genoemde weg van de minste weerstand. Maar een ontwerpfout los je op door het ontwerp te herzien. Als je een object moet delen tussen verschillende klassen, moet je het wellicht expliciet doorgeven aan de klassen die het gebruiken, zodat die afhankelijkheid zichtbaar wordt. Als je dan teveel afhankelijkheden tussen objecten krijgt, is de opdeling van je programma naar gescheidde verantwoordelijkheden wellicht niet zo geslaagd.

  • Janoz
  • Registratie: oktober 2000
  • Laatst online: 00:52

Janoz

Moderator Devschuur®

!litemod

momania schreef op zondag 24 oktober 2010 @ 14:03:
[...]

Aan de andere kant, Singletons zijn vaak gewoon valide oplossing en het lijkt wel of elke devver tegenwoordig voor een stuk programma van 100 regels standaard ook maar een IoC container erbij pakt, want dat hoort zo. Ja joh, lekker een paar MB aan overhead voor een simpel programma. KISS ;)

Key als altijd: juiste pattern/tool/design voor je probleem kiezen. Singleton hoeft daarin niet perse altijd slecht te zijn :Y)
Je kunt ook IoC toepassen met je eigen 'container'. niets verplicht je om al je objecten middels xml configuratie aan elkaar te hangen. In een niet zo heel grote applicatie van mijzelf gebruik ik geen singletons, maar IoC. Bij een dergelijk kleine applicatie is het aan elkaar hangen van de verschillende onderdelen ook wimpel in code te doen.

Wat ik persoonlijk trouwens erg vreemd vind is dat er uberhaupt over php singletons gepraat wordt. In php bestaan helemaal geen echte singletons.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Anoniem: 26306

Ik denk dat dit soort vragen altijd simpel te beantwoorden. Vergelijkbaar met "goto gebruiken of niet" en "globals gebruiken of niet".

Mijns inziens is het beste antwoord op de vraag conditioneel:
Als je niet begrijpt waarom men zegt dat je ze niet zou moeten gebruiken, moet je ze niet gebruiken.

Wie de valkuilen kent zal goed een goede afweging kunnen maken, en ze tóch gebruiken als een situatie erom vraagt.

  • NMe
  • Registratie: februari 2004
  • Laatst online: 18:56

NMe

Quia Ego Sic Dico.

ReenL schreef op zondag 24 oktober 2010 @ 13:52:
[...]

Dit heb je zelf ook niet onderbouwd...
Lees NMe in "Singleton: vermijden of juist niet?" en dan met name de laatste alinea's nog eens. ;)
Ik zie de waarheid wel in het artikel. Gevolg van een singleton is dat de classe globaal beschikbaar is, dus ook in bijvoorbeeld je view als je een mvc pattern gebruikt. Wil jij dat je designer die een beetje html/php kan toegang geven tot je database? Ik in elk geval niet.
Los van het feit dat een designer die denkt even wat aan te kunnen passen in de database in een template (!!!) problemen zou moeten krijgen met zijn baas is wat je nu omschrijft meer een probleem met PHP dan een probleem met het design pattern. Bovendien zou je in PHP net zo goed gewoon zelf een DB-object kunnen instantiëren in de templates, dat is echt geen probleem dat exclusief voorkomt bij singletons. ;) In een fatsoenlijke OO-omgeving worden class dependencies netjes geabstraheerd en kun je een singleton enkel beschikbaar maken voor/binnen bepaalde packages/namespaces.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • BlackHawkDesign
  • Registratie: maart 2005
  • Laatst online: 15:53
Soultaker schreef op zondag 24 oktober 2010 @ 16:19:
Feit blijft dat een Singleton een soort veredelde globale variabele is en daarmee dus ook de nadelen van een globale variabele heeft.
Dat vind ik dus onzin. Er zit nog een flink verschil tussen een singleton en een globale variabele, wat scoping betreft. Dus om dat nou even simpel op een hoop te gooien en dan dezelfde nadelen toe te passen vind ik te ver gaan. Overigens heb ik niet gezegd dat er geen implicaties waren.
Juist het feit dat het de makkelijkste manier is om het probleem weg te werken zonder daadwerkelijk iets te veranderen zorgt ervoor dat het patroon een groot risico loopt verkeerd gebruikt te worden. En nadat je 'm eenmaal geintroduceerd hebt, kom je er moeilijk vanaf, want met code die op Design Patterns gebaseerd is kan toch niets mis zijn?
Design patterns worden vaak gezien als de heilige graal en worden dus vaak misbruikt: mee eens. Maar maakt dat design patterns slecht, of de gene die ze gebruikt?
In sommige situaties is een globale variabele of een statische methode écht de beste oplossing voor het probleem. Het is dan onzinnig om er een singleton voor te introduceren. Daar win je niets mee. In andere situaties is het feit dat een klasse een ander oject nodig heeft zo essentieel dat het beter is dat tweede object expliciet mee te geven in de constructor (dat is wat R4gnax ook noemde). Ook dan gebruik je dus geen singleton.
Dat het singleton pattern niet geschikt is voor de problemen die je nu schetst zou heel goed kunnen, maar dat hoor je me ook niet zeggen. Als een globale variabele een betere oplossing zou zijn, dan is dat de keuze en niet een singleton.
Wat als ik een singleton niet geschikt vind, en mijn collega wel? Een ontwerpkeuze kan natuurlijk nooit gemotiveerd worden met ik vind.... Intuïtie speelt een grote rol bij OO ontwerp, maar juiste beslissingen zijn gebaseerd op impliciete of explicitiete belangenafwegingen. "Ik vind het wel leuk, dus is het goed." slaat nergens op.
Een belangenafweging is ondanks je daar een goede redenatie of argumentatie voor hebt, evengoed nog wel persoonlijk. Het kan zijn dat iemand anders uit dezelfde argumentatie een andere conclusie trekt. Dus het blijft hoe dan ook persoonlijk. Dus, Ik vind dit een geschikte keuze omdat : ... is helemaal niets mis mee ;)

Vergis je niet, ik vind het misbruiken van design patterns of specifiek het singleton pattern ook een slechte zaak en helaas zie je het veel. Mij hoor je dus ook niet zeggen, dat je altijd een singleton moet gebruiken. Maar nogmaals dat is geen reden om het altijd te mijden. Als een design pattern voor jouw probleem, de oplossing is, dan zie ik geen reden om het niet toe te passen. Ook vind ik het singleton pattern, voor het probleem waarvoor het ontworpen is, absoluut een geschikte oplossing. Alleen helaas gebruiken heel veel mensen hem voor de verkeerde toepassingen.

  • Janoz
  • Registratie: oktober 2000
  • Laatst online: 00:52

Janoz

Moderator Devschuur®

!litemod

BlackHawkDesign schreef op zondag 24 oktober 2010 @ 18:54:
Dat vind ik dus onzin. Er zit nog een flink verschil tussen een singleton en een globale variabele, wat scoping betreft. Dus om dat nou even simpel op een hoop te gooien en dan dezelfde nadelen toe te passen vind ik te ver gaan. Overigens heb ik niet gezegd dat er geen implicaties waren.
Flink verschil qua scoping issues? Zou je kunnen aangeven wat precies dat flinke verschil is? IMHO heeft een singleton enkel een extra wrappertje, meer verschilt het niet van een globale var.
Design patterns worden vaak gezien als de heilige graal en worden dus vaak misbruikt: mee eens. Maar maakt dat design patterns slecht, of de gene die ze gebruikt?

Dat het singleton pattern niet geschikt is voor de problemen die je nu schetst zou heel goed kunnen, maar dat hoor je me ook niet zeggen. Als een globale variabele een betere oplossing zou zijn, dan is dat de keuze en niet een singleton.
Maar de juiste optie is optie 3. Een singleton moet zeker niet vervangen worden door een globale var. Vaak kan het probleem een stuk netter opgelost worden

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • EfBe
  • Registratie: januari 2000
  • Niet online
R4gnax schreef op zondag 24 oktober 2010 @ 13:29:
[...]
Hoe dan? Nou, bijvoorbeeld met dependency injection: je IoC initialisatie code maakt één state object aan, wat vervolgens in de constructors geinjecteerd wordt van alle classes die hem moeten gebruiken. De wat stevigere IoC frameworks als Unity kunnen nog een stapje verder met lifetime managers en automatische injectie en op die manier alles compleet ontkoppelen.
Hoe wil jij je O/R mapping data in-memory houden en gebruiken dan? Middels een static .... singleton! Want, hoe ga je anders die data bereiken vanuit alle mogelijke instances? Ookal gebruik je een session / context class, die zal altijd de meta-data erven vanuit een centrale single-instance, die static is en niet wijzigt.

Dit:
Singleton is 9 van de 10 keer een zwaktebod, waarbij je zonder IoC geen beter alternatief hebt.
is precies het gelul waar ik tegen ageerde. Wel grote woorden gebruiken, maar je snapt niet echt waar je het over hebt. Case in point: jij wilt kennelijk IoC gebruiken. Prima, alleen... waar sla ik de Dependency Injection info op? Die staat ergens, en waarom zou ik daar GEEN singleton voor kunnen gebruiken? Immers, het is static data: geinitializeerd tijdens app initialisatie.

Daarom zei ik ook: static global data dat beschikbaar moet zijn tijdens de app lifetime. Hou jezelf niet voor de gek trouwens, static data opslaan in een object in je applicatie core is ook een singleton gebruiken, je noemt het alleen niet zo. Jouw IoC container moet ook ergens vandaan halen wat waarin te injecten. Dat gaat die IoC container echt niet iedere keer opnieuw van disk uit een XML file lezen, althans dat hoop ik toch niet. M.a.w.: je snapte niet wat ik bedoelde.

Lead developer of LLBLGen Pro.
https://fransbouma.com


  • EfBe
  • Registratie: januari 2000
  • Niet online
Soultaker schreef op zondag 24 oktober 2010 @ 16:19:
[...]
Ofwel: om afhankelijkheden tussen classes te verdoezelen. Dat is een foutieve manier om problemen in het ontwerp aan de aandacht te onttrekken.
Ook jij maakt je schuldig aan het bekritiseren van een ontwerp waar je de ballen verstand van hebt. Laat ik (N)Hibernate nemen. Je hebt een session factory, die sessions creeert. Die sessionfactory is een singleton, daar maak je niet iedere keer weer een instance van. Dat is precies wat ik bedoelde: die beheert static global data waar je op een centrale plek bij wilt zonder dat je een dependency naar de CONTAINER van de data legt in het object waar je de data in stopt. Heeft niets met praktisch te maken, het is in het geval van global static data precies de juiste oplossing, vandaar ook dat het een pattern is: het lost een probleem op, met specifieke karakteristieken, en je probleem moet dus precies die karakteristieken hebben, anders is het pattern niet de juiste oplossing (want dan heb je een ander probleem).
Ja, ik snap dat het soms praktisch is. De eerder genoemde weg van de minste weerstand. Maar een ontwerpfout los je op door het ontwerp te herzien. Als je een object moet delen tussen verschillende klassen, moet je het wellicht expliciet doorgeven aan de klassen die het gebruiken, zodat die afhankelijkheid zichtbaar wordt. Als je dan teveel afhankelijkheden tussen objecten krijgt, is de opdeling van je programma naar gescheidde verantwoordelijkheden wellicht niet zo geslaagd.
Ach ja, en jij, zonder enige kennis van zaken, kan dat prima beoordelen toch?

Jouw text hierboven is overigens hot air: immers, ik kan de singleton ook vervangen door een service, exact hetzelfde: de singleton verricht een service in mijn programma door data te beheren en beschikbaar te stellen. Als ik het vervang door een service heb ik totale decoupling, immers, ik heb NERGENS in mijn applicatie een dependency op een bepaald object op een bepaalde plek, integendeel, ik laat dat aan de service over. Dat is precies waarom een singleton soms wenselijk is.

Belangrijk Mijn punt is dat het alleen een goede oplossing is voor de situaties die ik schetste, dus voor problemen waarbij het pattern de oplossing is. Wat mij mateloos stoort is dat de discussie totaal vast loopt door het betweterige gezeik van sommigen die vinden dat ze designs kunnen afkraken als 'slecht' terwijl ze nauwelijks details weten van waar het in kwestie over gaat (wat ze afkraken). Als je wilt beargumenteren dat singletons soms verkeerd gebruikt worden, tja, alles wordt wel ergens verkeerd gebruikt, dat is een gegeven. Waar het om gaat hier is wanneer het WEL nut heeft. Je moet niet steevast een singleton gebruiken voor data die in objects hoort, maar als men goed had gelezen zei ik dat ook helemaal niet. Ik had het juist over data die:
1) static is
2) global beschikbaar (door een api) moet zijn

Die stop je in een object die door een static class wordt beheert, de singleton. Niet altijd, veelal niet, maar in sommige gevallen, zoals bv bij data die vanuit een XML file wordt geladen tijdens startup, maakt het je applicatie erg simpel en per saldo verandert er niets: de static data zit in zn eigen object, en dat zou hij ook zitten zonder het predikaat 'singleton'

[Voor 21% gewijzigd door EfBe op 24-10-2010 20:53]

Lead developer of LLBLGen Pro.
https://fransbouma.com


  • RayNbow
  • Registratie: maart 2003
  • Laatst online: 19:14

RayNbow

Kirika <3

EfBe schreef op zondag 24 oktober 2010 @ 20:35:
Hou jezelf niet voor de gek trouwens, static data opslaan in een object in je applicatie core is ook een singleton gebruiken, je noemt het alleen niet zo.
En wat nu als ik meerdere instanties van de applicatie core wil hebben? :+

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


  • RedRose
  • Registratie: juni 2001
  • Niet online

RedRose

Icebear

EfBe schreef op zondag 24 oktober 2010 @ 20:35:
[...]

Hoe wil jij je O/R mapping data in-memory houden en gebruiken dan? Middels een static .... singleton! Want, hoe ga je anders die data bereiken vanuit alle mogelijke instances? Ookal gebruik je een session / context class, die zal altijd de meta-data erven vanuit een centrale single-instance, die static is en niet wijzigt.

Dit:

[...]

is precies het gelul waar ik tegen ageerde. Wel grote woorden gebruiken, maar je snapt niet echt waar je het over hebt. Case in point: jij wilt kennelijk IoC gebruiken. Prima, alleen... waar sla ik de Dependency Injection info op? Die staat ergens, en waarom zou ik daar GEEN singleton voor kunnen gebruiken? Immers, het is static data: geinitializeerd tijdens app initialisatie.

Daarom zei ik ook: static global data dat beschikbaar moet zijn tijdens de app lifetime. Hou jezelf niet voor de gek trouwens, static data opslaan in een object in je applicatie core is ook een singleton gebruiken, je noemt het alleen niet zo. Jouw IoC container moet ook ergens vandaan halen wat waarin te injecten. Dat gaat die IoC container echt niet iedere keer opnieuw van disk uit een XML file lezen, althans dat hoop ik toch niet. M.a.w.: je snapte niet wat ik bedoelde.
Ja precies. Dat zegt Martin Fowler zelf ook: http://martinfowler.com/articles/injection.html

Daarnaast, waarom is in hemelsnaam het meegeven van een reference in elke constructor beter dan een Singleton, waarvan je allebei weet dat het static global data is dan wel een eenmalig geinstantieerde class?

Verder lijkt deze zin mij lood om oud ijzer:
Ofwel: om afhankelijkheden tussen classes te verdoezelen. Dat is een foutieve manier om problemen in het ontwerp aan de aandacht te onttrekken.
Of je nou IoC gebruikt of een Singleton, blijkbaar is er behoefte aan in de scope en de lifetime van een applicatie één instance te gebruiken en dat heeft volgens mij niet zoveel te maken met het ontwerp van een platte architectuur op code niveau, maar eerder met hoe het gebruikt wordt als applicatie/proces/service/whatever.

Hetzelfde geldt voor het Factory pattern (in analogie aan EfBe's Service voorbeeld), dat volgens mij eerder bedoeld is om implementaties te verbergen en makkelijk te kunnen switchen naar een andere implementatie. Maar dat is van een hele andere scope dan de wenselijkheid om slechts 1 instance te willen hebben. En er zijn legio voorbeelden van situaties waarbij je juist maar (ook multithreaded) 1 instance kan gebruiken.

In ieder geval is het lastig discussieren als er continue appels en peren worden vergeleken. :P
RayNbow schreef op zondag 24 oktober 2010 @ 20:48:
[...]

En wat nu als ik meerdere instanties van de applicatie core wil hebben? :+
Dan heb je dus meerdere singletons, 1 per core :P

[Voor 4% gewijzigd door RedRose op 24-10-2010 21:00]

Sundown Circus


Anoniem: 26306

RedRose schreef op zondag 24 oktober 2010 @ 20:59:

Hetzelfde geldt voor het Factory pattern (in analogie aan EfBe's Service voorbeeld), dat volgens mij eerder bedoeld is om implementaties te verbergen en makkelijk te kunnen switchen naar een andere implementatie.
Fijn dat je dat zegt, want ik zie een Singleton zelf het liefst als een Factory die simpelweg maar één object retourneert.

  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
EfBe schreef op zondag 24 oktober 2010 @ 20:43:
Ook jij maakt je schuldig aan het bekritiseren van een ontwerp waar je de ballen verstand van hebt. [..] Ach ja, en jij, zonder enige kennis van zaken, kan dat prima beoordelen toch?
Waarom kun je niet inhoudelijk reageren zonder het op de man te spelen? Als de discussie zo gevoerd gaat worden hoeft het van mij niet.
Mijn punt is dat het alleen een goede oplossing is voor de situaties die ik schetste, dus voor problemen waarbij het pattern de oplossing is.
Dat is een waarheid als een koe: het Singleton Pattern is een goede oplossing in situaties waarin het Singleton Pattern een goede oplossing is. Daar zeg je precies niets mee.

Je lijkt te suggereren dat in de gevallen waarin Singletons gebruikt worden er geen alternatieven zijn, die wellicht te preferen zijn. De laatste keer dat ik zelf het (Abstract) Factory Pattern gebruikte creëerde ik Factories juist níet als singleton maar gaf ze expliciet mee aan functie die er gebruik van maken. Het voordeel in dit geval was dat ik ze eerst kon configureren op een andere plaats dan waar ze gebruikt worden, én dat duidelijk was welke functies precies objecten aanmaakten (doormiddel van de Factory die ze meekrijgen). Die oplossing lijkt mij superieur aan een singleton, waarbij onduidelijk is hoe die geconfigureerd wordt en wie 'm precies gebruikt.

Ik ken Hibernate niet dus ik kan er weinig over zeggen of de Singleton daar zinnig toegepast is, maar ik wil maar aangeven dat er in situaties zijn waarin er betere alternatieven voor Singletons zijn. De argumentatie "een Singleton kan dus het is goed zo" snijdt dan geen hout, want één van de doelen van Design Patterns is juist om code beter te ontwerpen met alle voordelen van dien, en niet naar de eerste beste methode te grijpen "omdat dat ook werkt".

  • YopY
  • Registratie: september 2003
  • Laatst online: 16-09 14:48
quote: freaquingme
Uiteraard is een singleton een global. Daar hebben we 't hier juist over, om 't dan af te doen met "... are bad, right???' komt op mij niet over als een super argument. Ik zeg niet dat globals supergoed zijn, maar aangezien classnames in principe uniek zijn, heb je geen probleem met het feit dat je dubbele variablenames zou kunnen hebben in je globalscope - zoals je dat met "normale" globals wel hebt.
De auteur van dat stukje gaat niet verder in om de redenen waarom globals slecht zijn, aangezien er al genoeg anderen daarover gediscussieerd hebben. hier staat wel een goeie (niet al te lange) opsomming van redenen.
quote: freaquingme
2 Je combineert geen verantwoordelijkheden in 1 class. De class doet nog steeds X, en is nog steeds verantwoordelijk voor Y.
Dat doe je wel - verantwoordelijkheid 1 is hetgeen wat de class zelf al doet, de tweede verantwoordelijkheid is het in de gaten houden van het aantal instanties daarvan en het uitdelen van instanties van die class (je zou het een 'static service locator' kunnen noemen, maar dan eentje die maar één service aanbiedt, namelijk zichzelf). Als je een service locator wilt gebruiken is best, maar doe het dan met één service locator, die alle 'singletons' van je applicatie beheert (en maak van die service locator niet ook een singleton, maar een instance object dat je doorstuurt naar de objecten die ze nodig hebben). Een goeie tussenstap voor het uitfactoren van singletons, aangezien je je service locator wél makkelijk kunt isoleren / mocken in een unit test (itt een singleton).
quote: BlackHawkDesign
Maar maakt dat design patterns slecht, of de gene die ze gebruikt?
Ik kies optie 3, de artikeltjes op internet die singletons als oplossing aanwijzen zonder de alternatieven aan te bieden of de gebruiker te informeren over het hoe en wat.
quote: RedRose
Dan heb je dus meerdere singletons, 1 per core
Doubleton pattern? :+

  • EfBe
  • Registratie: januari 2000
  • Niet online
Soultaker schreef op zondag 24 oktober 2010 @ 21:18:
[...]
Waarom kun je niet inhoudelijk reageren zonder het op de man te spelen? Als de discussie zo gevoerd gaat worden hoeft het van mij niet.
Jee, ik denk precies hetzelfde. Kunnen we nu weer over singletons praten ipv andermans designs af te branden zonder kennis? dank.
[...]
Dat is een waarheid als een koe: het Singleton Pattern is een goede oplossing in situaties waarin het Singleton Pattern een goede oplossing is. Daar zeg je precies niets mee.
Tuurlijk wel, precies hetgeen wat menigeen vergeet, nl. patterns zijn geen buildingblocks maar oplossingen voor precies gedefinieerde problemen: heb je dat probleem niet, dan moet je niet het pattern gebruiken.
Je lijkt te suggereren dat in de gevallen waarin Singletons gebruikt worden er geen alternatieven zijn, die wellicht te preferen zijn. De laatste keer dat ik zelf het (Abstract) Factory Pattern gebruikte creëerde ik Factories juist níet als singleton maar gaf ze expliciet mee aan functie die er gebruik van maken. Het voordeel in dit geval was dat ik ze eerst kon configureren op een andere plaats dan waar ze gebruikt worden, én dat duidelijk was welke functies precies objecten aanmaakten (doormiddel van de Factory die ze meekrijgen). Die oplossing lijkt mij superieur aan een singleton, waarbij onduidelijk is hoe die geconfigureerd wordt en wie 'm precies gebruikt.
Maar dat is een oplossing voor een ander probleem. Immers, een factory maakt objects, maar dat is niet waar het bij singletons om gaat. Singletons zijn containers voor static data, beheert door de singleton static class (althans, dat is de singleton implementatie die ik altijd gebruik: een static class die intern een singleton instance heeft die een interface implementeert en waar je in je applicatie tegenaan praat: je krijgt de feitelijke instance dan van de static class, maar weet niet waar die gemaakt is noch welke class het precies is. Dat is dus decoupling die je wilt. Jouw factory beheert geen static data.
Ik ken Hibernate niet dus ik kan er weinig over zeggen of de Singleton daar zinnig toegepast is, maar ik wil maar aangeven dat er in situaties zijn waarin er betere alternatieven voor Singletons zijn. De argumentatie "een Singleton kan dus het is goed zo" snijdt dan geen hout, want één van de doelen van Design Patterns is juist om code beter te ontwerpen met alle voordelen van dien, en niet naar de eerste beste methode te grijpen "omdat dat ook werkt".
Ik haalde het aan omdat het een 'factory' genoemd wordt maar de factory creeert 'ISession' instances die feitelijk de static mapping data beheren van de 'factory' (intern daar gewoon naartoe callen). Dus je maakt middels een singleton de static data in de singleton (de mapping data) beschikbaar in iedere instance die je daarin maakt zodat je niet de static data iedere keer opnieuw hoeft te laden. Dat is precies wat je nl. wilt, want die xml parsen kan vele seconden duren, en je wilt dat maar 1 keer. Dan is een singleton precies de juiste oplossing: static data, beheert door een static class die de data aanbiedt als een service.

Lead developer of LLBLGen Pro.
https://fransbouma.com


  • BlackHawkDesign
  • Registratie: maart 2005
  • Laatst online: 15:53
Janoz schreef op zondag 24 oktober 2010 @ 19:33:
[...]
Flink verschil qua scoping issues? Zou je kunnen aangeven wat precies dat flinke verschil is? IMHO heeft een singleton enkel een extra wrappertje, meer verschilt het niet van een globale var.
1) De verantwoordelijkheid van het behouden een instance gebeurd nu in een andere class/file. Je zorgt dus voor een extra afhankelijkheid tussen 2.
2) Ook andere functies die niks met jouw global variable te maken hebben, hebben onnodig toegang tot deze. Je vergroot de scope van je global variable onnodig. Hiermee breek je principes als information hiding.

Bij een singleton leg je de verantwoordelijkheid voor het behouden van een instance bij de class zelf. Naar mijn idee de beste plek. Dus om het nou op een hoop te schuiven met global variablen, vind ik te ver gaan.

  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
BlackHawkDesign schreef op zondag 24 oktober 2010 @ 21:50:
1) De verantwoordelijkheid van het behouden een instance gebeurd nu in een andere class/file. Je zorgt dus voor een extra afhankelijkheid tussen 2.
Dit volg ik even niet?
2) Ook andere functies die niks met jouw global variable te maken hebben, hebben onnodig toegang tot deze. Je vergroot de scope van je global variable onnodig. Hiermee breek je principes als information hiding.
Huh? Iedereen die toegang wil tot die instantie kan er toch bij via de class zelf?

Misschien begrijp ik je niet, maar vind je dat er fundamenteel verschil zit tussen:
C++:
1
2
3
namespace foo {
  extern Bar theBar;
}

Of:
C++:
1
2
3
4
5
6
7
8
9
10
namespace foo { 
  class Bar { 
    public: 
      static Bar &getInstance();
  };
  Bar &Bar::getInstance() {
    static Bar inst;
    return inst;
  }
}

:?

In die zin ben ik het met Janoz eens dat het verschil met een globale variabele verwaarloosbaar is.

[Voor 5% gewijzigd door Soultaker op 24-10-2010 23:19]


  • pedorus
  • Registratie: januari 2008
  • Niet online
:D Iets met ThreadStatic zou wel nuttig kunnen zijn, maar dit is een grap of een wtf.
Soultaker schreef op zondag 24 oktober 2010 @ 23:17:
In die zin ben ik het met Janoz eens dat het verschil met een globale variabele verwaarloosbaar is.
Maar het is wel degelijk een fundamenteel verschil. Een globale variabele kan (per ongeluk, door zeg testcode te laten staan ofzo) opnieuw worden toegewezen met een tweede instantie, waardoor er dus meer dan een instantie ontstaat. Vooral in php lijkt me dit snel gedaan, door zeg een nieuwe databaseconnectie aan te maken terwijl je er maar 1 wil per http-connectie.

In php heb je trouwens eigenlijk geen echte singletons in mijn ogen, omdat ze maar 1 request meegaan, alleen voor dat request gelden en er meerdere requests tegelijkertijd kunnen zijn. Het 'probleem' met singletons lijkt me in php dan ook nihil, en je kan argumenten die voor andere talen gelden dan ook niet zomaar voor php overnemen. :p

Vitamine D tekorten in Nederland | Middelen tegen corona


  • NMe
  • Registratie: februari 2004
  • Laatst online: 18:56

NMe

Quia Ego Sic Dico.

pedorus schreef op maandag 25 oktober 2010 @ 00:49:
[...]

:D Iets met ThreadStatic zou wel nuttig kunnen zijn, maar dit is een grap of een wtf.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
pedorus schreef op maandag 25 oktober 2010 @ 00:49:
Een globale variabele kan (per ongeluk, door zeg testcode te laten staan ofzo) opnieuw worden toegewezen met een tweede instantie, waardoor er dus meer dan een instantie ontstaat.
Dat lijkt me meer een technische kwestie dan een fundamentele. In het C++ voorbeeld dat ik gaf kan dat voor zover ik weet niet edit: mits je de constructor private maakt. Met een final variabele in Java ook niet.

[Voor 5% gewijzigd door Soultaker op 25-10-2010 01:43]


  • BlackHawkDesign
  • Registratie: maart 2005
  • Laatst online: 15:53
Nou zoals je in je code voorbeeld al aangaf, je maakt ergens die globale variabele aan. Stel je doet dit in file1.cpp. Dan hebben we nog onze bar class.

- In het geval van een singleton heb ik alleen de afhankelijkheid tussen de bar class.
- Bij een globale variabele heb ik de afhankelijkheid van de bar class en file1.cpp

Nu kan je zeggen van ja maar ik stop het in een file die door het hele project wordt gebruikt, dus ik was toch al afhankelijk van die file. Toch zorgt dit voor een extra afhankelijkheid. Als ik besluit een methode die mijn singleton gebruikt, te hergebruiken in een tweede project, moet ik in het geval van de globale variabele ook nog die extra globale variabele aanmaken. Bij een singleton, kopier ik de twee classes en klaar ben ik.
[...]
Huh? Iedereen die toegang wil tot die instantie kan er toch bij via de class zelf?
In die zin ben ik het met Janoz eens dat het verschil met een globale variabele verwaarloosbaar is.
In het geval van een singleton heeft iedereen toegang tot die class. Maar niemand heeft toegang tot de implementatie van mijn methode. Immers kan jij garanderen dat niemand die globale variabele op null zet of de instance vervangt voor een nieuwe? Stel methode 1 in class a, gebruik thebar en zet deze daarna op null. Methode 2 in class b, gebruikt daarna thebar en gooit een nullpointer.

Dan kan je beargumenteren dat de gene die methode1 schrijft, een #^#%#(* is die niet zomaal globale variabelen op null moet zetten, maar uit de code kan hij niet halen dat dat niet mag. Een singleton maakt dat niet uit en dwingt gewoon af dat iedere methode zijn eigen instance krijgt ( Ook al is dat overal dezelfde instance).

In de praktijk zal het neerkomen op even snel aanmaken van een nieuwe globale variabele of even debuggen en de programmeur op ze ***** geven die dat ding op null zet. Daarin verschilt het niet veel nee. Toch waarborgt een singleton principes als information hiding en loosly coopling, waar een globale variabele deze schendt. Dus een singleton is een veredelde globale variable, nee dat vind ik dus niet ;)

  • 164019
  • Registratie: december 2005
  • Laatst online: 21-07-2014
Een singleton is een veredelde globale variabele zoals een property een veredeld field is. Het is puur aan de taal zelf of dit een verschil is of niet. In een taal met een complexere access control zou je zonder problemen een globale variabele kunnen gebruiken voor het implementeren van een singleton-patroon.

[Voor 10% gewijzigd door 164019 op 25-10-2010 09:39]


  • Janoz
  • Registratie: oktober 2000
  • Laatst online: 00:52

Janoz

Moderator Devschuur®

!litemod

BlackHawkDesign schreef op maandag 25 oktober 2010 @ 09:23:
[...]

Nou zoals je in je code voorbeeld al aangaf, je maakt ergens die globale variabele aan. Stel je doet dit in file1.cpp. Dan hebben we nog onze bar class.

- In het geval van een singleton heb ik alleen de afhankelijkheid tussen de bar class.
- Bij een globale variabele heb ik de afhankelijkheid van de bar class en file1.cpp

Nu kan je zeggen van ja maar ik stop het in een file die door het hele project wordt gebruikt, dus ik was toch al afhankelijk van die file. Toch zorgt dit voor een extra afhankelijkheid. Als ik besluit een methode die mijn singleton gebruikt, te hergebruiken in een tweede project, moet ik in het geval van de globale variabele ook nog die extra globale variabele aanmaken. Bij een singleton, kopier ik de twee classes en klaar ben ik.
Afhankelijkheid van een bestand waar de class in zit of afhankelijk van een bestand waar de var in zit. Petatoes vs petatoes lijkt mij...
In het geval van een singleton heeft iedereen toegang tot die class. Maar niemand heeft toegang tot de implementatie van mijn methode. Immers kan jij garanderen dat niemand die globale variabele op null zet of de instance vervangt voor een nieuwe? Stel methode 1 in class a, gebruik thebar en zet deze daarna op null. Methode 2 in class b, gebruikt daarna thebar en gooit een nullpointer.
Middels const danwel final is keurig af dwingen dat niemand de instantie overschrijft.
Dan kan je beargumenteren dat de gene die methode1 schrijft, een #^#%#(* is die niet zomaal globale variabelen op null moet zetten, maar uit de code kan hij niet halen dat dat niet mag. Een singleton maakt dat niet uit en dwingt gewoon af dat iedere methode zijn eigen instance krijgt ( Ook al is dat overal dezelfde instance).
hmm, ik nam altijd aan dat iedereen dezelfde instantie kreeg ipv ieder zijn eigen ;).
In de praktijk zal het neerkomen op even snel aanmaken van een nieuwe globale variabele of even debuggen en de programmeur op ze ***** geven die dat ding op null zet. Daarin verschilt het niet veel nee. Toch waarborgt een singleton principes als information hiding en loosly coopling, waar een globale variabele deze schendt. Dus een singleton is een veredelde globale variable, nee dat vind ik dus niet ;)
De information hiding is iets wat in de class Bar geimplementeerd wordt en heeft niks te maken met de manier waarop je aan die class komt. Daarnaast is een Singleton sowieso niet loosely coupled aangezien je altijd vast zit aan die ene implementatie. Voor een loosely coupled oplossing kun je beter naar het Factory pattern kijken. Het enige daadwerkelijke verschil tussen een globale variabele en een singleton is dat het initialiseren van de variabele in het laatste geval op een lazy manier kan gebeuren.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • BlackHawkDesign
  • Registratie: maart 2005
  • Laatst online: 15:53
Janoz schreef op maandag 25 oktober 2010 @ 10:43:
[...]

Afhankelijkheid van een bestand waar de class in zit of afhankelijk van een bestand waar de var in zit. Petatoes vs petatoes lijkt mij...
Maak van die 'of' een 'en'. Immers ook al heb je die var, je blijft die class nodig hebben. Bij een singleton heb je die var niet nodig en alleen maar de class zelf.
[...]
Middels const danwel final is keurig af dwingen dat niemand de instantie overschrijft.
True, niet aan gedacht, heb je gelijk in.
[...]
De information hiding is iets wat in de class Bar geimplementeerd wordt en heeft niks te maken met de manier waarop je aan die class komt.
Ik heb het niet over de information hiding van de Bar class, maar over de file1.cpp. Deze stelt onnodig zijn variabele aan iedereen beschikbaar. Die de verschillende methodes dus gebruiken voor hun implementatie.
Daarnaast is een Singleton sowieso niet loosely coupled aangezien je altijd vast zit aan die ene implementatie.
Koppeling is de mate waarin classes elkaar gebruiken en dus van elkaars bestaan afweten. Oftewel de mate waarin ze afhankelijk zijn van elkaar. Dus de extra afhankelijk die ik steeds aangeef.
[message]Wiki[/message]:
Coupling refers to the degree of direct knowledge that one class has of another. This is not meant to be interpreted as encapsulation vs. non-encapsulation. It is not a reference to one class's knowledge of another class's attributes or implementation, but rather knowledge of that other class itself.
Bron: Wikipedia: Loose coupling
Maar ik ben bang dat we hier niet uit gaan komen. :P Al is het wel een erg leuke discussie :)

  • Janoz
  • Registratie: oktober 2000
  • Laatst online: 00:52

Janoz

Moderator Devschuur®

!litemod

BlackHawkDesign schreef op maandag 25 oktober 2010 @ 12:13:
Ik heb het niet over de information hiding van de Bar class, maar over de file1.cpp. Deze stelt onnodig zijn variabele aan iedereen beschikbaar. Die de verschillende methodes dus gebruiken voor hun implementatie.
Een singleton stelt zijn instance ook aan iedereen beschikbaar.

Er is geen verschil tussen:
code:
1
Bar localBar = Bar.getInstance();

en
code:
1
Bar localBar = womGlobalBar;
Koppeling is de mate waarin classes elkaar gebruiken en dus van elkaars bestaan afweten. Oftewel de mate waarin ze afhankelijk zijn van elkaar. Dus de extra afhankelijk die ik steeds aangeef.
Ik weet wat het is, maar zie geen verschil tussen een object dat je via een getInstance methode krijgt of een object die je uit een globale variabele haalt. In beide gevallen moeten ze die class kennen.
Maar ik ben bang dat we hier niet uit gaan komen. :P Al is het wel een erg leuke discussie :)
Er zijn er maar een paar verschillen tussen een Singleton en een globale variabele en IMHO zijn die verschillen te klein om een singleton en een globale variabale als iets compleet anders te zien.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • pedorus
  • Registratie: januari 2008
  • Niet online
Soultaker schreef op maandag 25 oktober 2010 @ 00:55:
[...]

Dat lijkt me meer een technische kwestie dan een fundamentele. In het C++ voorbeeld dat ik gaf kan dat voor zover ik weet niet. Met een final variabele in Java ook niet.
offtopic:
Maar ook final is stiekem niet final. Tenminste niet op JVM-niveau.

Als het daadwerkelijk zo is dat je het aantal instanties tot 1 hebt beperkt, dan heb je gewoon een alternatieve implementatie van het singleton-pattern. En als je toch meer dan 1 instantie kan krijgen, dan heb je een fundamenteel verschil.. ;)

Een ander fundamenteel verschil kan instantiatie bij noodzaak zijn, in plaats van altijd bij het begin van de applicatie. Maar op zich ben ik het wel met Janoz eens dat de praktische verschillen vrij klein zijn, het is dan ook een klein pattern.. :p

Vitamine D tekorten in Nederland | Middelen tegen corona


  • Hydra
  • Registratie: september 2000
  • Laatst online: 17:00
Janoz schreef op maandag 25 oktober 2010 @ 13:06:
[...]

Een singleton stelt zijn instance ook aan iedereen beschikbaar.

Er is geen verschil tussen:
code:
1
Bar localBar = Bar.getInstance();

en
code:
1
Bar localBar = womGlobalBar;
Het verschil is dat de singleton gegarandeerd maar een keer geinstantieerd wordt. Die globale var kun je overal opnieuw instantieren in princiepe. Daarnaast is een singleton ook zelf verantwoordelijk voor de instantiatie. Ook hoort een instance pas aangemaakt te worden op het moment dat 'ie voor het eerst nodig is, en niet op het moment dat een class geladen wordt (dat kan namelijk al gebeuren voordat je logging framework geconfigureerd is).

Een singleton is dus meer dan gewoon een globale variabele en dat wordt AFAIK ook in 't boek design patterns uitgelegd.
- Altijd maximaal 1 instance
- Zelf verantwoordelijk voor z'n instantiatie
- Aangemaakt ten tijde van first use

Voldoet je 'singleton' niet aan bovenstaande voorwaarden dan is het gewoon geen singleton maar een simpleton.

https://niels.nu

Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee