[PHP 5] Abstract protected constructor

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

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Abstract protected constructor

Ik wil dat als je de abstracte class extend; dat de constructor alleen protected mag zijn en niet public of private. Om wat duidelijker te zijn geef ik even een voorbeeldje:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// PHP 5

abstract class Pattern
{
    abstract protected function __construct();
}

class Raspberry extends Pattern
{
    /*
    * De constructor is public terwijl in
    * de abstracte class `Pattern` staat
    * dat het een protected methode moet
    * zijn.
    */
    public function __construct()
    {
        echo "Trapt inside this Octavarium!";
    }
}

?>
Het voorbeeld geeft geen error. Maar als je de constructor van 'Raspberry' private maakt dan krijg ik de output:
Fatal error: Access level to Raspberry::__construct() must be protected (as in class Pattern) or weaker
Dit is goed want ik wil niet dat de constructor private toegankelijk is maar ik wil ook niet dat hij public (weaker) toegankelijk is.

Kortom: Hoe zorg ik ervoor dat de constructor alleen protected kan zijn?

PS : Het is voor een Singleton class.

Take care,
Pherion

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Als ik naar de foutmelding kijk valt vooral de 'or weaker' op. Waarschijnlijk kan het dus helemaal niet.

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


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op vrijdag 28 april 2006 @ 15:58:
Als ik naar de foutmelding kijk valt vooral de 'or weaker' op. Waarschijnlijk kan het dus helemaal niet.
Daarom zoek ik dus een oplossing... Is het misschien mogelijk om te controleren of een member / methode public, protected of private is?

[ Voor 3% gewijzigd door Verwijderd op 28-04-2006 16:00 ]


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Errr, is dat niet gewoon protected function __construct() { } in je concrete klasse (Rasberry)?
[edit]
Ah, ik begrijp je probleem nu :) Zoals al eerder gezegd, waarschijnlijk kan het gewoon niet gezien de foutmelding.

[ Voor 40% gewijzigd door prototype op 28-04-2006 16:01 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
prototype schreef op vrijdag 28 april 2006 @ 15:59:
Errr, is dat niet gewoon protected function __construct() { } in je concrete klasse (Rasberry)?
[edit]
Ah, ik begrijp je probleem nu :) Zoals al eerder gezegd, waarschijnlijk kan het gewoon niet gezien de foutmelding.
Ja dat is de bedoeling, maar dat moet dus aangegeven worden door die abstracte class. Zonder protected __constructor() heeft het namelijk geen zin om de class te gebruiken.

edit:

Inderdaad, misschien is er een andere oplossing...

[ Voor 7% gewijzigd door Verwijderd op 28-04-2006 16:03 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Een abstracte constructor.... Dat lijkt me wel heel sterk...
AFAIK kan een constructor nooit abstract zijn.

Ik weet natuurlijk niet hoe het in PHP zit, maar het is toch gewoon onlogisch om een abstracte (virtuele) constructor te hebben. Stel dat het zou mogelijk zijn, hoe weet je dan welke constructor je precies moet aanroepen ?

(En inherited singletons vind ik al helemaal raar eigenlijk.... Een singleton zorgt ervoor dat je max. 1 instantie van een class kunt hebben, maar als je subtypes gaat creeëren van een class, die op hun beurt dan ook weer singletons zijn, .... dan heb je in princiepe meer dan 1 instance van die class).

Je moet trouwens die constructor van je inherited class niet private maken, maar ook protected.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
whoami schreef op vrijdag 28 april 2006 @ 16:02:

(En inherited singletons vind ik al helemaal raar eigenlijk.... Een singleton zorgt ervoor dat je max. 1 instantie van een class kunt hebben, maar als je subtypes gaat creeëren van een class, die op hun beurt dan ook weer singletons zijn, .... dan heb je in princiepe meer dan 1 instance van die class).

Je moet trouwens die constructor van je inherited class niet private maken, maar ook protected.
Weet ik maar dat was voor het voorbeeld. En een constructor kan wel abstract zijn. Je kan toch verplichten aan een class dat hij een constructor heeft. Is ook gewoon een method.

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
<?php
// PHP 5

abstract class Singleton
{
    private static $instance = array();

    abstract public static function getInstance();
    abstract protected function __construct();

    private function __clone()
    {
        // Prevent clones
    }

    public static function singleton($class)
    {
        if(!isset(self::$instance[$class]))
        {
            self::$instance[$class] = new $class;
        }

        return self::$instance[$class];
    }
}

class MyClass extends Singleton
{
    protected function __construct()
    {
        echo "test";
    }  

    public static function getInstance()
    {
        return parent::singleton(__CLASS__);
    }
}

$object01 = MyClass::getInstance();

?>

[ Voor 58% gewijzigd door Verwijderd op 28-04-2006 16:14 ]


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver

March of the Eagles


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Verwijderd schreef op vrijdag 28 april 2006 @ 16:05:
[...]


Weet ik maar dat was voor het voorbeeld. En een constructor kan wel abstract zijn. Je kan toch verplichten aan een class dat hij een constructor heeft. Is ook gewoon een method.
Mja, dat zal dan wel weer php-specifiek zijn.
Een abstracte constructor, dat zou niet mogen kunnen.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
whoami schreef op vrijdag 28 april 2006 @ 16:25:
[...]

Mja, dat zal dan wel weer php-specifiek zijn.
Een abstracte constructor, dat zou niet mogen kunnen.
Wat heb ik aan zo'n antwoord?

@ Hacku : ik zal het doornemen!

[ Voor 8% gewijzigd door Verwijderd op 28-04-2006 16:36 ]


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 15:13
Ik zie het probleem nog steeds niet. Je wil een protected constructor, en in bovenstaand voorbeeld laat je een protected constructor zien. Wat is het probleem nou eigenlijk?

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
sig69 schreef op vrijdag 28 april 2006 @ 16:36:
Ik zie het probleem nog steeds niet. Je wil een protected constructor, en in bovenstaand voorbeeld laat je een protected constructor zien. Wat is het probleem nou eigenlijk?
Hij mag geen public zijn.

Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 15:13
Dat is ie toch ook niet als ie protected is?

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

Verwijderd

sig69 schreef op vrijdag 28 april 2006 @ 16:40:
Dat is ie toch ook niet als ie protected is?
Hij wil (volgens mij) dat het niet mogelijk is hem public te maken :) Verder snap ik er ook niets van ;)

[ Voor 8% gewijzigd door Verwijderd op 28-04-2006 16:42 ]


Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 16-09 16:02

JHS

Splitting the thaum.

Zie over inherited singletons overigens ook dit topic: [rml][ OO] Implementatie Singleton pattern[/rml] :) .

DM!


Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Het niet mogelijk maken van een public constructor is een vreemd design. Een maker van een derived class mag zelf bepalen of zijn class een singleton wordt of een instantie. Zolang die class maar voldoet aan dezelfde (semantische) eigenschappen als de abstract class.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op vrijdag 28 april 2006 @ 16:35:
[...]


Wat heb ik aan zo'n antwoord?
Nou, eigenlijk alles. Ter verduidelijking, in OO talen als java is het niet toegestaan om een abstracte constructor te definieren. Dat is ook vrij logisch, want stel dat het wel zou kunnen, wat gebeurd er dan zoal?
Ten eerste moet je nagaan wat abstract nou inhoudt. Dit houdt in dat de abstracte klasse zelf niet direct te instantieren is en dat de subklasse van de abstracte klasse de implementatie (van abstracte members) voor zich moet nemen. Als deze subklasse ook abstract is, kan hij het ook op zijn beurt overlaten aan zijn subklasse etc...
De constructie die jij nu hanteert, door binnen een abstracte classe een abstracte constructor te hanteren, is in feite zeggen dat subklassen van deze, de constructor van de abstracte superklasse moet implementeren.
Ten tweede heeft elke klasse een constructor. Als je deze niet expliciet zelf definieert, krijg je te maken met de default constructor, i.e. een met public modifier en geen parameters. De body van de constructor (default, danwel expliciet) zal in de eerste regel altijd impliciet dan wel expliciet de constructor van zijn superklasse invoken.
Stel dus even voor dat het mogelijk is om een abstracte constructor te hebben. Ten eerste heb je dan een conflict, omdat je nu een concrete public default constructor en een abstracte protected constructor binnen je abstracte klasse hebt, hetgeen whoami naar refereert. Je hebt immers niet expliciet je constructor gedefinieerd, i.e. een met implementatie, dus is er nog sprake van de public default constructor; qua toegankelijkheid verschillen ze niets binnen dezelfde package en subklassen/klassen waarlangs ze ge-erfd zijn. Ook qua parameters niet. Hoe resolve je nu dan de juiste superconstructor vanuit de constructor van je subklasse? Juist, dat is onmogelijk door ambiguiteit. Stel dat je het public abstract had gemaakt, je constructor, dan implementeer je in feite binnen dezelfde abstracte klasse al impliciet je abstracte constructor, maar abstract houdt in dat je implementatie overlaat aan subklassen, iets waar je je dus niet aan houdt dan.
Ten tweede vind je het niet een beetje raar dat je een subklasse moet opdragen om de constructor van de superklasse te implementeren, als dit al uberhaupt mogelijk zou zijn? Dat is ongeveer hetzelfde als een constructor definieren binnen een interface, in de hoop dat implementerende klassen deze nietszeggende constructor implementeren, dat gelukkig ook niet mogelijk is.
Een constructor is overigens niet zomaar een methode. Een constructor is bedoeld voor object instantiatie, en verschilt ook van een methode in dat hij geen returntype heeft; dit is namelijk triviaal, daar hij een referentie naar zichzelf (i.e. het object dat zojuist geinstantieerd is), returned.
Het is dus wederom een "php-thing" dat dit uberhaupt mogelijk is.

[ Voor 203% gewijzigd door prototype op 28-04-2006 17:35 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Oke duidelijk. Graag een andere mogelijkheid om de gebruiker erop te wijzen dat het niet de bedoeling is de constructor in de child class public te maken. Ik zou final kunnen gebruiken om ervoor te zorgen dat de childs geen constructor meer kunnen maken maar dat is ook niet echt een mooie oplossing.

[ Voor 85% gewijzigd door Verwijderd op 28-04-2006 17:31 ]


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op vrijdag 28 april 2006 @ 17:22:
[...]


Oke duidelijk. Graag een andere mogelijkheid om de gebruiker erop te wijzen dat het niet de bedoeling is de constructor in de child class public te maken. Ik zou final kunnen gebruiken om ervoor te zorgen dat de childs geen constructor meer kunnen maken maar dat is ook niet echt een mooie oplossing.
Excuses overigens, hetgeen waar je naar citeert is niet helemaal correct/compleet, had perongeluk vroegtijdig ctrl+s gedrukt ;)
Wat je zou kunnen doen is een contract opstellen. In de commentblock specificeer je dan dat het preconditie is dat men zich aan zekere regels dient te houden, om zekere diensten af te kunnen dwingen.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Orphix schreef op vrijdag 28 april 2006 @ 16:47:
Het niet mogelijk maken van een public constructor is een vreemd design. Een maker van een derived class mag zelf bepalen of zijn class een singleton wordt of een instantie. Zolang die class maar voldoet aan dezelfde (semantische) eigenschappen als de abstract class.
Nou, ik vind van niet. Het kan toch perfect zijn dat je een class hebt die enkel via een factory bv. mag geinstantieerd worden. Dan kan je de visibility van je constructor beperken, zodanig dat enkel classes die in dezelfde package zitten, die constructor kunnen zien bv.
Oke duidelijk. Graag een andere mogelijkheid om de gebruiker erop te wijzen dat het niet de bedoeling is de constructor in de child class public te maken. Ik zou final kunnen gebruiken om ervoor te zorgen dat de childs geen constructor meer kunnen maken maar dat is ook niet echt een mooie oplossing.
Dat zal je volgens mij niet kunnen afdwingen.
Het is altijd mogelijk om dit te doen:
code:
1
2
3
4
5
6
7
8
9
10
public Class1
{
    protected Class1( int a )
    {}
}

public Class2 : Class1
{
    public Class2( int a ) : base(a) {}
}

[ Voor 30% gewijzigd door whoami op 28-04-2006 17:49 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
whoami schreef op vrijdag 28 april 2006 @ 17:44:
Nou, ik vind van niet. Het kan toch perfect zijn dat je een class hebt die enkel via een factory bv. mag geinstantieerd worden. Dan kan je de visibility van je constructor beperken, zodanig dat enkel classes die in dezelfde package zitten, die constructor kunnen zien bv.
Oh, ik ben absoluut voorstander van private/protected/internal constructors. Dit kan zeker heel nuttig zijn. Ik vind alleen dat het opleggen van dezelfde beperkingen aan alle toekomstige afgeleide classes een onnodige beperking. De maker van een derived class mag toch zelf bepalen of het tevens via een singleton pattern te werk gaat, of bv via een monostate (waarbij publieke constructors nodig zijn).

Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Verwijderd schreef op vrijdag 28 april 2006 @ 17:22:
Oke duidelijk. Graag een andere mogelijkheid om de gebruiker erop te wijzen dat het niet de bedoeling is de constructor in de child class public te maken. Ik zou final kunnen gebruiken om ervoor te zorgen dat de childs geen constructor meer kunnen maken maar dat is ook niet echt een mooie oplossing.
Waarom zou de gebruiker dit niet mogen?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Orphix schreef op vrijdag 28 april 2006 @ 18:02:
[...]

Waarom zou de gebruiker dit niet mogen?
Als de gebruiker de class extend en er dus voor kiest om met singleton (aangezien de class daarvoor gemaakt is) te werken en vervolgens de constructor kan aanroepen dan word er meer dan 1 instantie aangeroepen van de class en heeft singleton geen nut meer...

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Ik was trouwens wel benieuwd hoe je je singleton gebeuren af wilde handelen in je parrentclass. Ga je een map bij houden? En wat doe je wanneer iemand een afgeleide class weer af gaat leiden. ZIjn het dan weer twee verschillende of is dat hetzelfde object?

Ik vermoed dat je denkt dat je iets leuks aan het maken bent, maar nog niet hard genoeg over de complicaties hebt nagedacht.

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


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Verwijderd schreef op vrijdag 28 april 2006 @ 18:23:
[...]


Als de gebruiker de class extend en er dus voor kiest om met singleton (aangezien de class daarvoor gemaakt is) te werken en vervolgens de constructor kan aanroepen dan word er meer dan 1 instantie aangeroepen van de class en heeft singleton geen nut meer...
Als je een singleton gaat gaan inheriten, dan heeft je singleton ook geen nut meer, want dan is het geen singleton meer imho.

Stel, je hebt een parent class, die een singleton is. Van deze parent class inherit je nog 2 andere classes, die ook singleton zijn. Hoeveel instances heb je dan van je parent class ? Niet één, maar 3. Aangezien die andere 2 classes van je singleton ge-inherit zijn, zijn ze ook van hetzelfde type als die parent class. Dan heb je dus geen singleton meer.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op vrijdag 28 april 2006 @ 18:29:
Ik was trouwens wel benieuwd hoe je je singleton gebeuren af wilde handelen in je parrentclass. Ga je een map bij houden? En wat doe je wanneer iemand een afgeleide class weer af gaat leiden. ZIjn het dan weer twee verschillende of is dat hetzelfde object?

Ik vermoed dat je denkt dat je iets leuks aan het maken bent, maar nog niet hard genoeg over de complicaties hebt nagedacht.
Via de abstracte Singleton class. En ik ben niet van plan om die classes weer te extenden.
whoami schreef op vrijdag 28 april 2006 @ 18:31:
[...]


Als je een singleton gaat gaan inheriten, dan heeft je singleton ook geen nut meer, want dan is het geen singleton meer imho.

Stel, je hebt een parent class, die een singleton is. Van deze parent class inherit je nog 2 andere classes, die ook singleton zijn. Hoeveel instances heb je dan van je parent class ? Niet één, maar 3. Aangezien die andere 2 classes van je singleton ge-inherit zijn, zijn ze ook van hetzelfde type als die parent class. Dan heb je dus geen singleton meer.
Oke ik stel het me voor... "Ik heb een parent class en daar wil ik maar 1 object van kunnen maken. Ik extend de class met de abstracte singleton class. Ik kan de class die ik extend heb alleen nog maar aanroepen via getInstance(); uit de parent class. Ik kan geen nieuwe instantie maken omdat de constructor protected is en method clone private is".

Hoe kom ik dan aan 3 instanties van de class?

[ Voor 23% gewijzigd door Verwijderd op 28-04-2006 18:49 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Via de abstracte Singleton class.
Dat is geen antwoord op mijn vraag. Stel je hebt je singleton class. Vervolgens heb je singleton::A en singleton::B. Hoe ga je dit afhandelen?
Hoe kom ik dan aan 3 instanties van de class?
Dat is nu juist het probleem. Je hebt 3 verschillende classes (een class is geen instantie!. Singleton zorgt voor het garanderen van 1 instantie van een class), maar geen onderscheid.

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


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op vrijdag 28 april 2006 @ 18:56:
[...]

Dat is geen antwoord op mijn vraag. Stel je hebt je singleton class. Vervolgens heb je singleton::A en singleton::B. Hoe ga je dit afhandelen?


[...]

Dat is nu juist het probleem. Je hebt 3 verschillende classes (een class is geen instantie!. Singleton zorgt voor het garanderen van 1 instantie van een class), maar geen onderscheid.
Kan je het probleem aan de hand van een voorbeeld uitleggen? Kijk wat ik doe is dit:

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
57
58
59
60
<?php
// PHP 5

abstract class Singleton
{
    private static $instance = array();

    protected function __construct()
    {
        // Prevent direct creation of object
    }

    private function __clone()
    {
        // Prevent clones
    }

    abstract public static function getInstance();

    public static function singleton($class)
    {
        if(!isset(self::$instance[$class]))
        {
            self::$instance[$class] = new $class;
        }

        return self::$instance[$class];
    }
}

class MyClass1 extends Singleton
{
    protected function __construct()
    {
        echo __CLASS__;
    }
  
    public static function getInstance()
    {
        return parent::singleton(__CLASS__);
    }
}

class MyClass2 extends Singleton
{
    protected function __construct()
    {
        echo __CLASS__;
    }
  
    public static function getInstance()
    {
        return parent::singleton(__CLASS__);
    }
}

$object_A = MyClass1::getInstance();
$object_B = MyClass2::getInstance();

?>

Ik snap niet wat je bedoelt met afhandelen. Ik zie het hele probleem niet? Gebruik dit voorbeeld eens om het probleem aan te geven.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op vrijdag 28 april 2006 @ 20:24:
[...]


Kan je het probleem aan de hand van een voorbeeld uitleggen? Kijk wat ik doe is dit:

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
57
58
59
60
<?php
// PHP 5

abstract class Singleton
{
    private static $instance = array();

    protected function __construct()
    {
        // Prevent direct creation of object
    }

    private function __clone()
    {
        // Prevent clones
    }

    abstract public static function getInstance();

    public static function singleton($class)
    {
        if(!isset(self::$instance[$class]))
        {
            self::$instance[$class] = new $class;
        }

        return self::$instance[$class];
    }
}

class MyClass1 extends Singleton
{
    protected function __construct()
    {
        echo __CLASS__;
    }
  
    public static function getInstance()
    {
        return parent::singleton(__CLASS__);
    }
}

class MyClass2 extends Singleton
{
    protected function __construct()
    {
        echo __CLASS__;
    }
  
    public static function getInstance()
    {
        return parent::singleton(__CLASS__);
    }
}

$object_A = MyClass1::getInstance();
$object_B = MyClass2::getInstance();

?>

Ik snap niet wat je bedoelt met afhandelen. Ik zie het hele probleem niet? Gebruik dit voorbeeld eens om het probleem aan te geven.
Waarom gebruik je hier uberhaupt inheritence bij? Enige waar je de klasse singleton voor gebruikt is een pool.

Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Je kan het beste de functionaliteit van je class los zien van de constructiemethode. Een singleton zegt iets over de manier waarop je een instantie creerd. Het zegt niks over de eigenschappen van de class zelf, of wat het doet!
Een singleton kan zeer eenvoudig worden omgezet naar een 'reguliere' class, en vice versa. Je maakt nu afgeleide classes op basis van een constructiemethode, niet op basis van inhoud of methodes. Dit is geen goede opzet.

Dus wat is dan wel een goede opzet? Dat ligt eraan, je hebt namelijk twee opties en het is mij nog niet duidelijk welke je nu wilt bereiken:
1) Je hebt een base class die geimplementeerd is als singleton. Ten alle tijden mag hier slechts 1 instantie van in de applicatie aanwezig zijn. Ongeacht hoeveel andere classes hier gebruik van maken.
Of
2) Je hebt een base class die nu geimplementeerd is als singleton. Je leidt hier andere classes vanaf die tevens als singleton zijn geimplementeerd. Maar nu mag er van elke afgeleide class slechts 1 bestaan, en zijn er feitelijk dus eigenlijk meer base classes aanwezig.

Deze keuze is van belang, omdat het design tussen beide opties duidelijk anders is.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Verwijderd schreef op vrijdag 28 april 2006 @ 17:22:
Oke duidelijk. Graag een andere mogelijkheid om de gebruiker erop te wijzen dat het niet de bedoeling is de constructor in de child class public te maken.
Documentatie. En als iemand die negeert, dan moeten ze het toch echt helemaal zelf weten. Als iemand de sourcecode heeft, dan kan je in elke taal met een beetje beschaafde reflectiemogelijkheden toch altijd overal bijkomen. Dat je die constructor protected maakt is op zich al voldoende hint betreffende je bedoelingen. Als iemand dat wenst te negeren dan kan je daar niets aan doen en waarom je je daar verder zorgen over zou maken is me een raadsel.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Een abstracte statische methode lijkt mij ook niet helemaal normaal. Wat is daar precies de reden van? Lijkt me dat je met statische methodes helemaal geen gebruik van polymorphisme kunt maken en dat het defineren van die statische method in de base class dus onnodig is.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • tech-no-logical
  • Registratie: December 2000
  • Laatst online: 17-09 22:52
Janoz schreef op vrijdag 28 april 2006 @ 18:56:
Dat is nu juist het probleem. Je hebt 3 verschillende classes (een class is geen instantie!. Singleton zorgt voor het garanderen van 1 instantie van een class), maar geen onderscheid.
misschien licht off-topic, maar toch kan het nuttig zijn, imho. ik doe 't zelf ook, op deze manier :

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
<?php

interface NodeInterface {

  public static function dummy($node);

}

class SingletonNode implements NodeInterface{

  private static $instances;

  private final function __construct() { }

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

  public static function dummy($node) {
    print "Warning: class '".$node->tagName."' doesn't implement export() correctly !";
    return Array();
  }


}

class SomeNodeClass extends SingletonNode implements NodeInterface {

  public static function dummy($node) {
    
    return Array(1,2);
        
  }     
  
} 

?>


een uitgekleed voorbeeld, maar toch. de interface (eigenlijk een beetje overbodig) definieert wat er geimplementeerd moet worden, de base-class beheert de pool en heeft de default implementaties van (sommige) methodes, de extended classes zijn het uiteindelijke doel, en vertonen dermate veel overeenkomsten dat inheritance m.i. van toepassing is. het kan ongetwijfeld ook anders, maar dit is zo gegroeid en functioneert. misschien dat ik alleen de interface nog 's loos...

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Aangezien ik even wilde wachten tot je reageerde TS, maar ik langzamerhand mee de stad in wordt gesleurd door m'n gewaardeerde vrienden, post ik maar even wat ik even achterwege wilde laten, tot je er zelf mee kwam ;) Je gebruikt inheretence namelijk niet op de juiste methode, en met een kleine aanpassing van je huidige code zou het ongeveer neerkomen op dit:

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
<?php

    class SingletonPool
    {
        //@invariant:
        //  sizeof(SingletonPool::$INSTANCES) >= 0
        private static $INSTANCES = array();
        
        /**
         * @require class_exists($class)
         * @ensure result != null
         */
        public static function getInstance($class)
        {
            if (!isset(self::$INSTANCES[$class]))
            {
                self::$INSTANCES[$class] = new $class;
            }
            
            //@invariant:
            //  isset(self::$INSTANCES[$class])
            
            return self::$INSTANCES[$class];
        }
    }
    
    interface Singleton
    {
        public static function getInstance();
    }
    
    class MyClass1 implements Singleton
    {
        protected function __construct()
        {
        }
        
        public static function getInstance()
        {
            SingletonPool::getInstance(__CLASS__);
        }
    }

?>

HTH

[ Voor 3% gewijzigd door prototype op 28-04-2006 22:12 . Reden: Private ipv protected :$ ]


Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Toch begrijp ik niet waarom je een SingletonPool class wilt hebben. De benodigde code voor een singleton is zo weinig (en vrij triviaal), dat ik dit gewoon zou verwerken in de class zelf. Als ik nu de code lees ga ik er vanuit dat SingletonPool nog extra functionaliteit heeft, maar ik geloof niet dat dit het geval is bij de TS. Teveel design is ook niet goed.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Orphix schreef op vrijdag 28 april 2006 @ 22:16:
Toch begrijp ik niet waarom je een SingletonPool class wilt hebben. De benodigde code voor een singleton is zo weinig (en vrij triviaal), dat ik dit gewoon zou verwerken in de class zelf. Als ik nu de code lees ga ik er vanuit dat SingletonPool nog extra functionaliteit heeft, maar ik geloof niet dat dit het geval is bij de TS. Teveel design is ook niet goed.
Het is ook absoluut niet handig, maar de TS komt misschien zelf tot die inzichten; het is iig een verbetering op het originele ontwerp van TS, waar inheretence schromelijk misbruikt werd. Dat was hetgeen dat ik even duidelijk wilde maken ;)
Als je het mij zou vragen kun je het allerbeste gewoon de traditionele singleton pattern volgen, en gewoon een class met static getInstance en static instance property. Zelfde effect, minder dependencies. Wat jij zegt dus ;)

[ Voor 8% gewijzigd door prototype op 28-04-2006 22:23 ]


Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
prototype schreef op vrijdag 28 april 2006 @ 22:21:
[...]


Het is ook absoluut niet handig, maar de TS komt misschien zelf tot die inzichten; het is iig een verbetering op het originele ontwerp van TS, waar inheretence schromelijk misbruikt werd. Dat was hetgeen dat ik even duidelijk wilde maken ;)
Als je het mij zou vragen kun je het allerbeste gewoon de traditionele singleton pattern volgen, en gewoon een class met static getInstance en static instance property. Zelfde effect, minder dependencies. Wat jij zegt dus ;)
Okay, duidelijk. En nu de stad in jij! :Y)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Orphix schreef op vrijdag 28 april 2006 @ 22:16:
Toch begrijp ik niet waarom je een SingletonPool class wilt hebben. De benodigde code voor een singleton is zo weinig (en vrij triviaal), dat ik dit gewoon zou verwerken in de class zelf. Als ik nu de code lees ga ik er vanuit dat SingletonPool nog extra functionaliteit heeft, maar ik geloof niet dat dit het geval is bij de TS. Teveel design is ook niet goed.
Ik wilde gewoon makkelijk gebruik kunnen maken van het singleton patroon zonder dat ik veel code moet toevoegen aan een class. Ik ga singleton vaker gebruiken vandaar die 'pool' zoals sommige het noemen. Dat vind ik namelijk overzichtelijker. Ik gebruik abstract in plaats van een interface omdat je hierin ook nog methods kan maken ipv alleen defineren. Anders heb ik 2 classes nodig.

@ Orphix: 1 dus :)

@ Confusion: Daar heb je gelijk in!

@ Michali : Is inderdaad niet nodig, bedankt voor het wijzen erop.

[ Voor 17% gewijzigd door Verwijderd op 28-04-2006 22:51 ]


Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Verwijderd schreef op vrijdag 28 april 2006 @ 22:49:
Ik ga singleton vaker gebruiken vandaar die 'pool' zoals sommige het noemen.
Ok, ik begrijp nu beter wat je bedoelt. Wil ik je alleen als tip nog meegeven om singleton niet te misbruiken als verkapte globale variabele. Vaak is het helemaal niet nodig om een singleton toe te passen, en is een gewone instantie van een class veel eenvoudiger en minder foutgevoelig.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Orphix schreef op vrijdag 28 april 2006 @ 23:14:
[...]

Ok, ik begrijp nu beter wat je bedoelt. Wil ik je alleen als tip nog meegeven om singleton niet te misbruiken als verkapte globale variabele. Vaak is het helemaal niet nodig om een singleton toe te passen, en is een gewone instantie van een class veel eenvoudiger en minder foutgevoelig.
Oke bedankt :). Ik wil dit bijvoorbeeld gebruiken voor mijn template parser. Bedankt voor alle reacties!

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Beter is om zo veel mogelijk een registry class te gebruiken die referenties heeft naar objecten die normaal singleton zouden zijn. Die registry laat je dan afhankelijk zijn van een interface, en niet van de concrete class. Dat zorgt er voor dat je ook nog eens kunt switchen van implementatie. Bij een singleton zit je altijd vast aan de concrete class (of je moet getInstance een instantie van een andere class laten terug gegeven, maar dat is niet zo netjes imo.) Ik pas nu altijd dit toe ipv. een singleton. Je moet dan wel altijd instanties aan de registry vragen en zorgen dat je geen nieuwe aan maakt, die mogelijkheid heb je wel.

Noushka's Magnificent Dream | Unity

Pagina: 1