[php5] singleton factory wil niet lukken

Pagina: 1
Acties:
  • 139 views sinds 30-01-2008
  • Reageer

  • tombo_inc
  • Registratie: December 2004
  • Laatst online: 04-02-2022
ik probeer een factory class de bouwen die singletons fabriceerd. dit wil echter niet lukken omdat ik mijn classname opgeslagen in mijn variabele niet geparsed krijg alszijnde een classname. oftewel de parser zeurt (terecht) om het feit dat ik een double colon gebruik na een variabele. aangezien je bij mijn weten niet kan casten naar een class zou ik niet weten hoe ik dit verder op moet lossen. ik vroeg mij af of hier een manier voor is of dat mijn idee onmogelijk is.

hieronder een voorbeeldje:
PHP:
1
2
3
4
5
6
7
8
9
10
11
class singletonfactory {

  public function getInstanceOf( $classname ) {

    $instance = $classname::getInstance(); //singleton class instantie ophalen
    
    return $instance;

  }

}

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Hmz, variabele functies en classes werken wel in PHP, misschien dat het met die colons niet werkt. (Zou vreemd zijn, m'goed, het blijft PHP.)

Maarre, als je toch een factory bouwt voor je singleton (wat an sich al vreemd is), waarom hou je dan niet gewoon je singleton instances bij in de factory zelf?

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • tombo_inc
  • Registratie: December 2004
  • Laatst online: 04-02-2022
dit is niet helemaal wat ik wil. ik heb namelijk een aantal singleton classen. deze classen zijn soms wel nodig en soms niet, ik wil ze dus alleen instantieren als ze nodig zijn. daarom maak ik een factory die op mijn commando de juiste class moet laden. als ik standaard alle classen instanties bij ga houden in mijn factory dan is het nut van dit principe een beetje weg lijkt mij.
vb:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class singletonfactory {

  public function getInstanceOf( $classname ) {

    $instance = $classname::getInstance(); //singleton class instantie ophalen
    
    return $instance;

  }

} 

$factory = new singletonfactory;
$mijnsingleton = $factory->getInstanceOf( 'eensingletonclass' );

normale classen kan ik gewoon instantieren op deze manier, de variabele classen werken namelijk wel i.c.m. het new keyword, echter dus niet met statische methods.

[ Voor 0% gewijzigd door tombo_inc op 16-11-2006 23:00 . Reden: typo ]

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition


  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 05-10-2024

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Volgens mij begrijp je niet precies wat ik bedoel.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class singletonfactory {

  private $instanceList;

  public function __construct() {
    $this->instanceList = array();
  }

  public function getInstanceOf( $classname ) {

    if(!isset($this->instanceList[$classname]))
      $this->instanceList[$classname] = new $classname;

    return $this->instanceList[$classname];
  }

}

Zoiets.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • tombo_inc
  • Registratie: December 2004
  • Laatst online: 04-02-2022
ik snapte wat je bedoelde :9 . maar dat gaat dus niet werken. jij maakt namelijk de objecten aan d.m.v het new keyword. dat geeft inderdaad een instance van een class en dat werkt perfect. maar dit is niet wat ik wil hebben. ik wil namelijk op die plaats een singleton ophalen en dat doe je niet met het new keyword maar met een static method van de singleton. en daar ligt dus het probleem, in die aanroep. een variabele met daarachter een double colon slikt php niet omdat voor de double colon syntactisch gezien een classname moet staan. ik hoop dat ik het nu duidelijk uitgelegd heb.

maar never mind :)
de call_user_func methode is mijn oplossing. ik kan daarmee namelijk een static method aanroepen op een variabele class, en dat is wat ik nodig had. :)
bedankt in ieder geval voor het meedenken d:)b

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Jij wilt hier per se een singleton gebruiken vanuit een factory. Als die factory toch weet of er al een instance van je class is dan hoef je het toch niet ook nog eens in die class te proppen?

Je bent gewoon hier patterns aan het overusen.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

@tombo_inc: Als je je toch zo blind wil staren op patterns weet je dat een parametrized factory in dit geval liever een static create method kent omdat het geen nut heeft om de factory te instancen. Ook zou je dan weten dat factory pattern niet ideaal is in deze situatie en wel om het volgende. Bij design patterns is de hoofdgedachte het belangrijkst en het is nog maar zo de vraag of het schoolvoorbeeld van een pattern wel altijd contigent kan zijn aan de situatie. Bij parametrized factory pattern is het belangrijkst iig dat je object creatie overlaat aan een methode zonder te vertellen om welke klasse het gaat; de instanties die de factory method dan terug kan geven dienen dan wel eenzelfde interface gemeen te hebben, i.e. allemaal subtype te zijn van 1 supertype (waar men dus de interface mee deelt). De pattern zorgt dus voor abstractie in de creatie van objecten.
In jouw geval geef je al prijs om welke klasse het gaat en dat doet al in zekere zin afbreuk aan abstractie. Daarbij hebben de klassen welliswaar een interface Singleton met getInstance methode gemeen, de vraag is echter wat het praktisch nut van dit alleen is in z'n totaliteit.
Moraal van het verhaal: gebruik patterns alleen als je zo ook begrijpt.

[ Voor 4% gewijzigd door prototype op 17-11-2006 05:17 ]


  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
tombo_inc schreef op donderdag 16 november 2006 @ 23:00:
dit is niet helemaal wat ik wil. ik heb namelijk een aantal singleton classen. deze classen zijn soms wel nodig en soms niet, ik wil ze dus alleen instantieren als ze nodig zijn. daarom maak ik een factory die op mijn commando de juiste class moet laden. als ik standaard alle classen instanties bij ga houden in mijn factory dan is het nut van dit principe een beetje weg lijkt mij.
vb:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class singletonfactory {

  public function getInstanceOf( $classname ) {

    $instance = $classname::getInstance(); //singleton class instantie ophalen
    
    return $instance;

  }

} 

$factory = new singletonfactory;
$mijnsingleton = $factory->getInstanceOf( 'eensingletonclass' );

normale classen kan ik gewoon instantieren op deze manier, de variabele classen werken namelijk wel i.c.m. het new keyword, echter dus niet met statische methods.
Wat is hier precies het nut van? Als je toch aan je factory de class name moet specificeren en je factory roept alleen maar getInstance() op die class aan dan kan je dat toch net zo goed direct doen? Ik zie niet hoe dit jouw probleem van het alleen instantieren van singletons als je ze nodig hebt oplost. Ik zie de meerwaarde van de factory niet.

Als je dat probleem wil oplossen kan je gewoon een singleton met lazy instantiation maken. Waarbij de static getInstance() methode dus gewoon checkt of de static instance null is of niet, zo ja dan maakt hij een nieuwe instantie en returnt die. Zo nee dan returnt hij gewoon de bestaande instantie.

Roep je getInstance op je singleton nooit aan dan wordt hij ook nooit geinstantieerd.

Verwijderd

Ik neem maar even aan dat het gaat om een webapplicatie. Wat is dan het nut van lazy initialisation in een langlopend process?

Verwijderd

Verwijderd schreef op vrijdag 17 november 2006 @ 10:35:
Ik neem maar even aan dat het gaat om een webapplicatie. Wat is dan het nut van lazy initialisation in een langlopend process?
Ik begrijp je vraag niet. Wat je bedoel je hiermee?

Verwijderd

Verwijderd schreef op vrijdag 17 november 2006 @ 10:43:
Ik begrijp je vraag niet. Wat je bedoel je hiermee?
Dat het vrij nutteloos is om lazy te initialiseren in een langlopend process. De kans is immers vrij groot dat elke instantie uiteindelijk wordt geladen. Dus het aanmaken van een instantie in de getInstance method is vrij nutteloos. Maak deze gewoon aan bij het inladen van de applicatie (hoewel ik me wel realiseer dat php hierin hoogstwaarschijnlijk vrij beperkt is).

Verwijderd

Ok, als je ervan uit kunt gaan dat iedere singleton vrijwel altijd gebruikt gaat worden dan kan ik me daar iets bij voorstellen. Er zijn echter ook situaties waarbij dit niet het geval is en dan kan lazy instantiation weer nuttig zijn (niet dat het de holy grail o.i.d. is).

Dus ik zie eigenlijk niet zo in waarom je het niet zou gebruiken en daarom vroeg ik me dat dus af :).

Verwijderd

Verwijderd schreef op vrijdag 17 november 2006 @ 11:04:
Dus ik zie eigenlijk niet zo in waarom je het niet zou gebruiken en daarom vroeg ik me dat dus af :).
Omdat bij lazy-initialization ook threading een duidelijk rol gaat spelen. Twee threads die gelijktiijdig voor het eerst de instantie gaan opvragen kunnen er voor zorgen dat er meer dan 1 instantie van de singleton class bestaan. Je zal dus moeten synchroniseren. En dat maakt het nodeloos complex...

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
Sinds wanneer is een PHP script een langlopend proces?

Ze handelen een request af en dan is het weer finito. Als je dan wat cpu cycles en resources kan besparen door niet nodeloos allerlei classes te gaan instantieren die je executie pad mogelijk helemaal niet gaat gebruiken waarom zou je dat dan nalaten?. Tuurlijk hangt het uiteindelijk nut grotendeels af van wat die singletons dan allemaal doen op het moment dat er een instantie aangemaakt wordt. Maar als je er classes tussen hebt zitten die met een database aan de haal gaan of met file I/O (config files parsen, ofzo) dan kan je toch wat tijd besparen.

En het is niet zo dat een lazy singleton maken veel extra moeite kost (ik zou zelfs zeggen geen extra moeite) en die extra null check in de getInstance() zal je ook niet in de performance terug zien.

Ik zie niet direct een overduidelijk reden waarom je dit zou vermijden.

Verwijderd

Verwijderd schreef op vrijdag 17 november 2006 @ 11:11:
[...]
Omdat bij lazy-initialization ook threading een duidelijk rol gaat spelen. Twee threads die gelijktiijdig voor het eerst de instantie gaan opvragen kunnen er voor zorgen dat er meer dan 1 instantie van de singleton class bestaan. Je zal dus moeten synchroniseren. En dat maakt het nodeloos complex...
Dat is me bekend. Maar voor zover ik weet is het niet mogelijk binnen PHP om threading te gebruiken dus dit probleem doet zich volgens mij niet voor. En dus is het ook niet nodeloos complex :).

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
Verwijderd schreef op vrijdag 17 november 2006 @ 11:11:
[...]
Omdat bij lazy-initialization ook threading een duidelijk rol gaat spelen. Twee threads die gelijktiijdig voor het eerst de instantie gaan opvragen kunnen er voor zorgen dat er meer dan 1 instantie van de singleton class bestaan. Je zal dus moeten synchroniseren. En dat maakt het nodeloos complex...
Dat is een goed punt, ware het niet dat PHP geen ingebouwde mogelijkheden heeft voor multi-threading. Dus alles is in PHP gewoon per definitie thread-safe.

Verwijderd

CAIRATH schreef op vrijdag 17 november 2006 @ 11:13:
[...]
Maar als je er classes tussen hebt zitten die met een database aan de haal gaan of met file I/O (config files parsen, ofzo) dan kan je toch wat tijd besparen.
[...]
Dit zou voor mij inderdaad de reden zijn om standaard lazy initialization te gebruiken. Mocht PHP ooit (:*)) multi-threading gaan ondersteunen dan heeft Mark hier een goed punt.

Verwijderd

Jullie hebben gelijk, soms verbeeld ik me wel eens dat php daadwerkelijk een fatsoenlijke taal is ;) Dan heeft singleton (wat al een beperkt bestaansrecht heeft) helemaal geen bestaansrecht binnen php.

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op vrijdag 17 november 2006 @ 11:23:
Jullie hebben gelijk, soms verbeeld ik me wel eens dat php daadwerkelijk een fatsoenlijke taal is ;) Dan heeft singleton (wat al een beperkt bestaansrecht heeft) helemaal geen bestaansrecht binnen php.
Hoezo niet? Ik instantieer twee modules die elk DB aanroepen moeten doen. Dan is het best fijn om maar 1 instantie van de DB module af te dwingen.

Wat de TS gewoon fout doet is een factory pattern en een singleton pattern te combineren, want als je een factory gebruikt dan hoef je die singleton implementatie niet te maken, dat laat je de factory doen.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Verwijderd

Omdat je simpelweg 1 instantie door kan geven. Heb je heel singleton niet voor nodig.

  • maartenba
  • Registratie: November 2001
  • Laatst online: 29-07-2024
Losstaand van de discussie, ik vermoed dat je hier wel mee verder kan:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class singletonfactory {

  public function getInstanceOf( $classname ) {

    $instance = call_user_func($classname, 'getInstance'); //singleton class instantie ophalen
    
    return $instance;

  }

}
?>

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
Waarom niet de standaard vorm van een Singleton gebruiken?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

class Singleton
{
    private static $instance;

    public static function getInstance()
    {
        if ( is_null(self::$instance) )
        {
            self::$instance = new Singleton();
        }
        return self::$instance;
    }
}

?>

Zo doet ie toch precies wat je wilt?

Zo'n SingletonFactory lijkt me vrij nutteloos eerlijk gezegd. Misschien dat je er goede redenen voor hebt, daar ben ik wel benieuwd naar dan.

Noushka's Magnificent Dream | Unity


Verwijderd

Grijze Vos schreef op vrijdag 17 november 2006 @ 11:46:
Hoezo niet? Ik instantieer twee modules die elk DB aanroepen moeten doen. Dan is het best fijn om maar 1 instantie van de DB module af te dwingen.
Wat Mark volgens mij wil aangeven is het volgende:
Bron: Wikipedia - Singleton pattern
In software engineering, the singleton design pattern is used to restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. Sometimes it is generalized to systems that operate more efficiently when only one or a few objects exist. It is also considered an anti-pattern since it is often used as a euphemism for global variable. Before designing a class as a singleton, it is wise to consider whether it would be enough to design a normal class and just use one object.
Daarom is het gebruik van een singelton om een database connectie te pakken te krijgen misschien ook wel niet zo goed en zou je dat op een andere manier willen doen. Verder is deze oplossing minder goed onderhoudbaar want stel dat ik nu meerdere database connecties wil hebben, wat dan? Het singelton pattern zegt dat er maar één instantie kan bestaan maar bij een database connectie is het toch mogelijk om meerdere connecties te hebben... dus kun je je afvragen of het gebruik van het singelton pattern hier dan goed is.

Het gebruik van het singelton pattern is dus alleen maar bruikbaar bij objecten waarvan maar één instantie kan bestaan. Gaat je applicatie uit van maximaal één database connectie dan valt er iets voor te zeggen maar persoonlijk ben ik er in dat geval geen voorstander van.

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op vrijdag 17 november 2006 @ 11:50:
Omdat je simpelweg 1 instantie door kan geven. Heb je heel singleton niet voor nodig.
Dat is wat ik gedaan heb in mijn stukje code een paar posts omhoog. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • tech-no-logical
  • Registratie: December 2000
  • Laatst online: 01-12 14:04
stukje zoals ik het gebruik, denk dat dit is wat de ts zoekt ?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class SingletonNode {

        private static $instances;
        protected static $errorNode;

        private function __construct() { }

        public static function getInstanceOf($class) {
                if(!isset(self::$instances[$class])) {
                        self::$instances[$class] = new $class;
                }
                return self::$instances[$class];
        }

Verwijderd

even voor mijn begrip: is een php static var een thread/request-scope static?

Verwijderd

Verwijderd schreef op vrijdag 17 november 2006 @ 12:42:
even voor mijn begrip: is een php static var een thread/request-scope static?
Ja, volgens mij wel.

  • tech-no-logical
  • Registratie: December 2000
  • Laatst online: 01-12 14:04
php heeft (behoudens sessie-spul) niets dat een request overleeft, dus ja. een singleton heeft (iig voor mij) ook altijd een levensduur zolang als 't request.

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

tech-no-logical schreef op vrijdag 17 november 2006 @ 12:24:
stukje zoals ik het gebruik, denk dat dit is wat de ts zoekt ?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class SingletonNode {

        private static $instances;
        protected static $errorNode;

        private function __construct() { }

        public static function getInstanceOf($class) {
                if(!isset(self::$instances[$class])) {
                        self::$instances[$class] = new $class;
                }
                return self::$instances[$class];
        }
Dat is toch min of meer een implementatie van het registry pattern.

Systeem | Strava


  • tech-no-logical
  • Registratie: December 2000
  • Laatst online: 01-12 14:04
Brakkie schreef op vrijdag 17 november 2006 @ 13:16:
Dat is toch min of meer een implementatie van het registry pattern.
klopt. het groeide bij mij echter uit een implementatie die begon als singleton, en uiteindelijk werd tot een baseclass (de singleton) en een set extended classes die dezelfde interface implementeren. de baseclass is daarmee een soort van gepromoveerd tot de registry.

Verwijderd

Dit is toch geen singleton wat je dan krijgt. Het is inderdaad een registry wat hier beschreven wordt.

Nogmaals, wanneer een object het singleton pattern implementeert is het niet mogelijk om meerdere instanties van het object te hebben (binnen welke scope dan ook). Dat kan hier dus wel... voorbeeld:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class SingletonNode {
  private static $instances = array();

  private function __construct() {
  }

  public static function getInstanceOf($class) {
    if(!isset(self::$instances[$class])) {
      self::$instances[$class] = new $class;
    }
    
    return self::$instances[$class];
  }
}

class Registry {
}

$reg1 = SingletonNode::getInstanceOf('Registry');
$reg2 = new Registry();


Edit: ok, het is je dus wel duidelijk :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 14:25

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op vrijdag 17 november 2006 @ 12:42:
even voor mijn begrip: is een php static var een thread/request-scope static?
Voor je begrip, de enige scopes die php kent zijn request, class en function. Session, page en aplpication scope heeft php niet en zelfs een foreach lekt zijn looping parameters naar global scope.

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


  • tech-no-logical
  • Registratie: December 2000
  • Laatst online: 01-12 14:04
Verwijderd schreef op vrijdag 17 november 2006 @ 13:26:

Edit: ok, het is je dus wel duidelijk :)
ter aanvulling : de extended classes hebben (natuurlijk) een protected constructor... misschien dat 't alles hierdoor voor de ts misschien wat minder toepasbaar is, en ts beter een volledig geimplementeerd registry-pattern kan gebruiken...

  • tombo_inc
  • Registratie: December 2004
  • Laatst online: 04-02-2022
Michali schreef op vrijdag 17 november 2006 @ 12:03:
Zo'n SingletonFactory lijkt me vrij nutteloos eerlijk gezegd. Misschien dat je er goede redenen voor hebt, daar ben ik wel benieuwd naar dan.
ten eerste is mijn probleem al opgelost m.b.v. de call_user_func functie. namelijk op de manier die maartenba ook al liet zien. :)

ten tweede zal ik uitleggen waarom ik voor deze methode kies omdat dat voor de meeste van jullie niet duidelijk is. daarbij moet ik zeggen dat ik deze oplossing net wat anders gebruik dan de voorbeelden die ik gepost heb in dit topic, omdat dat het simpeler hield. hier dus mijn situatie:

ik ben bezig met een framework c.q. grote code bibliotheek. nou wil ik een interface maken naar die code bibliotheek en daarmee wil ik mijn onderliggende library structuur abstraheren voor het bovenliggende systeem. ik heb dus een heleboel componenten/classes die ik in mijn te bouwen applicatie wil kunnen gebruiken. de interface van mijn framework implementeerd nu functionaliteit om instanties van die componenten/classes te krijgen. mijn interface is hier dus een factory die classe instanties terug geeft.
vb:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class mainfactory {

  public static function getInstanceOf( $componentname ) {
    //map componentnaam naar classenaam ($classname)
    //laad classfile
    //check singleton of niet
    if( $is_singleton ) {
      $instance = call_user_func( array( $classname, 'getInstance' ) );
    } else {
      $instance = new $classname;
    }
    return $instance;
  }
}

//vb
$sesshandler = mainfactory::getInstanceOf( 'sessionhandler' ); //haal een sessionhandler object op

omdat ik in mijn framework zowel singletons als niet singletons gebruik moet mijn factory zowel singletons als niet singletons terug kunnen geven. omdat ik tevens de gebruiker niet lastig wil vallen met classe namen gebruik ik eenvoudige en duidelijke componentnamen. de factory zorgt er vervolgens voor dat de juiste classes geladen worden. wat ik dus niet wil is om standaard al mijn objecten te laden, want dat genereerd een hele berg overhead die helemaal niet nodig is, aangezien vaak lang niet alle componenten gebruikt worden in de applicatie.

ik hoop dat ik met dit voorbeeld duidelijk heb kunnen maken waarom ik voor deze aanpak gekozen heb. en ik hoop dat jullie het nu met mij eens zijn. commentaar is altijd welkom want ik wil uiteraard horen of het beter kan etc. :)

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
Ok, een goede reden, maar ik zie toch een betere oplossing. Ik zou dan toch gebruik maken van het Abstract Factory pattern (een variant), omdat dit je nog meer flexibiliteit geeft. Stel je wilt een class instantieren met enkele parameters, in je huidige oplossing is dat niet mogelijk. Of je wilt een component opbouwen samen met andere objecten afhankelijk van het platform of database oid. en je wilt dit niet door je class zelf laten regelen (wat je meestal niet wilt), dan krijg je problemen.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php

$componentFactoryClassMap = array(
    'component1' => 'Component1Factory',
    'component2' => 'component_2_factory',
    'component3' => 'Comp3Fact'
);

class Component1Class {} // Singleton
class component_2_class {} // geen Singleton
class component3 {} // constructor met paramters

interface ComponentFactory
{
    public function create();
}

class Component1Factory implements ComponentFactory 
{
    public function create()
    {
        return Component1Class::getInstance();
    }
}

class component_2_factory implements ComponentFactory 
{
    public function create()
    {
        return new component_2_class();
    }
}

class Comp3Fact implements ComponentFactory 
{
    public function create()
    {
        return new component3($param1, $param2);
    }
}

class ComponentManager
{
    public static function getComponent($name)
    {
        if ( isset($GLOBALS['componentFactoryClassMap'][$name]) )
        {
            $factoryClass = $GLOBALS['componentFactoryClassMap'][$name];
            $factory = new $factoryClass;
            return $factory->create();
        }
        return null; // of een exception gooien, wat je wilt
    }
}

?>

Je wilt duidelijk gebruik maken van polymorphisch gedrag, dan moet je er niet om heen gaan draaien, maar het ook werkelijk zo toepassen. Deze oplossing geeft je veel meer mogelijkheden. Het creëren van het object kun je nu regelen zoals je wilt.

Mocht je het nodig vinden (afhankelijk van hoe vaak je een component ophaalt), kun je de factory objecten ook cachen. Als dit niet nodig is, dan kun je het zo laten. Een objectje extra instantieren levert niet zo veel problemen op.

Noushka's Magnificent Dream | Unity


  • tombo_inc
  • Registratie: December 2004
  • Laatst online: 04-02-2022
ok dat ziet er interessant uit. :) ik probeer even te snappen wat je doet, als ik het niet goed zeg moet je me verbeteren.

je hebt 3 verschillende typen classen (maar dat mogen er natuurlijk meer zijn). voor ieder type class maak je een eigen factory class aan die afgestemt is om een object van 1 type te instantieren.
jij hebt dus 3 factory classen omdat je 3 verschillende soorten classen hebt.
vervolgens heb je je parent factory die dient als een soort wrapper voor de losse type factories, en dus de juiste factories aan roept.
klopt mijn gedachtegang?

wat ik me dan alleen nog afvraag bij type 3, met die parameters is hoe je die parameters meegeeft. want dat kan ik nog niet helemaal volgen.

en tot slot. deze aanpak die je me hier laat zien, wordt die veel gebruikt? het kost je immers wel een hoop extra classen, dit wordt dus niet als nadeel ervaren?

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
Die parameters kun je overal vandaan halen waar je wilt. Een configuratie waarde, een constant, etc.

Je redenatie klopt verder wel. Je hebt verschillende classes, die elk een eigen manier voor het verkrijgen van een instantie hebben, maar je wilt dit wegwerken voor de client. Dan maakt je dus een interface die het gewenste gedrag uitvoert (in dit geval een instantie maken of verkrijgen), en die laat je voor de verschillende classes implementeren.

Dit kan niet in het component zelf, omdat die al voor andere doelen wordt gebruikt. Hiervoor maak je gewoon een aparte class. Overigens kun je veel voorkomende implementaties gewoon generaliseren. Scheelt je ook weer werk.

Of deze aanpak veel wordt gebruikt? Ik heb het nog nooit zo toegepast, maar ze zeggen ook wel dat ieder gebruik van een pattern meestal uniek is, als de redenen voor het gebruik maar goed zijn. Verder denk ik dat het zo niet heel veel wordt toegepast, omdat je iets probeert dat (naar mijn idee) sowieso niet heel gebruikelijk is.

Noushka's Magnificent Dream | Unity

Pagina: 1