Singleton en constructorparameters

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Bv202
  • Registratie: Oktober 2006
  • Laatst online: 14-11-2021
Hey,

Ik heb een klasse waarbij de constructor een aantal parameters accepteert:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

class Singleton {
  private $var1;
  private $var2;

  public function __construct($param1, $param2) {
    $this->var1 = $param1;
    $this->var2 = $param2;
  }
}

?>


Simpel. Van deze klasse wil ik nu echter een Singleton maken (en ja, ik ben zeker dat ik een Singleton wil). Ik zou hier gewoon een getInstance()-methode kunnen maken die ook deze 2 parameters accepteert en deze parameters dan gebruikt bij het oproepen van de constructor.

Het probleem is dat deze parameters niet overal beschikbaar zijn en het me ook zinloos lijkt om bij elke getInstance()-call deze parameters mee te geven wanneer je 100% zeker weet dat het object al bestaat (en de parameters dus niet nodig zijn).

Mijn huidige oplossing is het gebruiken van optionele parameters (het is PHP), maar dat lijkt me niet de beste oplossing.

Hoe los ik dit probleem best op? Pas ik hier een Singleton helemaal verkeerd toe en ben ik verkeerd bezig?

Bedankt!

Acties:
  • 0 Henk 'm!

Verwijderd

Waarom kun je parameters meegeven aan je instance? Wat betekent het als je daarna nogmaals de static function getInstance aanroept met andere parameters?

Normaal gesproken zou je getInstance zonder parameters aanroepen. Daarna heb je je instance en kun je op de plaatsen waar nodig parameters doorgeven met een andere method.

code:
1
2
$instance = Singleton::getInstance ();
$instance->setParameters($param1, $param2);


Dat is de nette manier om dit te doen, omdat nergens meer onduidelijkheid hoeft te zijn.

En tóch heb ik het gevoel dat het weer om een database-klasse gaat ;)

[ Voor 7% gewijzigd door Verwijderd op 13-07-2011 18:11 ]


Acties:
  • 0 Henk 'm!

  • Webgnome
  • Registratie: Maart 2001
  • Laatst online: 15:58
Zoals cheatah al aangeeft. Waarom zou je parameters aan willen geven bij het initieren van je instance? Als je singleton afhankelijk is van een x aantal parameters dan kun je deze beter
  • door de singleton laten getten en setten in een configuratie
  • bekijken of dat deze echt wel nodig zijn
  • of het dan misschien niet beter is om een factory class te gebruiken waarbij je zegt factory-> geef nieuwe instance(parm1,param2);
Maar dit is nogal koffiedik kijken zonder enige context.

[ Voor 10% gewijzigd door Webgnome op 13-07-2011 18:31 ]

Strava | AP | IP | AW


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Een registry gerbuiken ipv een singleton. Of een registry gebruiken voor je params die getinstance dan uitleest. Hoe kun je zo zeker van je (singleton) zaak zijn als je niet eens weet hoe je het op moet lossen?

Acties:
  • 0 Henk 'm!

  • Bv202
  • Registratie: Oktober 2006
  • Laatst online: 14-11-2021
Verwijderd schreef op woensdag 13 juli 2011 @ 18:11:
Waarom kun je parameters meegeven aan je instance? Wat betekent het als je daarna nogmaals de static function getInstance aanroept met andere parameters?

Normaal gesproken zou je getInstance zonder parameters aanroepen. Daarna heb je je instance en kun je op de plaatsen waar nodig parameters doorgeven met een andere method.

code:
1
2
$instance = Singleton::getInstance ();
$instance->setParameters($param1, $param2);


Dat is de nette manier om dit te doen, omdat nergens meer onduidelijkheid hoeft te zijn.

En tóch heb ik het gevoel dat het weer om een database-klasse gaat ;)
Bedankt, ik ga eens kijken naar deze oplossing (en een registry, zoals hierboven is aangehaald).
En tóch heb ik het gevoel dat het weer om een database-klasse gaat ;)
Hoe kun je zo zeker van je (singleton) zaak zijn als je niet eens weet hoe je het op moet lossen?
Klopt, het gaat hier over een Database-klasse en ja, ik heb de discussie in dat andere topic hierover gelezen. Het probleem is dat ik met een hoop functionele procedurele code aan het werken ben (die later nog herschreven moet worden) waarbij ik, zonder Singleton, bij elke functie-call als parameter het DB-object zou moeten meegeven. Deze code ben ik nog van plan te herschreven in OO, maar dat zal pas voor later zijn. Ik ben dan ook van plan om deze Database-klasse weer te herbekijken nadat alles OO is (en er dus geen Singleton meer van te maken)

Waarschijnlijk krijg ik op deze aanpak een hoop commentaar/kritiek; laat maar komen. Als iemand een betere manier van werken heeft (vast wel, want dit is de eerste keer dat ik functionele procedurele code refactor naar OO), hoor ik dat graag :P

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Bv202 schreef op woensdag 13 juli 2011 @ 18:38:
Waarschijnlijk krijg ik op deze aanpak een hoop commentaar/kritiek; laat maar komen. Als iemand een betere manier van werken heeft (vast wel, want dit is de eerste keer dat ik functionele code refactor naar OO), hoor ik dat graag :P
offtopic:
Je bedoelt precedurele code, functionele code is code die werkt of je doelt op Functional Programming, wat AFAIK (nog) niet (volledig) kan in PHP :P

Als het werkt voor jou en je daardoor beter overzicht hebt of beter kunt werken in je eigen workflow zoals je die graag hanteert dan moet je dat vooral doen. Soms moet je gewoon pragmatisch zijn en allerlei "religieuze" of "theoretische" zaken lekker aan de kant zetten. Waarmee je natuurlijk geen groen licht hebt om 't altijd zomaar te doen; maar als je 't kunt verdedigen: boeie.

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

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

Verwijderd

RobIII schreef op woensdag 13 juli 2011 @ 18:50:
[...]

offtopic:
Je bedoelt precedurele code, functionele code is code die werkt of je doelt op Functional Programming, wat AFAIK (nog) niet kan in PHP :P

Als het werkt voor jou en je daardoor beter overzicht hebt of beter kunt werken in je eigen workflow zoals je die graag hanteert dan moet je dat vooral doen. Soms moet je gewoon pragmatisch zijn en allerlei "religieuze" of "theoretische" zaken lekker aan de kant zetten. Waarmee je natuurlijk geen groen licht hebt om 't altijd zomaar te doen; maar als je 't kunt verdedigen: boeie.
Eens. In deze situatie waar je met een bestaand gedrocht zit, kun je dan beter ergens in het begin een connectie initialiseren op de manier die ik aangaf. Het is niet mooi, maar het werkt.

Als je echter de luxe hebt dat je van begin af aan een applicatie kunt opzetten, zou ik het absoluut niet met een singleton doen omdat dat enorm beperkend is en juist problemen kan geven in een later stadium, als ineens extra eisen worden gesteld.

Acties:
  • 0 Henk 'm!

  • Bv202
  • Registratie: Oktober 2006
  • Laatst online: 14-11-2021
Een andere oplossing waar ik net aan denk (dus zonder singleton) is simpelweg het gebruik van globals in deze functies. Ook niet de mooiste oplossing, maar daardoor kan ik deze singleton wel vermijden.

Sowieso weet ik dat een singleton niet de oplossing is hier. Sterker nog, ik ben van plan de applicatie uit te breiden met functionaliteit waarvoor een tweede databaseverbinding nodig is.

Ik denk dus dat ik het op deze manier ga doen. Bedankt voor de reacties; ik ga me zeker eens verdiepen in een registry en dergelijke :)

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Nou ja, begin in dat geval maar gewoon meteen met een simpele registry die je db instance kan bewaren.

Lees: begin met lezen. :P

{signature}


Acties:
  • 0 Henk 'm!

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 15:24
Als ik een DB-singleton maak in PHP doe ik meestal zoiets:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
class dbconnection extends PDO {

    private static $instance;

    public function __construct() {}
    private function __clone() {}

    public static function getInstance() {
        if (!dbconnection::$instance instanceof PDO) {
            try {
                dbconnection::$instance = new PDO('mysql:dbname=databeestnaam;host=localhost', 'aap', 'wachtwoord');
            } catch (PDOException $e) {
                echo 'Connection failed: ' . $e->getMessage();
            }
        }
        
        return dbconnection::$instance;
    }
}
?>


Je kunt je username + wachtwoord ook gewoon wegstoppen in een Apache-dingetje (ik ben kwijt hoe dat heet, zo'n soort constante die je kunt definiëren), dan staat ie niet in je code dus kun je probleemloos je code openbaar maken.

Wellicht heb je er wat aan, het is in ieder geval een snippet die ik mezelf keer op keer zie gebruiken voor kleine sites :)

Acties:
  • 0 Henk 'm!

  • ZeroXT
  • Registratie: December 2007
  • Laatst online: 11:20
Je kunt je username + wachtwoord ook gewoon wegstoppen in een Apache-dingetje (ik ben kwijt hoe dat heet, zo'n soort constante die je kunt definiëren), dan staat ie niet in je code dus kun je probleemloos je code openbaar maken.
Ik ben wel benieuwd naar dit stukje code. Zal het betrekking hebben met een Vhost of wellicht een gewone .htacces file?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
ZeroXT schreef op donderdag 14 juli 2011 @ 00:43:
[...]


Ik ben wel benieuwd naar dit stukje code. Zal het betrekking hebben met een Vhost of wellicht een gewonen .htacces file?
<VirtualHost *>
        ...
        SetEnv FOO bar
        ...
</VirtualHost>


PHP:
1
2
echo getenv('Foo');
echo apache_getenv('Foo');


bar
bar

Voila.

[ Voor 26% gewijzigd door RobIII op 14-07-2011 00:57 ]

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

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 15:24
Dat was het inderdaad :)

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Waar je eigenlijk gewoon naar op zoek bent is een simpele builder. De hele singleton discussie doet er eigenlijk niet eens toe. Overigens ga je dan het hele idee van een dependency injection container ook wel boeiend vinden. Dat is eigenlijk een combinatie van een builder en een registry. Genoeg google termen bij elkaar, dacht ik zo. Ik heb niet zo veel zin om er linkjes bij te zoeken. :P

Tot slot: hét probleem met singletons is (imo) testbaarheid. Schaalbaarheid maakt idd een goeie tweede.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

Ik zeg ook, Dependency Injection +1! :)

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
HMS schreef op donderdag 14 juli 2011 @ 03:08:
Ik zeg ook, Dependency Injection +1! :)
Maak daar maar +2 van.

Imho is het enige juiste antwoord op dit type probleem om IoC met DI toe te passen. Dan kan het later ook nog eens makkelijk worden om via een een lifetime manager connecties te poolen voor hergebruik, usw.
Pagina: 1