login  Naam:   Wachtwoord: 
Registreer je!
 Forum

OO-overkill? (OOO???)

Offline nemesiskoen - 30/04/2006 23:29 (laatste wijziging 01/05/2006 10:19)
Avatar van nemesiskoenGouden medaille

PHP expert
Momenteel ben ik bezig met een klein experimentje. Ik ben begonnen met een idee een loginsysteem te maken dat zoveel mogelijk OO geprogrammeerd is. Uiteraard is uitgaan van deze stelling verkeerd, omdat als je jezelf VERPLICHT alles oo te gaan doen dan zit je met de verkeerde instelling, het is namelijk de bedoeling om oo toe te passen waar het handig is, als dataholder of voor de reusabillity. Dit was ook mijn bedoeling, het experimentje diende ervoor dat ik kon zien wat er gebeurde.

Zoals ik had verwacht is er aan mijn verwachtingen voldaan en heb ik een OO-overkill gedaan, ik heb mezelf in de knoop gedraaid (geweldig!). Ik ben wel trots op het resultaat en zal alles doen om de stommiteiten die ik erin heb gegooid er uit te halen, en uiteindelijk het systeem hier op sima te posten.

Misschien vraag je jezelf nu af: waarom ik trots ben op het resultaat. Het antwoord daarop is eenvoudig, mijn index-pagina is echt kicke!
  1. <?php
  2.  
  3. require 'config.php';
  4.  
  5. $registreer = new URL($action, 'registreer', 'registreer');
  6. $login = new URL($action, 'login', 'login');
  7. $controlepaneel = new URL($action, 'controlepaneel', 'controlepaneel');
  8.  
  9. try {
  10.  
  11. if($result = $pageLoader->load($_GET, $action, $allowed, 'actionLayout')) // throws exception
  12. require $result;
  13.  
  14. } catch(Exception $e) {
  15.  
  16. ExceptionHandler::handle($e);
  17.  
  18. $layout->title('Kon pagina niet laden');
  19. $layout->initBody('templates/errors.tpl', 'errors');
  20. $layout->template()->assign('errorMessage', ExceptionHandler::render());
  21.  
  22. }
  23.  
  24.  
  25. $layout->template()->assign(
  26.  
  27.  
  28. 'registreer_link' => $registreer->render(),
  29. 'login_link' => $login->render(),
  30. 'controlepaneel_link' => $controlepaneel->render()
  31.  
  32. )
  33.  
  34. );
  35.  
  36. echo $layout->render();


Ik vind, als het systeem zo in elkaar steekt, bovenstaande instelling (praktisch alleen maar engels gebruiken ipv te programmeren) geweldig! Alleen is het pokkemoeilijk te verwezenlijken (heb ik gemerkt).

Nu zijn mijn vragen:
1. Wie hier heeft al eens te maken gehad met OO-overkill? (situatie een beetje schetsen als het kan)
2. Wat zou een mogelijke oplossing zijn om niette veel OO te willen programmeren?
3. Waarom denk je dat zoveel mensen de laatste tijd OO willen gebruiken (omdat het zo cool is?)
4. Denk je dat het verkeerd is als mensen zoveel OO te willen gebruiken? (of hoort dit bij het leerproces)
5. Waarom the f*** wil onderstaand ding maar niet werken?

--
Zoals je hierboven ziet is vraag 5 ook een beetje een hulpvraag, omdat ik (zoals ik vermelde) mezelf in de knoop heb gedraaid.

Het probleem is als volgt:
Ik heb een Layout klasse (die een Decorator is voor TemplatePower) die meerdere layouts kan 'dragen': de index-layout (met bijbehorende template), en de onderverdeelde (error, login, registreer...) met bijbehorende template.

Het probleem is dat een Layout meerdere Layout objecten kan hebben (beetje recursief). Als ik het eindproduct render dan laat ik eerst basis dingen genereren (<html><head><title>...) en vervolgens giet ik de layout in de body.

Dit ziet er ongeveer zo uit:

  1. <?php
  2. if(sizeof($this->tpl) != 0) {
  3.  
  4. if(sizeof($this->extraLayouts) != 0) {
  5.  
  6. foreach($this->extraLayouts as $k => $v) {
  7.  
  8. var_dump($v);
  9.  
  10. $this->tpl[0]->assign($k, $v->render());
  11.  
  12. }
  13.  
  14. }
  15.  
  16. $output->add($this->tpl[0]->getOutputContent());
  17.  
  18. }


Zoals je ziet worden de extra layout-objecten bijgehouden in de array $extraLayouts. Deze is ook daadwerkelijk gevuld. Het enige probleem is dat als ik $v->render() aanroep er niets gebeurd...

$this->tpl[0] is de 'moeder'-template van elk object. De andere zijn onderverdeeld met een key. Dus eigenlijk zou het dus getOutputContent moeten aanroepen, dit doet het echter niet. Hij geraakt niet eens door de 'sizeof' if bij de aanroepn van 'sub-Layouts'. Terwijl de objecten wel geset zijn (met hun eigen templates). Een beetje verwarrend dus.

Ter informatie:

body initialiseren
  1. public function initBody($page, $key = null) {
  2.  
  3.  
  4. $key = $key == null ? 0 : $key;
  5.  
  6. $this->tpl[$key] = new TemplatePower($page);
  7. $this->tpl[$key]->prepare();
  8.  
  9. return $this;
  10. }


template opvragen
  1. public function template($key = null) {
  2. return $key == null ? $this->tpl[0] : $this->tpl[$key];
  3. }


child-layout toevoegen
  1. public function addLayout($key, Layout $layout) {
  2. $this->extraLayouts[$key] = $layout;
  3.  
  4.  
  5. $this->tpl[$key] = $layout->template();
  6. // dit bewijst dat $this->tpl[0] voor de childs zijn geset! (aangezien bovenstaande methode) ***
  7. }


***: hierdoor ben ik dus extreem in de war. Het is geset, maar dan toch niet.

^ als iemand op puntje 5 kan antwoorden?

Ik denk dat ik best een nieuwe klasse aanmaak ChildLayout die erft van Layout en de render methode overschrijft. Spijtig genoeg heb ik hierbij het probleem niet verholpen (wel het feit dat hij tweemaal <html><head> etc zal renderen).

20 antwoorden

Gesponsorde links
Offline Thomas - 01/05/2006 11:35
Avatar van Thomas Moderator 1. Wie hier heeft al eens te maken gehad met OO-overkill? (situatie een beetje schetsen als het kan)

phpclasses.org - geeft (vaak) goed weer hoe het niet moet. Daarentegen zitten er ook hele aardige classes tussen, maar andere zijn gewoon regelrecht troep.

2. Wat zou een mogelijke oplossing zijn om niet te veel OO te willen programmeren?

Je bedoelt misschien "een mogelijk reden" om niet te veel OO te willen programmeren? Omdat niet alle zaken zich lenen om OO geschreven te worden. OO is een middel, geen doel an sich.

3. Waarom denk je dat zoveel mensen de laatste tijd OO willen gebruiken (omdat het zo cool is?)

Dit zou de nieuwe stijl programmeren moeten zijn / worden? Er zijn de laatste tijd ook een aantal talen verschenen die OO ondersteunen (.NET-varianten etc).

4. Denk je dat het verkeerd is als mensen zoveel OO te willen gebruiken? (of hoort dit bij het leerproces)

Als ze een keer hun handen branden en hier van terugkomen is dat niet erg (je leert dan een hoop). Maar als je OO blijft toepassen bij alles wat je doet... Ik zou gewoon het beste van de twee werelden gebruiken (OO en niet-OO).

5. Waarom the f*** wil onderstaand ding maar niet werken?

Geen idee Kijk hier wellicht later nog naar.
Offline Ibrahim - 01/05/2006 11:51
Avatar van Ibrahim PHP expert OOP scripting wordt hier vaak niet goed begrepen.

Fenrir geeft me hier goede adviezen/regels/voorbeelden over.

een belangrijke opmerking van hem was:

quote:
Citaat:
Veel mensen op sitemasters maken een class en denken meteen dat ze object georienteerd programmeren.
OOP is als je een hoofddoel hebt voor ogen en die dan onderverdeeld in een aantal classen [een class per functie voor je hoofddoel]. Daarom is OO programmeren in php vaak nutteloos...
Een schets van OO programmeren:

HoofdDoel = forum
classen:
Onderdeel 1 => bekijk forum
Onderdeel 2 => bewerk forum
Onderdeel 3 => verwijder forum
Onderdeel 4 => bekijk topic
enz.

OOP is pas nuttig als je het gebruikt bij talen die object georienteerd zijn zoals bijv. Ruby


Wat ik wil vragen (aan nemesiskoen en anderen "OOP experten") of dit waar is 
Offline marten - 01/05/2006 11:56 (laatste wijziging 01/05/2006 11:57)
Avatar van marten Beheerder
Citaat:
Veel mensen op sitemasters maken een class en denken meteen dat ze object georienteerd programmeren.
OOP is als je een hoofddoel hebt voor ogen en die dan onderverdeeld in een aantal classen [een class per functie voor je hoofddoel]. Daarom is OO programmeren in php vaak nutteloos...
Een schets van OO programmeren:

HoofdDoel = forum
classen:
Onderdeel 1 => bekijk forum
Onderdeel 2 => bewerk forum
Onderdeel 3 => verwijder forum
Onderdeel 4 => bekijk topic
enz.

Tot zover ben ik er mee eens Op de regel ,,Daarom is OO programmeren in php vaak nutteloos'' na.


Citaat:
OOP is pas nuttig als je het gebruikt bij talen die object georienteerd zijn zoals bijv. Ruby


Oneens. PHP word steeds meer OO. (Je kan er in ieder geval steeds meer mee doen denkend aan PHP 5) Dit zal waarschijnlijk steeds verder uitgebreid worden zodat PHP later ook OO genoemd kan worden.
Offline Maarten - 01/05/2006 12:02
Avatar van Maarten Erelid Ik ben het zeker eens dat veel zaken OO worden gedaan terwijl dit zeker niet nodig is. Soms kan je evengoed een gewone functie gebruiken.. een class is handig als je interactie tussen de objecten wilt IMO.
Offline Ibrahim - 01/05/2006 12:05 (laatste wijziging 01/05/2006 12:10)
Avatar van Ibrahim PHP expert ik ben offtopic gegaan maar even hierop reageren:

Citaat:
Tot zover ben ik er mee eens Op de regel ,,Daarom is OO programmeren in php vaak nutteloos'' na.


waarom zou je in php voor elk onderdeel een class maken? heeft niet echt zin he...

genoeg over dit 

maar ik kan nemesiskoens vragen niet beantwoorden, want ik script niet OOP 

ik kan wel eentje beantwoorden (mening):

de reden dat mensen laatste tijd 'OOP' willen scripten is eigelijk omdat als men iets nieuws ziet het ook wilt leren (tenminste als ze een cool voorbeeld zien wat het kan) dat is hetzelfde met Ajax (Hits: 2463)
Offline lasdesigner - 01/05/2006 13:14
Avatar van lasdesigner PHP beginner Ik denk dat ik het hier niet mee eens ben 

  1. HoofdDoel = forum
  2. classen:
  3. Onderdeel 1 => bekijk forum
  4. Onderdeel 2 => bewerk forum
  5. Onderdeel 3 => verwijder forum
  6. Onderdeel 4 => bekijk topic
  7. enz.


Ik zou eerder iets doen als;
  1. Hoofddoel = forum:
  2. classen:
  3. Onderdeel1 = Auteur (bewerk/verwijder rechten)
  4. Onderdeel2 = Admin (bewerk/verwijder van topics, toevoegen categorien etc.. )
  5. Onderdeel3 = Forum (Bekijken categorien, topics en berichten)
  6. Onderdeel4 = Profiel (Zoek user etc.. )
Offline nemesiskoen - 01/05/2006 13:20
Avatar van nemesiskoen Gouden medaille

PHP expert
OOP scripting is een beetje een rare uitdrukking als je het acroniem voluit schrijft. Dat ter zijde:

Citaat:
waarom zou je in php voor elk onderdeel een class maken? heeft niet echt zin he...

Er is een verschil tussen 'voor alles een klasse maken' en oo-voordelen uit php halen.

Een goed voorbeeld hiervan is een templateparser. Sure, je _kan_ een function-based-tpp maken maar door het als een object te benaderen ziet het er logischer/duidelijker uit. Idem bij het uitlezen van xml.

Ik merk ook dat mijn klassen in java zich meer lenen voor reussability, maar php moet daarom niet volledig hiervoor onderdoen. Bij java word je half en half geforceerd om oo te programmeren, bij php heb je een keuze, en reussability is er zeker!

Omdat php 'struct' niet kent, of voor zover ik weet toch niet (php heeft hashing-tables in de plaats) zal oo zich binnen php verlenen tot het nabootsen hiervan. Dus dataholders die eigenlijk een array zijn die op een eenvoudige manier kan aangesproken worden.

Voorbeeld:
  1. <?php
  2.  
  3. class ItemHandler {
  4.  
  5. private $items = array();
  6.  
  7. /**
  8. * @desc: adds an element to the items array
  9. * @return: void
  10. * @accept: FormElement
  11. **/
  12.  
  13. public function add(FormElements $what) {
  14.  
  15. $this->items[] = $what;
  16.  
  17. }
  18.  
  19. /**
  20. * @desc: returns the amount of items in the items array
  21. * @return: int
  22. * @accept: void
  23. **/
  24.  
  25. public function count() {
  26.  
  27. return count($this->items);
  28.  
  29. }
  30.  
  31. /**
  32. * @desc: returns one item of the items array
  33. * @return: FormElement
  34. * @accept: mixed
  35. **/
  36.  
  37. public function get($what = NULL) {
  38.  
  39. return $this->items[$what]->toString();
  40.  
  41. }
  42.  
  43. }


Of een soort van outputhandler die het '.= ...' veranderd in '$object->add'.
Offline ikkedikke - 01/05/2006 13:28
Avatar van ikkedikke PHP expert Volgens mij is php gewoon niet de taal om oop in te gebruiken.
simpelweg omdat php procesgericht is, en andere "echte" oo-talen eventgericht zijn.
Offline nemesiskoen - 02/05/2006 17:49 (laatste wijziging 02/05/2006 17:50)
Avatar van nemesiskoen Gouden medaille

PHP expert
Voor de geïnteresseerden: ik ben eruit geraakt. Heel eenvoudig opgelost: de $tpl array tot een 1 $tpl object gemaakt en een sublayout klasse geschreven die heel eenvoudig is:

  1. <?php
  2.  
  3. class SubLayout extends Layout {
  4.  
  5. public function __construct() {}
  6.  
  7. public function render() {
  8.  
  9. return $this->tpl->getOutPutContent();
  10.  
  11. }
  12.  
  13. }


Hij is exact gelijk aan Layout, alleen erft hij de private methods niet over (wat goed is) en veranderd hij de render-methode (wat de bedoeling was).

Nu kan ik in al mijn bestanden gewoon $template aanroepen, deze wordt aangemaakt via index.php en representeert de template van elk bestand appart (bepaald door $_GET[$action], een variabele $_GET dus:)).

Ik ben wel tevreden over het systeempje, ook al zitten er belachelijk veel klassen in (en sommige, momenteel, vrij nutteloze) is het wel grappig. Heb op een minuutje een registreer-pagina gemaakt met foutafhandeling en de waardes blijven in het tekstvlak staan als er iets mocht mislopen:)

Nu nog even een login-pagina en een paar dummy 'controles' toevoegen en de grondlaag is gelegd!
Offline Ibrahim - 02/05/2006 17:56 (laatste wijziging 02/05/2006 17:57)
Avatar van Ibrahim PHP expert mag ik vragen wat voor nut het heeft een __construct functie te maken als je er niets inzet ? Heeft het een speciale reden, want volgens mij hoeft een __construct niet perse...
Offline Stijn - 02/05/2006 18:01
Avatar van Stijn PHP expert singleton silicom 
Offline nemesiskoen - 02/05/2006 18:05
Avatar van nemesiskoen Gouden medaille

PHP expert
__construct hoeft zeker niet, maar ik zet hem daar omdat ik later nog argumenten zal meegeven. Dit kon jij natuurlijk niet weten, maar deze zal in de toekomst nog argumenten opvragen als ik een oneindige template-boomstructuur ga uitwerken (maar dat is nu nog niet nodig).

Een andere reden dat ik hem soms aanmaak (bij bv. de moederklasse Layout) is omdat ik een singleton wilde maken van Layout (je hebt tenslotte maar 1 layout), toen wilde ik sublayouts maken en dacht ik deze als een Layout object te benaderen dus werd Layout niet meer Singleton. Ik veranderde de 'private function __construct() {}' in 'public function __construct() {}'. (waarom niet...) En het is blijkbaar handig geweest omdat ik hem nu terug naar singleton heb veranderd.

Maar je hebt gelijk, __construct _moet_ er niet staan.
Offline Ibrahim - 02/05/2006 18:22
Avatar van Ibrahim PHP expert ik wist het (Fenrir heeft weer gelijk xD)

alleen stijns reactie snap ik even niet.

Dus wat ik uit zijn reactie lees is dat je bij Singleton (ik ga even je tutorial lezen) dus wel een __construct functie moet aanmaken ?
Offline nemesiskoen - 02/05/2006 19:48 (laatste wijziging 02/05/2006 20:05)
Avatar van nemesiskoen Gouden medaille

PHP expert
Ja/nee, stijn zit fout omdat het een public constructor is en dus niets met singleton te maken heeft. Ik heb hem daar geplaatst omdat ik weet dat ik hem later (eigenlijk heb ik hem nu al nodig, ben heel de dag bezig geweest en de constructor is al in gebruik) zou nodig hebben (nu dus).

Hoewel het belachelijk veel apparte klassen zijn bewijst het toch wel dat het scripten veel sneller gaat (misschien het parsen een miliseconde trager...). Ik heb op enkele seconden een login en loguit pagina gemaakt. De loguit pagina bestaat uit 2 regels php-code:)

  1. <?php
  2.  
  3. $lid->logoff();
  4.  
  5. header("location: ?". $action ."=login");
Offline Gerard - 02/05/2006 20:36
Avatar van Gerard Ouwe rakker dat zijn er toch echt 5 koen 
Offline nemesiskoen - 02/05/2006 21:11
Avatar van nemesiskoen Gouden medaille

PHP expert
2 regels php-commando's dan?

:D
Offline Dolfje - 02/05/2006 21:50
Avatar van Dolfje Gouden medailleGouden medailleGouden medaille

PHP ver gevorderde
Over die OO-overkill:
Je moet de dingen alleen in een class steken als het zin heeft.
Nu komt de vraag wanneer het zin heeft:
Wanneer het verschillende functies is die je wilt bundelen.
Wanneer het functies zijn die je meerdere keren gebruikt.
Wanneer je de class de volgende keer niet meer moet herschrijven voor andere sites.

Ik heb dus een template-class, gemaakt door haytjes (promo )
Ik heb een inloggen-class, maar die is niet zeer groot, hij controleert alleen als iemand ingelogd is (dmv cookies). en heeft een functie $f_inloggen->login($id); en $f_inloggen->uitloggen()
Ik heb een class voor mysql, zodat alles wat makkelijker gaat
en dat is het. (Dus alleen het broodnodige om een nieuwe site 1 tandje sneller op te zetten)

offtopic:
Je script is minimaal 4 regels lang 

  1. <? //jaja dit is code
  2. $lid->logoff();
  3. header("location: ?". $action ."=login");
  4. ?> en dit doet ook nog iets...
Offline nemesiskoen - 02/05/2006 21:57 (laatste wijziging 02/05/2006 21:58)
Avatar van nemesiskoen Gouden medaille

PHP expert
Over die 4 regels zit je fout. Mijn script is minimaal drie regels lang. Die laatst '?>' mag niet als je nergens anders escaped voor html. Het zal geen error geven maar eigenlijk moet je het weglaten. (heb ik het ooit een keer met proximus over gehad)
Offline Gerard - 02/05/2006 22:02 (laatste wijziging 02/05/2006 22:02)
Avatar van Gerard Ouwe rakker Quote uit de Zend Framework Documentation:
Citaat:
For files that contain only PHP code, the closing tag ("?>") is never permitted. It is not required by PHP. Not including it prevents trailing whitespace from being accidentally injected into the output.
Offline nemesiskoen - 02/05/2006 23:08
Avatar van nemesiskoen Gouden medaille

PHP expert
...

heb net 2 uur zitten zoeken achter de stomste fout ooit. Ik heb zowat alles herschreven en bewerkt omdat ik ergens een ampersant had weggelaten. Ik dacht dat alle objecten in php per referentie werden doorgegeven vanaf PHP5; oftewel klopt de php documentatie niet (of ik ben verkeerd ingeligt), oftewel zit er een fout in de php engine want dit was dus niet het geval. Ik MOEST een ampersant zetten, anders kon er geen actie op worden uitgevoerd. In sommige gevallen wel maar als ik daarvoor dan een of andere complexe actie er doorgooide dan kon hij het ineens weer niet meer zonder ampersant...

strange...

Overigens heb ik weer met slechts 64 regels code (met vele enters ertussen om het leesbaar te houden) een bewerk_profiel pagina kunnen maken. Met een validator (dus als er iets niet goed is ingevult: error), de waardes blijven bewaart als ze zijn ingevuld en ze worden via 1 commando opgeslagen. Heel uitgebreide bewerk-pagina dus:) Dus het werpt zijn vruchten af, alleen moet je daarvoor eerst massa's andere pagina's aanmaken:)
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.295s