[PHP5] Constructors kunnen geen waarde retourneren?

Pagina: 1
Acties:

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Stel je voor je hebt een klasse:
PHP:
1
2
3
4
5
6
7
8
9
10
// Versie 4 & 5
class mijnKlasse {
  function __constructor($ID) {
    if ($ID == 1) {
      return true;
    }else{
      return false;
    }
  }
}
Met deze klasse was het in PHP4 zo dat je dat dan kan gaan checken:
PHP:
1
2
3
4
// Versie 4 & 5
if ($k = new mijnKlasse(2)) {
  // nu krijg ik dus false terug!
}
Echter bij PHP5 krijg je geen false terug maar een klasse! (object) Maar dit zou dus betekenen dat je altijd via een externe functie dat moet gaan doen (dus een aparte functie die een klasse retourneerd of false). Nu vraag ik me af of dit wel de bedoeling is en of er misschien een oplossing is.

Natuurlijk zou je door het woordje 'new' altijd een klasse terug moeten krijgen, alleen hierdoor kan je dus geen enkele voorwaarde meer in de constructor stoppen. Dit lijkt me wel een rare situatie. Het is toch best mogelijk dat de code in de constructor mag bepalen of het aanmaken van een klasse mogelijk is? Of past dit niet binnen echte OO software, het is voor mij een raadsel waarom ze dit hebben aangepast eigenlijk, iemand een idee?

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Misschien een exception throwen? Het lijkt me dat de constructor van een klasse alleen een instantie van die klasse zou moeten teruggeven. Anders lijkt me dat het gebruik van klassen onvoorspelbaar gedrag kan opleveren.

[ Voor 75% gewijzigd door Brakkie op 31-01-2005 13:52 ]

Systeem | Strava


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Een constructor hoort ook niets anders dan een instantie van die klasse terug te geven! Dat je in php4 daar heel vies mee kon werken zegt nog niet dat het ook in OOP hoort.

Als je perse wilt dat bepaalde condities gecontroleerd worden alvorens een object te maken, dan kan je daar bijvoorbeeld een factory voor maken. En anders een exception opgooien zoals Brakkie zegt, maar dat zal weer niet in php4 werken.

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Voorheen kwam er gewoon een klasse terug tenzij er in de constructor de false terug gaf afaik. Dat lijkt me niet zo erg onvoorspelbaar.

Een exception throwen lijkt me geen oplossing omdat dan het script abrupt stopt. Een (imo ranzige) oplossing zou dit kunnen zijn:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class mijnKlasse { 
  function open($ID) { 
    if ($ID == 1) { 
      return true; 
    }else{ 
      return false; 
    } 
  } 
} 

$k = new mijnKlasse;

if ($j = $k->open(2)) { 
  // nu krijg ik dus false terug! 
}

[ Voor 3% gewijzigd door LauPro op 31-01-2005 14:00 . Reden: foutje in aanroepen klasse ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

ACM schreef op maandag 31 januari 2005 @ 13:53:
Een constructor hoort ook niets anders dan een instantie van die klasse terug te geven!
[mierrenneukmodus]
Feitelijk geeft een constructor nooit iets terug, ook niet z'n eigen instance. In de regel wordt er geheugen gereserveerd voor de instance, en de constructor wordt vervolgens aangeroepen op die instance zoals elke andere memberfunctie. Het resultaat van de expressie new Bla () komt van die new operator, niet van de constructor van Bla.
[/mierrenneukmodus]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

LauPro schreef op maandag 31 januari 2005 @ 13:57:
Een exception throwen lijkt me geen oplossing omdat dan het script abrupt stopt.
:D
je moet juist een Exception throwen, dat is juist de beste manier 8)7
En als je niet weet wat exceptions zijn en hoe je ze moet opvangen (try catch) tja dan stopt je script ja ;)
http://nl3.php.net/manual/en/language.exceptions.php

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Sorry ik gaf het verkeerd aan, ik ken het nut van exeptions, ik wil slechts snel kijken of iets kan en zo ja een klasse terug krijgen. Dit is een beetje vergelijkbaar met mysql_fetch_object, daar krijg je ook een object terug totdat het niet meer kan (false).

Om nu een heel try-catch blok in te gaan bouwen lijkt me een beetje overkill, met name omdat deze functies/constructies nogal vaak voorkomen in mijn geval (dik tegen de 100 nu als ik even snel tel). Los daarvan nog alle situaties waar deze controles zijn, dat wordt dus aanpassen :7 .

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Even jullie mening over het volgende stukje code:
PHP:
1
2
3
4
if ($oFactuur = new shopFactuur($sID)) {
  $oFactuur->delete();
  redirect($sUrl);
}
Dat zou bij PHP5 dus zoiets moeten worden:
PHP:
1
2
3
4
if ($oFactuur = openShopFactuur($sID)) {
  $oFactuur->delete();
  redirect($sUrl);
}
Waar openShopFactuur dus een klasse of een false terug geeft afhankelijk van of de waarde van $sID in de db staat bijvoorbeeld.

[ Voor 4% gewijzigd door LauPro op 31-01-2005 14:10 ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Ach, je kan ook nog een methode toevoegen die je object "activeert". Je gebruikt de constructor om het object te configureren, en dan de activatiemethode om het object in gebruiksklare toestand te brengen. Die methode kan dan wel een resultaat hebben.

Voorbeeld, denk aan een netwerksocket klasse die een connect en close methode heeft.

Maar wat betreft je voorbeeld: dat kan je toch prima met excepties oplossen? Bestaat het factuur niet dan gooi je een exceptie. Of pas op het moment dat je delete methode aanroept.

[ Voor 23% gewijzigd door Infinitive op 31-01-2005 14:13 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

LauPro schreef op maandag 31 januari 2005 @ 14:06:
Sorry ik gaf het verkeerd aan, ik ken het nut van exeptions, ik wil slechts snel kijken of iets kan en zo ja een klasse terug krijgen. Dit is een beetje vergelijkbaar met mysql_fetch_object, daar krijg je ook een object terug totdat het niet meer kan (false).
Maar dat is dan ook een functie en niet een klasse ;)
Een constructor kan geen waarde terug geven zoals al gezegt is. Het enige wat je kan doen (en imo de beste manier) is een exceptoin gooien, mja of jouw "ranzige" manier ;)
Om nu een heel try-catch blok in te gaan bouwen lijkt me een beetje overkill, met name omdat deze functies/constructies nogal vaak voorkomen in mijn geval (dik tegen de 100 nu als ik even snel tel). Los daarvan nog alle situaties waar deze controles zijn, dat wordt dus aanpassen :7 .
als je zoveel hetzelfde moet aanpassen denk ik dat je sowieso al verkeerd bezig bent geweest :o

[ Voor 1% gewijzigd door Erkens op 31-01-2005 14:15 . Reden: RML fixed ]


  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Of je bouwt een klasse die shop overkoepelende functies in zich heeft. Bijvoorbeeld:
PHP:
1
2
3
4
5
6
class Shop {
      public static function factuurExists ($id)
      {
           //Check in de db of een bepaalde factuur bestaat en geef true of false terug.
      }
}

En dan voor je een nieuw object factuur aanmaakt:
PHP:
1
2
3
4
if(Shop::factuurExists($id))
{
    //Doe je dingen met de factuur
}

Weet alleen niet of dat verantwoord OOP is, excuses vooraf :P

[ Voor 56% gewijzigd door Brakkie op 31-01-2005 14:19 ]

Systeem | Strava


  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?
class mijnKlasse {
  function __constructor($ID) {
    if ($ID != 1)
      $this = null;
  }
}

// Versie 4 & 5
if ($k = new mijnKlasse(2)) {
  // ...
}


Zou moeten werken ;)

edit:
oops verkeerde code ge-copy-paste :p

[ Voor 32% gewijzigd door c0deaddict op 31-01-2005 14:36 ]


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Erkens schreef op maandag 31 januari 2005 @ 14:12:
Maar dat is dan ook een functie en niet een klasse ;)
Een constructor kan geen waarde terug geven zoals al gezegt is. Het enige wat je kan doen (en imo de beste manier) is een exceptoin gooien, mja of jouw "ranzige" manier ;)
Daar zit het hem nou juist in: een constructor kon tot voorkort (met PHP4) een waarde retourneren.
als je zoveel hetzelfde moet aanpassen denk ik dat je sowieso al verkeerd bezig bent geweest :o
Dat zou je kunnen stellen. Maar ik heb toendertijd de keuze gemaakt om deze structuur aan te houden juist om het gemak. Je kan in 1 regel controlleren of iets in de DB staat, zonder dat daar vele regels voor nodig zijn. Dit maakt het allemaal veel eenvoudiger en je kan razendsnel nieuwe functies toevoegen. In dit geval kan de factuur ook nog worden betaald, verzonden, geëmaild, uitgeprint etc etc etc.

Maar hoe zouden jullie dit oplossen dan? Ook via een aparte functie (in de geest van mysql_fetch_object) of via exeptions? Dit zijn altijd van die dingen die naar mijn idee naar 'beste stuurwal staan aan wal' neigen. Technisch is het gooien van exceptions helemaal te gek, alleen in de praktijk schort het er nogal aan imo. Stel dat ik een factuur, order en een offerte wil vergelijken, dan zou ik dus 3 grote blokken krijgen met eventuele exceptions. Imo niet echt het schoolvoorbeeld van compact programmeren.

Ik ben benieuwd naar de oplossing zoals die echt verantwoord is zullen we maar zeggen ;) .

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

LauPro schreef op maandag 31 januari 2005 @ 14:23:
Technisch is het gooien van exceptions helemaal te gek, alleen in de praktijk schort het er nogal aan imo. Stel dat ik een factuur, order en een offerte wil vergelijken, dan zou ik dus 3 grote blokken krijgen met eventuele exceptions. Imo niet echt het schoolvoorbeeld van compact programmeren.
als je compact wilt programmeren, waarom dan klassen gebruiken? daarnaast kan je een try catch best wel op 1 regel kwijt :+
Zelf ga ik altijd voor het exception throwen, juist omdat dit het duidelijkst is, ook als je over een x aantal tijd weer naar je code kijkt, of als iemand bezig gaat met jouw code :)

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Erkens schreef op maandag 31 januari 2005 @ 14:26:
als je compact wilt programmeren, waarom dan klassen gebruiken? daarnaast kan je een try catch best wel op 1 regel kwijt :+
Zelf ga ik altijd voor het exception throwen, juist omdat dit het duidelijkst is, ook als je over een x aantal tijd weer naar je code kijkt, of als iemand bezig gaat met jouw code :)
Omdat in dit geval ik juist de enige ben die naar deze code kijkt en wanneer er ooit anderen naar kijken ik degene ben die daar verder uitleg over kan geven is dat niet zo'n probleem.

En klassen zorgen er wel degelijk voor dat je code compact blijft hor. Je kan met 1 regel dus iets uit de DB halen en meteen een aantal dingen doen, als je voor elke controle een apart SQL-querie moet gaan maken dat wordt dat imo onbeheersbaar. Dat is de reden waarom ik ongeveer een jaar terug heb gekozen voor deze structuur. Misschien iets meer overhead maar wel razend snel dingen doen. Door met directe keywords te werken (openDit, createDat) is de code imo logischer dan dat deze bezaaid is met SQL-queries.

Dit voorbeeldje komt uit een codebase van ongeveer 1 MB en nu 30000 regels code. Noem het ranzig, dat is prima echter besef wel dat ten tijden van PHP4 (jaar terug) er verdomd weinig mogelijkheden waren om echt goed OO te werken. Ik heb gekozen voor deze oplossing en ja nu snij ik mezelf in de vingers. Maar misschien is dat over een jaar ook weer het geval met PHP6. Gelukkig heb ik een goede replace functie :Y) .

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Helaas
Fatal error: Cannot re-assign $this in /data/vhosts/cms/htdocs/classtest.php

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:09
LauPro schreef op maandag 31 januari 2005 @ 14:34:
[...]
Omdat in dit geval ik juist de enige ben die naar deze code kijkt en wanneer er ooit anderen naar kijken ik degene ben die daar verder uitleg over kan geven is dat niet zo'n probleem.
Wel als jij er niet meer bent omdat je bv. tegen een boom ofzo bent gereden.

Trouwens, waarom maak je gewoon geen soort van factory?
Die factory checkt of je object mag gecreeërd worden:

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

    public MyObject Create()
    {
           if( conditie )
           {
                    return new MyObject();
           }
            else return null;
    }

}

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

LauPro schreef op maandag 31 januari 2005 @ 14:06:
Sorry ik gaf het verkeerd aan, ik ken het nut van exeptions, ik wil slechts snel kijken of iets kan en zo ja een klasse terug krijgen.
Dit is klassiek gedrag voor een static functie, of zelfs een afzonderlijke class factory. Als je een constructor correct beschouwd, dwz zoals oisyn het uitlegt, is het enkel een stuk initialisatiecode op een geinstantieerd object. Dat kun je alleen met een exception afstoppen, omdat het construeren zelf niet ter discussie staat.

Als je feitelijk invoerwaardes wil checken hoor je een exception te gooien, als het je om externe condities gaat moet je een static functie toepassen of een factory gebruiken.

Professionele website nodig?


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
whoami schreef op maandag 31 januari 2005 @ 14:42:
Wel als jij er niet meer bent omdat je bv. tegen een boom ofzo bent gereden.
Ik heb wel een documentje gereed met wat tekst en uitleg over het een en ander ;) .
Trouwens, waarom maak je gewoon geen soort van factory?
Die factory checkt of je object mag gecreeërd worden:
Ik kwam het begrip niet zo 1-2-3 tegen op de PHP-site, ik ga er direct achter aan. Het lijkt alsof het is wat ik zoek :) Thanks!

[ Voor 21% gewijzigd door LauPro op 31-01-2005 14:51 ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:09
LauPro schreef op maandag 31 januari 2005 @ 14:49:
[...]


Ik kwam het begrip niet zo 1-2-3 tegen op de PHP-site, ik ga er direct achter aan. Het lijkt alsof het is wat ik zoek :) Thanks!
Het is wel iets dat hier al door meerdere personen vermeld werd..

https://fgheysels.github.io/


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

whoami schreef op maandag 31 januari 2005 @ 14:42:
[...]

Wel als jij er niet meer bent omdat je bv. tegen een boom ofzo bent gereden.

Trouwens, waarom maak je gewoon geen soort van factory?
Die factory checkt of je object mag gecreeërd worden:

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

    public MyObject Create()
    {
           if( conditie )
           {
                    return new MyObject();
           }
            else return null;
    }

}
Uhm, is 't misschien een idee om de create method static te maken? nu moet je (onnodig?) een factory object instantieren om subinstanties te krijgen :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 10:09
prototype schreef op maandag 31 januari 2005 @ 19:48:
[...]


Uhm, is 't misschien een idee om de create method static te maken? nu moet je (onnodig?) een factory object instantieren om subinstanties te krijgen :)
Dat is niet altijd een nadeel (check eens het abstract factory pattern); misschien dat het in dit geval idd niet echt een voordeel biedt.

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

prototype schreef op maandag 31 januari 2005 @ 19:48:
[...]

Uhm, is 't misschien een idee om de create method static te maken? nu moet je (onnodig?) een factory object instantieren om subinstanties te krijgen :)
Hangt er maar vanaf of je de factory zelf stateless wil hebben of daar ook nog iets van configuratie of state in moet zitten :)

Professionele website nodig?


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
LauPro schreef op maandag 31 januari 2005 @ 14:09:
Even jullie mening over het volgende stukje code:
PHP:
1
2
3
4
if ($oFactuur = new shopFactuur($sID)) {
  $oFactuur->delete();
  redirect($sUrl);
}
Dat zou bij PHP5 dus zoiets moeten worden:
PHP:
1
2
3
4
if ($oFactuur = openShopFactuur($sID)) {
  $oFactuur->delete();
  redirect($sUrl);
}
Waar openShopFactuur dus een klasse of een false terug geeft afhankelijk van of de waarde van $sID in de db staat bijvoorbeeld.
Dit is toch ook een factory of ben ik nou gek. Volgens mij heb je in die tijd gewoon je eigen antwoord al gegeven.

Noushka's Magnificent Dream | Unity


  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Dit is toch ook een factory of ben ik nou gek. Volgens mij heb je in die tijd gewoon je eigen antwoord al gegeven.
Volgens mijn bescheiden kennis over OOP niet. Een factory is een klasse met 1 statische methode die aan de hand van een argument een instantie maakt van een bepaalde subklasse.

Zoiets bijv:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class dbFactory {
    
    
    public static method createDbObject($type)
    {
        switch ($type)
        {
            case 'mysql':
                return new mysqlConnection;
            break;  
            case 'mysqli':
                return new mysqliConnection;
            break;
        }
    }       
}

//En die gebruik je dan zo
$db = dbFactory::createDbObject('mysqli');

[ Voor 40% gewijzigd door Brakkie op 01-02-2005 10:41 ]

Systeem | Strava


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Brakkie schreef op dinsdag 01 februari 2005 @ 10:35:
[...]


Volgens mijn bescheiden kennis over OOP niet. Een factory is een klasse met 1 statische methode die aan de hand van een argument een instantie maakt van een bepaalde subklasse.
Onzin. Een factory is een concept, en de implementatie is volledig afhankelijk van de context.

[ Voor 32% gewijzigd door Michali op 01-02-2005 12:40 ]

Noushka's Magnificent Dream | Unity


  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Michali schreef op dinsdag 01 februari 2005 @ 12:39:
[...]

Onzin. Een factory is een concept, en de implementatie is volledig afhankelijk van de context.
Ik heb zeker geen enorme kennis over OOP maar ik kan zo gauw geen algemene beschrijving vinden van het concept van een factory. Implementaties zijn er echter wel genoeg te vinden en die komen zo'n beetje neer op mijn beschrijving. Zie bijvoorbeeld hier:

http://www.informit.com/a...cle.asp?p=346958&seqNum=4
Polymorphism and the use of base class is really the center of OOP. However, at some stage, a concrete instance of the base class's subclasses must be created. This is usually done using the factory pattern. A Factory class has a static method that receives some input and, according to that input, it decides what class instance to create (usually a subclass).
Daar heb ik ook mijn kennis vandaan. Ik ben echter zeer benieuwd naar een algemene beschrijving van het concept. Maar misschien is dat wat offtopic.

Systeem | Strava


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-05 08:48

Janoz

Moderator Devschuur®

!litemod

LauPro schreef op maandag 31 januari 2005 @ 14:09:
Even jullie mening over het volgende stukje code:
PHP:
1
2
3
4
if ($oFactuur = new shopFactuur($sID)) {
  $oFactuur->delete();
  redirect($sUrl);
}
PHP:
1
2
3
4
5
6
7
try {
  $oFactuur = new shopFactuur($sID)) {
} catch (Exception $e){
  $oFactuur->delete();
  log($e->getMessage());
  redirect($sUrl);
}

Lijkt mij een stuk netter. Eventueel kun je de try catch lus groter nemen om het gehele deel die dezelfde actie moet ondernemen op een exception die erbinnen opgegooid kan worden.

In een fetch actie die of een object of false terug klan geven vind ik persoonlijk niet mooi. In dat geval lijkt me een 'hasNext()' methode veel meer voor de hand liggen.

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


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Brakkie schreef op dinsdag 01 februari 2005 @ 13:19:
[...]

Daar heb ik ook mijn kennis vandaan. Ik ben echter zeer benieuwd naar een algemene beschrijving van het concept. Maar misschien is dat wat offtopic.
Dat is dus helemaal niet handig en verneukt een paar van de voordelen van factories. Factories zijn juist handig om als instances te hebben slingeren, en dan dus instance methodes aan te kunnen roepen. Stel bijvoorbeeld een systeem wat ik nu in ASP.NET aan het ontwikkelen ben: bij iedere nieuwe sessie wordt er automatisch een security session object aangemaakt, wat gedefinieerd is als zijnde een object dat de interface ISecuritySession implementeert. Het systeem zelf detecteert echter de session start, en moet vervolgens een class instantieren van het type dat de implementor opgeeft. Dan heb je dus een callback of een delegate nodig, of je lost het elegant op met een factory.

In dit geval heeft de application class dus een pointer naar een ISecuritySessionFactory implemenatie, en die wordt aangeroepen om een ISecuritySession te instantieren, dus:
C#:
1
2
3
4
5
6
7
8
9
public interface ISecuritySessionFactory
{
  ISecuritySession Create();
}

public interface ISecuritySession
{
  ... session specific methods which are invoked from the system ...
}

In dit geval wil ik die method dus absoluut niet static hebben, want dan is ie niet over te erven, en kan de factory niet stateful zijn (hij kan bijvoorbeeld weigeren sessies te creeren voor blocked IP's die hij lokaal in een lijst bijhoudt, par example). In dit soort gevallen is de factory dus een elegante object oriented uitvoering van het minder OOP-zuivere delegates/callbacks concept.

Professionele website nodig?


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Brakkie schreef op dinsdag 01 februari 2005 @ 13:19:
Daar heb ik ook mijn kennis vandaan. Ik ben echter zeer benieuwd naar een algemene beschrijving van het concept. Maar misschien is dat wat offtopic.
Een echte "algemene" beschrijving bestaat er niet van. Het idee van een factory is dat je de regels voor het wel of niet aanmaken van een instantie en/of de regels voor het bepalen van welke class een instantie moet worden aangemaakt gescheiden houdt van de code die de instantie gebruikt. Hoe je dit oplost is geheel aan jezelf. Natuurlijk is het netjes om dit op te lossen met aparte class, maar het hoeft niet. Een gewone method kan ook, hoewel niet geheel OO. Princiepes achter desing patterns zijn vaak ook toe te passen in wat minder OO oplossingen. Het gaat meer om de gedachten erachter en niet zozeer om het puur OO zijn van zoiets.

Noushka's Magnificent Dream | Unity


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op dinsdag 01 februari 2005 @ 13:37:
[...]

PHP:
1
2
3
4
5
6
7
try {
  $oFactuur = new shopFactuur($sID)) {
} catch (Exception $e){
  $oFactuur->delete();
  log($e->getMessage());
  redirect($sUrl);
}

Lijkt mij een stuk netter. Eventueel kun je de try catch lus groter nemen om het gehele deel die dezelfde actie moet ondernemen op een exception die erbinnen opgegooid kan worden.
Beetje rare code, als er een exception is gegooid dan is er geen ShopFactuur geconstruct en heeft $oFactuur ook geen geldige waarde. Een delete erop aanroepen is vervolgens undefined.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Over die structuur van de factory (dus wel of niet binnen een klasse): Dit is nogal een discutabel punt, echter het heeft wel voordelen. Bijvoorbeeld het autoloaden van files bij het benaderen van een klasse: http://www.php.net/manual/en/language.oop5.autoload.php

Met een 'factory' in een klasse kan dat, zonder niet want er is geen functie om een file te includen bij het aanroepen van een niet-bestaande functie afaik. Een oplossing is om per verzameling een klasse aan te maken met daarin de factories.

Dit heb ik zelf al gerealiseerd door middel van een functie los van een klasse, ik was echter niet op de hoogte van het begrip factory. Zo leer je elke dag weer wat nieuws ;) .

De constuctie van Janoz klopt niet geheel. Ik blijf het echter geen mooie oplossing vinden vanwege het relatief grote blok (t.o.v. de mysql_fetch_object constructie). Ik vind de discussie over hoe technisch-correct de mysql_fetch_object constructie is wel interessant. Wat ik mij echter af vraag is waar we heen gaan als alles helemaal 100% OO moet worden.

Er lopen hier mensen rond met een paar hele mooie ideeën omtrend dit geheel (dus om binnen PHP5 goed OO te programmeren), daar ben ik eigenlijk wel benieuwd naar :) . Zou iemand een tipje van de sluier kunnen posten?

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik weet niet precies wat je nu onder een factory verstaat, maar __autoload heeft er iig niets mee te maken. Een factory zou er zo kunnen uitzien:
PHP:
1
2
3
4
5
6
7
8
class Factory
{
  public static function getObject($param)
  {
    $class = $param . Config::getValue('blaat');
    return new $class();
  }
}

Het mooie van deze constructie is dat als je op meerdere plaatsen nu een instance gebruikt en je de manier of regels voor het aanmaken van zo'n instance wilt wijzigen, dan kun je dat op een plek regelen en wordt dat overal dus doorgevoerd.

Verder over mysql_fetch_object, die zou ik niet gebruiken. Is traag vergeleken bij mysql_fetch_assoc en heeft verder geen voordelen. Als alles echt OO is moet je meer gaan denken aan 1 class (of meer) per tabel in de database. Vaak wordt daarbij gebruik gemaakt van een data access layer die er voor zorgt dat objecten uit de database gelezen worden, en dat ze eventueel weer naar de database geschreven worden. Als je dan nog gebruik maakt van een relationele database, dan kun je het al snel een object-relational (O-R) mapping layer noemen. Vaak maakt zo'n layer ook nog eens gebruik van een database abstractie layer, die er voor zorgt dat je verschillende databases op dezelfde manier kunt aanspreken. Zo kun je dus een applicatie onafhankelijk (in zekere mate) van de database ontwikkelen.

Verder zou je ook eens naar de mysqli extensie kunnen kijken. Die is al wat anders opgezet dan de oude manier.

Trouwens, wil je echt serieus verder met OO, dan zou ik zeker overwegen om het boek "Design Patterns Explained" aan te schaffen. Ik denk dat je na het lezen van dat boek al een stuk verder bent en heel wat meer inzicht hebt in de stof. Het heeft mij wel erg geholpen in ieder geval.

[ Voor 10% gewijzigd door Michali op 02-02-2005 20:11 ]

Noushka's Magnificent Dream | Unity


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 09:45

LauPro

Prof Mierenneuke®

Topicstarter
Ik gebruik mysql_fetch_object nauwelijks maar het gaat om het principe. Echter wat een beetje tegenstijdig is in je verhaal is de referentie naar de mysqli extensie. Deze is helemaal gebaseerd op objecten, na het uitvoeren van elke query wordt er een object terug gegeven. Dit klinkt mij in de oren als een boel overhead.

Dat boek zal ik eens nakijken, dank voor de tip. Op zich wel frappant dat er vanuit PHP.net zelf uit vrij weinig richting wordt gegeven naar wat nu eigenlijk echt de bedoeling is.

Mijn referentie naar autoloaden zal ik even uitleggen: wanneer je direct een klasse aan roept dan zou je dus via die autoload functie die klasse eerst kunnen includen. Bij het gebruik van een factory zonder klasse moet je die factory-functions als het ware weer in een apart bestand zetten. Zou leuk geweest zijn dat er vanuit de taal een mogelijkheid zijn ipv (imo dan) de huidige workaround mbt de factory constructie.

[ Voor 31% gewijzigd door LauPro op 02-02-2005 21:46 ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • ludo
  • Registratie: Oktober 2000
  • Laatst online: 01-03 18:17
LauPro schreef op woensdag 02 februari 2005 @ 21:43:
Ik gebruik mysql_fetch_object nauwelijks maar het gaat om het principe. Echter wat een beetje tegenstijdig is in je verhaal is de referentie naar de mysqli extensie. Deze is helemaal gebaseerd op objecten, na het uitvoeren van elke query wordt er een object terug gegeven. Dit klinkt mij in de oren als een boel overhead.
De mysqli extensie is níet helemaal gebaseerd op objecten. Het is een verbeterde (improved) versie van de mysql extensie. Als je wilt kun je de mysqli extensie zelfs op dezelfde manier benaderen als de mysql extensie. Het zijn namelijk ook gewoon php functies, maar het is wel mooi dat je de functies ook op een OO manier kunt aanroepen.
In de mysqli extensie zit net zo goed een functie mysqli_fetch_object() om de reultset als object op te vragen, maar er zit ook een mysqli_fetch_assoc() in waarmee je een gewone associatieve array terugkrijgt. Maar dit heeft dus niks te maken met het feit dat de mysqli extensie ook op een OO manier te benaderen is.
Dat boek zal ik eens nakijken, dank voor de tip. Op zich wel frappant dat er vanuit PHP.net zelf uit vrij weinig richting wordt gegeven naar wat nu eigenlijk echt de bedoeling is.

Mijn referentie naar autoloaden zal ik even uitleggen: wanneer je direct een klasse aan roept dan zou je dus via die autoload functie die klasse eerst kunnen includen. Bij het gebruik van een factory zonder klasse moet je die factory-functions als het ware weer in een apart bestand zetten. Zou leuk geweest zijn dat er vanuit de taal een mogelijkheid zijn ipv (imo dan) de huidige workaround mbt de factory constructie.
Ik snap nog niet precies wat dit met de autoload functie van doen heeft. Bedoel je dat je nu toch ergens een include() neer moet zetten omdat je de Factory functie in een apart bestand wilt zetten? Daar is an sich toch niks mis mee? En het Factory pattern is géén workaround. Het Factory pattern kan, mits goed toegepast, een zeer handige manier zijn om een probleem op te lossen.

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
LauPro schreef op woensdag 02 februari 2005 @ 21:43:
Ik gebruik mysql_fetch_object nauwelijks maar het gaat om het principe. Echter wat een beetje tegenstijdig is in je verhaal is de referentie naar de mysqli extensie. Deze is helemaal gebaseerd op objecten, na het uitvoeren van elke query wordt er een object terug gegeven. Dit klinkt mij in de oren als een boel overhead.
Volgens mij is ie een stukje sneller dan de vorige extensie. Doe anders eens een aantal benchmarks. Zelf gebruik ik gewoon de oude nog in verband met oude database software etc. met daaroverheen een abstractie laag. Mischien dat ik de nieuwe ook wel binnenkort ga gebruiken.
Dat boek zal ik eens nakijken, dank voor de tip. Op zich wel frappant dat er vanuit PHP.net zelf uit vrij weinig richting wordt gegeven naar wat nu eigenlijk echt de bedoeling is.
op php.net staat gewoon een reference voor alle functies en taal constructies. Het is geen echte programmeer tutorial. Kijk anders eens op deze site: http://www.phppatterns.com/
Mijn referentie naar autoloaden zal ik even uitleggen: wanneer je direct een klasse aan roept dan zou je dus via die autoload functie die klasse eerst kunnen includen. Bij het gebruik van een factory zonder klasse moet je die factory-functions als het ware weer in een apart bestand zetten. Zou leuk geweest zijn dat er vanuit de taal een mogelijkheid zijn ipv (imo dan) de huidige workaround mbt de factory constructie.
Volgens mij bedoel je dat je autoload niet kan gebruiken in samenwerking met losse functies. Hou het nou maar gewoon puur op classes voor een factory, het punt wat ik een aantal reacties hiervoor gaf dat een factory geen class hoeft te zijn, was alleen om aan te geven dat het om de princiepes gaat. Het is veel netter om gewoon een class te gebruiken dan een losse functie. Probeer gewoon behalve wat magic methods (zoals __autoload) en configuratie methods van alles een object te maken.

Zelf stop ik alle classes in een apart bestand. Ik include een grote array met alle locaties van de classes (dat bestand genereer ik) en die gebruik ik dan in __autoload om een class te includen als hij nog niet bestaat. Erg handig.

Noushka's Magnificent Dream | Unity

Pagina: 1