[php/alg] Class 'extenden' dmv. plugins

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Ik ben al een tijdje aan het zoeken naar de 'beste' oplossing, maar ik weet het nog niet helemaal..
Stel je het volgende voor:
Ik heb een class:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
    class tekenen {
        function tekenCirkel(){
            // Teken een cirkeltje
            doiets();
            //
        }
        fucntion tekenVierkant(){
            // teken een vierkantje
            doietsanders();
            //
        }
    }

Dit zit in een systeem dat ik dmv. plugins wil uitbreiden.
Nu kan ik dit dmv. extends natuurlijk doen.
PHP:
1
2
3
4
5
6
7
    class beterTekenen extends tekenen {
        function tekenSter(){
            // teken een ster
            donogiets();
            //
        }
    }

Maar dit levert een probleem op bij een reeds uitgerold systeem:
Ik moet alle initialisaties van de class, dus bv.
PHP:
1
$tek=new tekenen();

vervangen door
PHP:
1
$tek=new beterTekenen();

Dit is op zich nog wel te overzien maar natuurlijk niet echt handig.
Het liefst zou ik een directory maken met daarin per method een file'tje dat automatisch in de class wordt 'geincluded'.
Dit is ook nog wel te maken. (Voor een voorbeeld zie hier)

Best een aardig systeem, maar het is daarmee niet mogelijk om een method via een plugin te 'overriden'.
En daar zit dus precies het punt. Ik wil graag in een draaiend 'systeem' een php-plugin kunnen toevoegen (bestandje in dir zetten) waarbij het ook mogelijk is een evt. method te overriden zonder dat ik verder ook maar iets aan het systeem hoef aan te passen. Dus als ik de plugin verwijder alles weer terug bij het oude is.

Een van de mogelijkheden daarvoor is gebruik te maken van de PHP Classkit. Dat is een PECL module. Hiermee is het zelf mogelijk runtime een complete class te vervangen, methods te renamen, verwijderen toe te voegen of te redefinen. Precies wat ik zoek dus eigenlijk. Maar het probleem is ook meteen duidelijk. Er zullen weinig hosters zijn die deze module aanbieden/hebben of ertoe genegen zijn deze te installen. En zelf includen is er ook niet bij volgens mij. (Correct me if I'm wrong!)

De vraag dus: Hebben of kennen jullie andere oplossingen om dit probleem op te lossen? Hoe zouden jullie dit doen.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Bij een bestaand systeem wordt het moeilijk, je zult echt gaan moeten refactoren om er de mogelijkheid voor te schapen. Wat je zoekt (denk ik) is het Strategy pattern. Dit houdt in dat je een functie (of een set functies) in een apart object houdt. De class die alle functie calls ontvangt delegate alleen naar een member wat zo'n object is. Je hoeft dan alleen een instantie van een andere class toe te kennen aan die member om het gedrag aan te passen. Het aanmaken van die instanties kun je weer laten doen door een factory object/class, daarin kun je dan regelen welke instantie wordt aangemaakt (welke plugin dan in dit geval). Begrijp je een beetje wat ik bedoel? Ga anders op zoek naar "strategy pattern" en "factory pattern", dan zul je het wel zien.

[ Voor 3% gewijzigd door Michali op 25-02-2005 16:54 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Okee, ik zal deze nog eens doornemen, maar voorzover ik ze ken (lees: nog denk te kennen :) ) doen deze ook niet wat ik wil... (Maar ik ga er zeker nog weer eens naar kijken!)
Het is niet zo dat ik deze plugin op een al reeds bestaand iets wil implementeren, maar ik wil de 'klant' zeg maar een compleet werkend systeem opleveren met alle classes incl. methods etc.etc. er in.
Als er op een later moment uitgebreid moet worden moet het geheel erop voorbereid zijn dat ik nog slechts een 'plugin' bestandje in een bepaalde dir hoef te zetten. Hiermee moet ik dan de oorspronkelijke class volledig in takt kunnen laten (lees: niet hoeven aan te passen). oa. ivm met CVS(version control) etc.etc. en de mogelijkheid om de 'base' class bij verschillende klanten te kunnen gebruiken en evt. updaten (overal dus dezelfde class) waarbij ik bij bijv. één klant mbv een plugin bijv. de method tekenVierkant() kan overriden, of de method tekenSter() kan toevoegen.

Acties:
  • 0 Henk 'm!

  • tjerkw
  • Registratie: September 2004
  • Laatst online: 04-04-2024
maak gebruik van de singleton design pattern:

in pseudo code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
 
  usefullMethodA() { }
 
 public A getInstance() {
   return new B();
 }
}

class B {
 usefullMethodB() {}

 //override usefullMethodA
 userfullMethodA() {}
}


en dan als je de classe wilt gebruiken:

code:
1
2
3
A object=A.getInstance();

object.usefullMethodA()


Volgens mij lost dit wel wat problemen op, of zie ik het verkeerd?

Tjerk W


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Wat ik bedoelde was dit ongeveer (beetje pseudo):

Factory vorm:
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
<?

class Obj
{
    function doeIets()
    {
        // doe iets
    }
}

class ObjExtension extends Obj
{
    function doeIets()
    {
        // doe wat anders
    }
}

class ObjFactory
{
    function getObj()
    {
        return ( "er is een extensie" ) ? new ObjExtension() : new Obj();
    }
}

$factory = new ObjFactory();

$obj = $factory->getObj();

?>


Strategy vorm:
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
<?

class Obj
{
    var $func;

    function Obj()
    {
        $this->func = ( "er is een extensie" ) ? new ObjFunctionsExtension() : new ObjFunctions();
    }

    function doeIets()
    {
        $this->func->doeIets();
    }
}

class ObjFunctions
{
    function doeIets()
    {
        // doe iets
    }
}

class ObjFunctionsExtension extends ObjFunctions
{
    function doeIets()
    {
        // doe wat anders
    }
}

$obj = new Obj();

$obj->doeIets();

?>

[ Voor 15% gewijzigd door Michali op 25-02-2005 18:41 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Volgens mij lost dit wel wat problemen op, of zie ik het verkeerd?
Volgens mij zie je het verkeerd ;) (volgens mij is dit ook geen singleton wat je laat zien..)

Ik probeer het nog een keer voor de duidelijkheid:
PHP:
1
2
3
4
5
6
7
8
9
10
// Main script:
class tekenen{
    function tekenvierkant(){
        // teken een simpel vierkantje
    }
}

$drawing=new tekenen();
$drawing->tekenvierkant();
// Output: simpel vierkantje

Bovenstaande zit in het main script.

Nu heb ik een plugin (bestandje ergens in een dir) met daarin ('conceptcode'):
PHP:
1
2
3
4
// speciaalvierkant.php
function tekenvierkant(){
    // deze functie tekent heel speciale vierkanten.
}


Het liefst zou ik nu in de constructor van het main script dit doen.
PHP:
1
2
3
4
    function tekenen(){    // of __construct
        // Laad de plugins.
        LoadPluginsFromDir('xyz');
    }


Waarna (indien de 'speciaalvierkant.php' plugin beschikbaar) het result van het scriptje is:
PHP:
1
2
$drawing->tekenvierkant();
// Output:een heel speciale vierkant


Dus gebruikt maakt van de method in de plugin. Dus eigenlijk het toevoegen/overriden/definieren van methods/classes at runtime.

Nogmaals ik weet wat class extenden, singleton etc. is, maar deze (wellicht wel in een of andere special combi) patterns leveren niet
wat ik graag zou willen.
Bij extenden doet zich namelijk een probleem voor bij meerdere (onbekend aantal plugins) omdat ik niet weet wat wat moet extenden.

En bij de andere patterns steeds het probleem dat ik toch ook steeds achteraf het main script moet aanpassen, en dat is nou precies wat ik niet wil.

edit:
@Michali: Ik schreef dit voor ik jou post gelezen had, dat ga ik dus straks even doen (eerst even sporten nu. :*)

[ Voor 6% gewijzigd door beetle71 op 25-02-2005 18:41 ]


Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

Useful tip: factories maken is erg eenvoudig in PHP (je hoeft niet te switchen op classnames ofzo):

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?
class MyFactory {
   //howto "implement static member variables" in PHP :+
   function getPlugins () {
      static $plugins = array ( 'DefaultClass', 'SomeCoolPlugin' );
      return $plugins;
   }

   function getPluginClassName () {
      foreach ( MyFactory::getPlugins () as $plugin ) {
         if ( class_exists ( $plugin ) ) {
            return $plugin;
         }
      }
      trigger_error ( 'No available plugins :X' );
   }

   function getInstance () { 
      $className = MyFactory::getPluginClassName ();
      return new $className (); // <-- handig ;)
   }
}
?>

Hoe je precies de classname naar boven tovert doet er niet zo veel toe, dit is maar een voorbeeldje.

[ Voor 9% gewijzigd door drm op 25-02-2005 18:52 ]

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


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
@drm

Mmm, klinkt goed, maar volgens mij is er iets dat niet klopt aan je voorbeeld.
De defaultclass wordt namelijk door de factory wel aan de instance toegekend, maar de 'SomeCoolPlugin' niet..
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// drm's code here...

class DefaultClass {
    function foo(){
        return('foo');
    }
}

class SomeCoolPlugin {
    function bar(){
        return('bar');
    }
}

$test=new MyFactory();
$obj=$test->getInstance();
echo $obj->foo(); // output: foo;
echo $obj->bar(); // error: Call to undefined function: bar()............


Volgens mij omdat de method getPluginClassName met een foreach door alle plugins loopt, maar al met de eerst returned. (en een array daar returnen mag natuurlijk niet..)
Of pas ik je code niet goed toe?

@Michali.. Jou voorbeeld van de factory is niet bruikbaar omdat ik een onbepaald aantal plugins (dus in dit geval class extends) heb. Elke plugin zou een (of meer) extra methods (of overrides) aan één class moeten kunnen toewijzen. Zou ik dit met extends doen dan krijg je iets als SuperSuperSuperFoo extend SuperSuperFoo en SuperSuperFoo extends SuperFoo enz.. Dus dat gaat niet werken. (of denk ik verkeerd?)

Volgens mij heb ik ongeveer hetzelfde probleem dan met de strategy vorm.

Ik heb (wil) dus een onbepaald aantal plugins die per plugin een method moeten kunnen toevoegen of overriden, waarbij elke plugin dan ook weer toegang heeft tot alle reeds bestaande methods of methods die door een plugin toegevoegd zijn.

[ Voor 4% gewijzigd door beetle71 op 25-02-2005 22:48 ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
beetle71 schreef op vrijdag 25 februari 2005 @ 22:46:
@Michali.. Jou voorbeeld van de factory is niet bruikbaar omdat ik een onbepaald aantal plugins (dus in dit geval class extends) heb. Elke plugin zou een (of meer) extra methods (of overrides) aan één class moeten kunnen toewijzen. Zou ik dit met extends doen dan krijg je iets als SuperSuperSuperFoo extend SuperSuperFoo en SuperSuperFoo extends SuperFoo enz.. Dus dat gaat niet werken. (of denk ik verkeerd?)

Volgens mij heb ik ongeveer hetzelfde probleem dan met de strategy vorm.
Je kunt toch een strategy stijl object voor iedere method toepassen? Dan lukt het zeker. En verder is de code erg minimaal. Je moet er zelf even het idee uithalen en er wat mee doen.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Michali schreef op zaterdag 26 februari 2005 @ 11:13:
[...]

Je kunt toch een strategy stijl object voor iedere method toepassen? Dan lukt het zeker. En verder is de code erg minimaal. Je moet er zelf even het idee uithalen en er wat mee doen.
Jip, op zich is dat goed mogelijk, daarmee kan ik de extends opvangen, maar niet het toevoegen van methods!

Acties:
  • 0 Henk 'm!

Verwijderd

beetle71 schreef op zaterdag 26 februari 2005 @ 11:35:

Jip, op zich is dat goed mogelijk, daarmee kan ik de extends opvangen, maar niet het toevoegen van methods!
Waarom zou je methods willen toevoegen? Je benadert het vanaf de verkeerde kant.

In jouw startpost gaat je uit van een object "Tekenen" en en method "TekenVorm". Het is logischer om het andersom te doen: Een class Cirkel, Vierkant, Ster, etc. met allemaal de methode teken().

Zo te zien is dit ook wat Michali bedoelt.

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Verwijderd schreef op zaterdag 26 februari 2005 @ 11:39:
[...]

Waarom zou je methods willen toevoegen? Je benadert het vanaf de verkeerde kant.

In jouw startpost gaat je uit van een object "Tekenen" en en method "TekenVorm". Het is logischer om het andersom te doen: Een class Cirkel, Vierkant, Ster, etc. met allemaal de methode teken().

Zo te zien is dit ook wat Michali bedoelt.
Mmm. Op zich natuurlijk een hele goede vraag. Ik begrijp wat Michali bedoelt en wat jij bedoelt. Evt. zou hiervoor ook het Decorator-pattern zeer geschikt zijn. Inderdaad dus de benadering vanaf de andere kant.

Het is niet zo dat ik per se het een of het ander wil, ik probeer een goed overzicht te krijgen van de mogelijkheden, en wat dat evt. in gaat houden voor de implementatie.

Dan de vraag, waarom zou je methods willen toevoegen? Als je uitgaat van een decorator oid is dat inderdaad niet relevant. Maar denk even na over het volgende. (STEL >:) )

Ik wil het systeem uitbreiden met een tekenAmerikaanseVlag() method/functionaliteit. Dan kan ik die op zich natuurlijk als plugin toevoegen. Maar in de amerikaanse vlag zitten sterretjes, en ik vind het wel handig om ook losse sterretjes te kunnen tekenen, dus ik maak ook een plugin met tekenSterretje(). (ook handig voor tekenTurkseVlag() ) Het zou dan handig zijn als ik die als method aan de teken class zou kunnen toevoegen. ik wist van tevoren niet dat ik ooit sterretjes zou willen toevoegen dus er zit in mijn baseclass geen method hiervoor. (en ik wil/kan de baseclass(lees: file) NIET aanpassen). Hier zou het dus relevant zijn.

Nogmaals: Als ik het van de andere kant bekijk (strategy/factory/decorator etc.) zijn er zeker ook oplossingen, maar die hebben ook weer allemaal hun nadelen (ivm allerlei andere zaken in de echte implementatie). Wat ik dus nu probeer uit te vinden is of 'de gedachte' (dynamisch methods toevoegen/extenden) overeind kan blijven (voorzover die uberhaupt al overeind is 8) )

Acties:
  • 0 Henk 'm!

Verwijderd

beetle71 schreef op zaterdag 26 februari 2005 @ 12:43:

Ik wil het systeem uitbreiden met een tekenAmerikaanseVlag() method/functionaliteit. Dan kan ik die op zich natuurlijk als plugin toevoegen. Maar in de amerikaanse vlag zitten sterretjes, en ik vind het wel handig om ook losse sterretjes te kunnen tekenen, dus ik maak ook een plugin met tekenSterretje(). (ook handig voor tekenTurkseVlag() ) Het zou dan handig zijn als ik die als method aan de teken class zou kunnen toevoegen. ik wist van tevoren niet dat ik ooit sterretjes zou willen toevoegen dus er zit in mijn baseclass geen method hiervoor. (en ik wil/kan de baseclass(lees: file) NIET aanpassen). Hier zou het dus relevant zijn.
Of niet. Ik zie eerder een AmerikaanseVlag klasse die in zijn constructor een stuk of 50 keer een Ster instantie maakt, en hetzeltfde doet met een paar rode en witte Rechthoek objecten. In zijn teken() methode roept hij de teken() methoden van al deze objecten aan.

Je zorgt er dus voor dat je in die AmerikaanseVlag klasse gebruik kunt maken van die Ster en Rechthoek klasse. Hiervoor kun je iets als include_once gebruiken zodat je zeker weet dat de benodigde super klassen en gebruikte klassen "geladen zijn".

[ Voor 3% gewijzigd door Verwijderd op 26-02-2005 14:08 ]


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Of niet. Ik zie eerder een AmerikaanseVlag klasse die in zijn constructor een stuk of 50 keer een Ster instantie maakt, en hetzeltfde doet met een paar rode en witte Rechthoek objecten. In zijn teken() methode roept hij de teken() methoden van al deze objecten aan.

Je zorgt er dus voor dat je in die AmerikaanseVlag klasse gebruik kunt maken van die Ster en Rechthoek klasse. Hiervoor kun je iets als include_once gebruiken zodat je zeker weet dat de benodigde super klassen en gebruikte klassen "geladen zijn".
Klopt! :) Dan moet ik dus wel het Canvas object elke keer aan al die instanties meegeven. Of gaan werken met 'subcanvasjes' die gereturned worden en dan weer in het origineel geplakt worden, maar dat laatste is weer onhandig ivm. maatvoering. schaling en colorpalette etc.etc.

Het wordt dan dus een tekening object die een canvas object 'bezit' en die dat canvas object steeds aan allerlei teken instanties geeft.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
/ maak een tekening.
$canvas=new canvasObject(297,210,'RGB');

// teken een sterretje
$ster=new sterObject(&$canvas);
$ster->draw(100,100,6,50,'E8A100');

// teken nog een sterretje
$ster->draw(30,30,8,40,'FFFFFF');

// teken een vierkant.
$vierkant=new vierkantObject(&$canvas);
$vierkant->draw(10,10,100,100,'EEEEEE');


En moet ik dus elk tekenObject als factory/strategy uitvoeren. (vanwege mogelijke plugins)

Dit werkt prima. Maar vindt ik voor mijn gevoel veel omslachtiger als dat ik gewoon een tekeningObject heb waarvan canvas een variabele is en elk van de teken items gewoon members.
PHP:
1
2
3
4
$drawing=new tekening(297,210,'RGB');
$drawing->drawStar(100,100,6,50,'E8A100');
$drawing->drawStar(30,30,8,40,'FFFFFF');
$drawing->drawRect(10,10,100,100,'EEEEEE');


En er in het geval van een drawStar plugin, deze member overschreven wordt of toegevoegd voor het geval deze nog niet bestond. Ik hoef dan niet elke method die er 'af fabriek' al inzit te gaan testen op mogelijke plugins, maar slecht 1x een plugin loader toe te passen.

Ik zou dat normaal gesproken dan ook met een extended class doen,
dus bijv:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class betereTekening extends tekening{
    drawStar($x,$y,$point,$rad,$color){
        // method override
        ... tekene een mooiere ster
    }
    
    drawDonut($par1,$par2,....){
        // additionele method bestaat niet in baseclass
    }
}

// en dan aanroepen met:
$drawing=new betereTekening (297,210,'RGB');

Maar precies dat is dus onhandig als je het mbv plugins wilt doen omdat je dan niet weet wat wat moet extenden en hoe vaak je extend.

Nogmaals ik ben nieuwsgierig of ik dit (voor mijn gevoel) simpeler kan oplossen dan met een hele berg designpatterns.

Disclaimer: Ik ben een beetje eigenwijs O-)

[ Voor 25% gewijzigd door beetle71 op 26-02-2005 15:45 ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
maar hoe ga je die methods eigenlijk aanroepen? dat lijkt me vrij lastig als je niet weet wat de naam van de method is. Je zou dit kunnen oplossen met meta data oid. Beter is om gewoon gebruik te maken van polymorphisme, met verschillende objecten, zoals cheetah ook voorstelt. Overigens zijn deze concepten gewoon overduidelijk als je kijkt naar de namen van die functies: drawStar, drawDonut etc. dat hoort gewoon $star->draw() te zijn als je het mij vraagt.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Michali schreef op zaterdag 26 februari 2005 @ 16:47:
maar hoe ga je die methods eigenlijk aanroepen? dat lijkt me vrij lastig als je niet weet wat de naam van de method is. Je zou dit kunnen oplossen met meta data oid. Beter is om gewoon gebruik te maken van polymorphisme, met verschillende objecten, zoals cheetah ook voorstelt. Overigens zijn deze concepten gewoon overduidelijk als je kijkt naar de namen van die functies: drawStar, drawDonut etc. dat hoort gewoon $star->draw() te zijn als je het mij vraagt.
Okee, een 'echt' voorbeeld.

Ik maak in een pdf-rapport gebruik van de FPDF class.
dat gaat zo:
PHP:
1
2
3
4
$rapport=new FPDF(210,297);
$rapport->addPage();
$rapport->setXY(10,10);
$rapport->rect(10,10,100,100,'B',1);


Nu zijn er natuurlijk altijd dingen die ontbreken in die class, bijv. het tekenen van een polygon. Als ik die wil toevoegen doe ik natuurlijk het volgende:
PHP:
1
2
3
4
5
class PDF_polygon extends FPDF{
   function Polygon($points,$style='D'){
      // doe iets.. 
   }
}

Dat werk natuurlijk prima, ik kan dan in mij rapportscript ook $rapport->Polygon(array(1,2,2,2),'D'); doen. (Dus ik weet dan ook welke method ik wil gebruiken.)
Het lastige (vind ik) is dat als ik meerdere methods wil toevoegen/overriden dat ik die allemaal in die ene extend moet zetten, of extend over extend moet doen. Tenminste het wordt lastig als ik stukken van die extend in een ander project weer wil (laten) gebruiken. Dat wordt steeds copy-paste met de gevaren van dien. Dus ik dacht dat ik misschien die extended (of nieuwe) methods wel in een los file'tje kon zetten die ik als plugin in de FPDF kan laden. Lekker overzichtelijk en als ik ergens anders ook een polygonnetje nodig heb, dan kopieer ik even die plugin en hoef ik de extend daar niet aan te gaan passen (okee.. zoveel werk is dat nou ook weer niet).

Maar ik snap jullie redenaties heel goed, en de geboden oplossingen zijn prima! THNX. Maar op de een of andere manier laat de gedachte me nog niet helemaal los: "Waarom pattern over pattern in pattern" als ik ook een 'truukje' heb om een class te extenden mbv. een plugin file'tje (zoals bijv. deze link als ook al in de topicstart).
Hiermee kunnen dynamisch methods en members aan een class worden toegevoegd, maar 'helaas' geen overrides worden uitgevoerd.

Dit is dus het hele idee achter de gedachte.

Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

beetle71:
@drm

Mmm, klinkt goed, maar volgens mij is er iets dat niet klopt aan je voorbeeld.
De defaultclass wordt namelijk door de factory wel aan de instance toegekend, maar de 'SomeCoolPlugin' niet..
Dat komt door de volgorde in de array (je kan toch wel PHP lezen neem ik aan? ;)). Maar 't ging mij puur even om 't instantieren van een class waarvan de naam in de string staat. Dat is imo de meest eenvoudige manier om een factory te bouwen in PHP. (Afgezien van het feit dat andere patterns ook best toepasbaar kunnen zijn)

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


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
drm schreef op zaterdag 26 februari 2005 @ 17:34:
[...]
Dat komt door de volgorde in de array (je kan toch wel PHP lezen neem ik aan? ;)). Maar 't ging mij puur even om 't instantieren van een class waarvan de naam in de string staat. Dat is imo de meest eenvoudige manier om een factory te bouwen in PHP. (Afgezien van het feit dat andere patterns ook best toepasbaar kunnen zijn)
Mmm. >:) Ik dacht al dat het eigenlijk alleen ging om het principe
PHP:
1
2
$classname= "IetsLeuks";
$inst=new $classname;

Maar ik dacht even/hoopte dat nog iets erg leuks in PHP mogelijk was wat ik niet verwacht had/nog niet wist..... 8)7

Acties:
  • 0 Henk 'm!

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

classkit_import is waar de TS in zijn openingspost om vraagt.
classkit_import

(no version information, might be only in CVS)
classkit_import -- Import new class method definitions from a file
Description
array classkit_import ( string filename )
Het is nog wel een experimentele functie, dus ik denk dat je er helaas nog niks aan hebt... B)

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Als het alleen over het tekenen gaat zou je ook zoiets kunnen doen:
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
class PDFDraw extends FPDF
{
        function Draw($ToDraw, $Position, $Color)
        {
                $ToDraw->Draw($this->Document, $Position, $Color);
        }
}

class Drawable
{
        function Draw($handle, $Position, $Color)
        {
                trigger_error('Virtual method');
        }
}

class Polygon extends Drawable
{
        function Draw($handle, $Position, $Color)
        {
                //Teken een polygoon op $handle
        }
}

$X = new PDFDraw();
$X->Draw(new Polygon(), new Position(12,13), new Color('green'));


Volgens mij zoek je echter meer iets richting het Decorator pattern (dynamisch functionaliteit toevoegen aan een class)

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
zwippie schreef op zaterdag 26 februari 2005 @ 20:05:
classkit_import is waar de TS in zijn openingspost om vraagt.

[...]

Het is nog wel een experimentele functie, dus ik denk dat je er helaas nog niks aan hebt... B)
Jip, naast dat het experimenteel is is het ook nog eens een niet standaard PHP module die je dus bij geen enkele hoster kunt/mag verwachten.

@PrisonerOfPain: Inderdaad, dit is goed 'op te lossen' met het decorator pattern, en die mogelijkheid zal ik ook overwegen! Of misschien toch maar bij het 'good old' normale extenden blijven. Ik wilde het mezelf alleen maar makkelijker maken. En ik vraag me af of een decorator pattern in combinatie met factory of strategy patterns (ivm. mogelijk voorkomende plugins) het geheel niet veel onoverzichtelijker maakt. En daar was het me uiteindelijk toch om te doen.
Pagina: 1