Vraag over OOP
Maar het schrijven van Classes, het is niet de intentie hiervan om een verzameling van functie's in te gaan noteren. Het kan, het is makkelijk en geeft je de voordeel om een soort library te creeeren.
Maar is de grootste essentie ervan, om classes te extenden en daarmee een functie in de ene class, uit te breiden met een functie uit de andere class?
Zoals nu ben ik bezig met dit concept (even pragmatisch, zonder code dus):
Ik heb een Class
1. Language
2. Error handler
3. DBMS
1. Beheert het opvragen op basis van foutcode, om de juiste tekst op te halen.
2. Vervangt de fout afhandeling van php met die van mijn eigen.
3. Communiceert met elk gewenste database server (mysql, pgsql)
De class DBMS extends naar Error handler, omdat als er fouten optreden die database gerelateerd zijn, ik deze BOOL check (enzovoorts) met een functie uit de Error handler class, en vanuit daar een TRIGGER doe richting de hoofd functie van de Error handler class.
De class Error handler extends naar de class Language, deze haalt de juiste tekst op gebaseerd op een foutcode die vanuit de DBMS word meegestuurd naar de Error handler class, en deze middels een functie uit de Language class de juiste tekst ophaalt.
Is deze aanpak goed, of moet ik nog dieper gaan, of nog anders denken?
OOP is er niet om bibliotheken te maken, maar meer om de code abstract te houden. Een error handler klasse heeft als doel om een lijst met fouten te beheren en al dan niet weer te geven of acties te ondernemen. Op die manier heb je 1 instantie, de error handler, in plaats van een array en tig functies die die global array moeten vullen.
Extenden zoals jij toepast is eigenlijk in de ogen van echt Object Orientated programmeren helaas dan ook fout. Je Error handler is geen Language, maar maakt gebruik van een Language. Een instantie van een Language-object binnen je Error handler object gebruiken is dan een betere keuze. Sterker nog, als het goed is heb je meestal maar 1 Language-object nodig in je hele applicatie, namelijk die van de huidige taal. Je zou hier bijvoorbeeld het Singleton of Registery-pattern kunnen toepassen.
Zo ook je error handler. Ik weet niet precies hoe die van jouw werkt, ikzelf laat dat deel tegenwoordig eigenlijk geheel door exceptions afhandelen. Echt een aanrader. Maar hoeveel error handlers heb je nodig? Nu heb je er in ieder geval al een voor iedere database-instantie.
Om een lang verhaal kort te maken: het werkt in mijn idee verreweg het beste om alleen te extenden wanneer B een A is, bijvoorbeeld een Database Error Handler is een Error Handler, maar heeft wat extra methods om bijvoorbeeld queries te voorzien van een kleurtje en error meldingen van de database af te vangen. Wanneer B een A gebruikt gebruik je binnen B een instantie van A. Want B hoeft niet bij de interne lijsten of methods van A, die heeft daar niets te zoeken. Sterker nog, B maakt het niet eens zoveel uit hoe A werkt, zolang hij maar een paar bekende public methods van A aan kan roepen.
Quote:
Maar is de grootste essentie ervan, om classes te extenden en daarmee een functie in de ene class, uit te breiden met een functie uit de andere class?
Nee, dat is niet de grootste essentie. M.i. is OO een denkwijze en een manier om problemen op te delen in losstaande blokjes (objecten). Overerving is slecht een van de 3 grootste pijlers van OO, naast encapsulatie en polymorfisme.
Quote:
Ik heb een Class
1. Language
2. Error handler
3. DBMS
1. Language
2. Error handler
3. DBMS
Van dit rijtje kan ik niet echt een concreet "object" maken, ik zie het vooralsnog als verzamelingen van functies welke je in een class hebt gestopt. Dit is trouwens niet verkeerd hoor :)
Quote:
De class DBMS extends naar Error handler, omdat als er fouten optreden die database gerelateerd zijn, ik deze BOOL check (enzovoorts) met een functie uit de Error handler class, en vanuit daar een TRIGGER doe richting de hoofd functie van de Error handler class.
Hier ga je naar mijn mening tóch de fout in. Overerving "mag" je alleen gebruiken als je kunt zeggen "class B is ook een class A"...jij maakt een class DBMS die eigenlijk ook een errorhandler is, da's niet correct. Je hebt op deze manier een knalharde koppeling tussen een errorhandler en een dbms-class.
Een logischere opzet zou kunnen zijn:
Code (php)
Laat classes gewoon errors "gooien" (throw Exception) als het fout gaat, die kun je met alle andere clientcode opvangen (try/catch) en de gewenste actie ondernemen.
Quote:
De class Error handler extends naar de class Language, deze haalt de juiste tekst op gebaseerd op een foutcode die vanuit de DBMS word meegestuurd naar de Error handler class, en deze middels een functie uit de Language class de juiste tekst ophaalt.
Zelfde verhaal: errorhandler is een language? Nee, is geen duidelijke constructie, ook hier een keiharde en onduidelijke koppeling.
Lees de volgende pagina's eens door om een beter beeld van OO te krijgen:
- http://wiki.phpfreakz.nl/Object_Oriented_Programming
- http://wiki.phpfreakz.nl/OOP_Toepassen
- http://wiki.phpfreakz.nl/Model_View_Controller
- http://wiki.phpfreakz.nl/Design_Patterns
Edit:
En wat duplicates met Jelmer, ik hoop dat de strekking duidelijk is ;)
Gewijzigd op 01/01/1970 01:00:00 door Remco van Arkelen
Dan begrijp ik waarvoor extending daadwerkelijk voor bedoeld is, ben ik daar ook eens over uit.
Ga ik me even verdiepen op "het Singleton of Registery-pattern" suggestie van je, ben nog niet zo bekend met dit.. maar meestal klinkt het moeilijker dan het is, dus ik ga het nodige even lezen voordat ik verder ga met het project.
Bedankt v.d info!
@Remco, ook bedankt voor je info!..
Gewijzigd op 01/01/1970 01:00:00 door Danny Roelofs
Dier -> Aap
Dier -> Muis
Vervoermiddel -> Auto
Vervoermiddel -> Fiets
De klasse waarin je overerft is altijd concreter als de klasse die wordt overgeerft (lastig woord).
Zo heb ik het altijd geleerd, op school.
Dier en Vervoermiddel zijn meestal abstracte klassen omdat hiervan geen object gemaakt mag worden.
Gewijzigd op 01/01/1970 01:00:00 door Martijn B
Gezien ik met een zo groot project bezig ga, wil ik toch zoveel mogelijk goed doen vanuit het begin.
Stel je voor, ik heb een aap en tijger als dier, ze leven in een dierenpark en bevinden zich ergens in deze dierenpark.
1. aap en tijger kan ik zien als een extend van dier omdat ze beiden dieren zijn.
2. een locatie in het dierenpark mag ik dus niet extenden vanuit de rest.
Ga ik dan vanuit de class dier, de locatie aanroepen middels een method uit de class dierenpark zoals dit voorbeeld van mij:
Code (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
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 dierenpark
{
function vind_dier($een_dier)
{
if ($dier = 'aap') { $this->ikbenhier = 'Ik ben te vinden op plattegrond 1, sectie A'; }
if ($dier = 'tijger') { $this->ikbenhier = 'Ik ben te vinden op plattegrond 2, sectie D'; }
}
}
class dier
{
function waar_ben_je($een_dier)
{
$dierenpark = new dierenpark();
$dierenpark->vind_dier($een_dier)
$this->ikbenhier = $dierenpark->ikbenhier;
}
}
class aap extends dier
{
function aap()
{
$this->waar_ben_je('aap');
echo $this->ikbenhier;
}
}
class tijger extends dier
{
function tijger()
{
$this->waar_ben_je('tijger');
echo $this->ikbenhier;
}
}
?>
class dierenpark
{
function vind_dier($een_dier)
{
if ($dier = 'aap') { $this->ikbenhier = 'Ik ben te vinden op plattegrond 1, sectie A'; }
if ($dier = 'tijger') { $this->ikbenhier = 'Ik ben te vinden op plattegrond 2, sectie D'; }
}
}
class dier
{
function waar_ben_je($een_dier)
{
$dierenpark = new dierenpark();
$dierenpark->vind_dier($een_dier)
$this->ikbenhier = $dierenpark->ikbenhier;
}
}
class aap extends dier
{
function aap()
{
$this->waar_ben_je('aap');
echo $this->ikbenhier;
}
}
class tijger extends dier
{
function tijger()
{
$this->waar_ben_je('tijger');
echo $this->ikbenhier;
}
}
?>
Dit is even maar een voorbeeld, puur om de manier van... doe ik hier iets fout in mijn gedachtegang?
Gewijzigd op 01/01/1970 01:00:00 door Danny Roelofs
Nu weet ik niet precies hoe die gaat met aap en tijger, als deze ook een constructor hebben.
De constructor in PHP5 is overigens __construct.
Maak je in dierenpark ook een array of object met mogelijk locaties?
Dit zal waarschijnlijk uit de database worden gehaald.
De methode waar_ben_je in dier zou ik final maken.
Nu kan deze niet meer wordt overschreven in aap en tijger.
Ik moet, erg helaas.. maar toch ook wel stilstaan dat ik ondanks zelf onder php5 werk, ook het project php4 compatible wil houden tot aan dat ik de indruk krijg dat php4 toch aardig uitgestorven is.
Ik kan ook niet hele project bespreken, het gaat nog complex worden, ook al moet ik nog veel uitwerken, maar een aantal basis benodigdheden ben ik dan al aan het ontwerpen.
Een project gaat Xenolink heten, evenredig als de domein naam die ik daar al voor heb geregistreerd en kortom wordt het een Multie Content Management System en dat zal opensource worden, hopelijk t.z.t worden er mensen gemotiveerd om er aan mee te werken of er toepassingen voor te schrijven.
Om alles uit te leggen, van wat ik ga gebruiken, of wil benaderen word me nu te omslachtig. Maar het komt er op nee dat met Xenolink je concepten benaderd als:
1. Joomla
2. Hyves
3. Youtube
4. Webshop
5. Forum
6. database beheer / ontwerp.
Het wordt web 2.0, praat ik over gebruikers interactie (niet over design).
Het moet ook kunnen functioneren als framework.
Eigenlijk als ik het heel eenvoudig zeg, een 100 delige Zwitsers zakmes.
Daarom stel ik nu ook een beetje OOP vragen, dat vind ik essentieel gezien ik de code (omdat het opensource zal worden) ook duidelijk leesbaar moet zijn voor een ieder die er aan mee wil werken.
Code (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
/**
* Abstracte class met basis functionaliteit voor een dier in jouw Dierentuin
*
*/
abstract class Dier
{
protected $intPlattegrond;
protected $strSectie;
public function __construct( $intPlattegrond, $strSectie )
{
$this->intPlattegrond = $intPlattegrond;
$this->strSectie = $strSectie;
}
}
class Tijger extends Dier
{
}
class Aap extends Dier
{
}
class Dierentuin
{
private $arrDieren = array( );
/**
* Voeg een dier toe aan de collectie
*
* @param Dier $objDier
*/
public function addDier( Dier $objDier )
{
$this->arrDieren[] = $objDier;
}
/**
* Geeft alle dieren in de dierentuin
*
* @return Dier[]
*/
public function getDieren( )
{
return (array)$this->arrDieren;
}
}
/**
* Maak een Dierentuin aan
*/
$objDierentuin = new Dierentuin();
/**
* Maak een tijger aan
* Voeg de tijger toe aan de dierentuin
*/
$objTijger = new Tijger( 2, 'A' );
$objDierentuin->addDier( $objTijger );
/**
* Maak een aap aan
* Voeg de aap toe aan de dierentuin
*/
$objAap = new Aap( 1, 'B' );
$objDierentuin->addDier( $objAap );
/**
* Loop alle dieren in de dierentuin door
*/
foreach( $objDierentuin->getDieren() as $objDier )
{
var_dump( $objDier );
}
?>
/**
* Abstracte class met basis functionaliteit voor een dier in jouw Dierentuin
*
*/
abstract class Dier
{
protected $intPlattegrond;
protected $strSectie;
public function __construct( $intPlattegrond, $strSectie )
{
$this->intPlattegrond = $intPlattegrond;
$this->strSectie = $strSectie;
}
}
class Tijger extends Dier
{
}
class Aap extends Dier
{
}
class Dierentuin
{
private $arrDieren = array( );
/**
* Voeg een dier toe aan de collectie
*
* @param Dier $objDier
*/
public function addDier( Dier $objDier )
{
$this->arrDieren[] = $objDier;
}
/**
* Geeft alle dieren in de dierentuin
*
* @return Dier[]
*/
public function getDieren( )
{
return (array)$this->arrDieren;
}
}
/**
* Maak een Dierentuin aan
*/
$objDierentuin = new Dierentuin();
/**
* Maak een tijger aan
* Voeg de tijger toe aan de dierentuin
*/
$objTijger = new Tijger( 2, 'A' );
$objDierentuin->addDier( $objTijger );
/**
* Maak een aap aan
* Voeg de aap toe aan de dierentuin
*/
$objAap = new Aap( 1, 'B' );
$objDierentuin->addDier( $objAap );
/**
* Loop alle dieren in de dierentuin door
*/
foreach( $objDierentuin->getDieren() as $objDier )
{
var_dump( $objDier );
}
?>
Door correct gebruik te maken van overerving bundel je alle gedeelde functionaliteit in de basisklasse van een dier. Deze heb ik abstract gemaakt, hierdoor kan er géén object van Dier worden gemaakt, een Dier is immers niets concreets, maar een Aap of Tijger wel :)
Ik gooi niet zo gauw met bepaalde woorden als super, cool.. of vet (ben ik te oud voor) ;-).. maar ben je zeer erkentelijk voor je voorbeeld!
Danny Roelofs schreef op 02.02.2008 19:57:
En nu werk je er zelf aan mee dat PHP versie 4 niet uitsterft... PHP versie 5 is al járen op de markt, is een stuk beter dan versie 4 (zéker wat betreft de OOP-capaciteiten) en versie 4 wordt niet meer bijgewerkt. De laatste update is al geweest...Ik moet, erg helaas.. maar toch ook wel stilstaan dat ik ondanks zelf onder php5 werk, ook het project php4 compatible wil houden tot aan dat ik de indruk krijg dat php4 toch aardig uitgestorven is.
Maak het jezelf niet onnodig moeilijk en ga uitsluitend versie 5 ondersteunen. Zelfs binnen versie 5 heb jij al genoeg uitdagingen om de boel werkend te krijgen.
Tip: Zet de error_reporting op E_ALL | E_STRICT, zo krijg je ook fouten m.b.t. classes e.d. voor je neus.
Het ligt er aan hoe je dat ziet, mijn project zal er niet aan bijdragen dat php4 vereist wordt, het is alleen backwards compatible. Dus dat ik dan er aan mee werk dat php4 niet uitsterft, is dan niet geheel van toepassing.
De beste en meestal enige manier is dan dedicated hosting.
Waarom dan nog PHP4 gebruiken?
@Danny: ik zou toch ook overwegen om tenminste PHP5 te gebruiken, pgFrank geeft het al aan, PHP4 is op sterven na dood, waarom zou je met een nieuw en nog op te zetten project nog voor 4 kiezen? PHP5 voorziet in zoveel moois, denk aan PDO, SOAP, SimpleXML, DOM en het verbeterde OO-model...
server waaronder ik ook zekers gebruik maak van php5.
De server heeft een aardige capaciteit, althans.. systeem en dataverkeer vallen voor mij onder de keuze "afdoende". Moet er alleen nog eens wat geheugen laten bij prikken zodra het project de markt op gaat en de nodige aandacht krijgt.
Quote:
Inmiddels is het 2-2-2008, je hebt dus nog 6 maanden, daarna is er geen ondersteuning meer. Volkomen zinloos om dan voor die 6 maanden allerlei zaken die standaard in versie 5 te zitten, zelf met het handje te gaan bouwen in versie 4. Daarnaast zijn veel zaken gewoon niet mogelijk in versie 4, denk alleen al aan constructors en destructors.The PHP development team would like to announce the immediate availability of PHP 4.4.8. It continues to improve the security and the stability of the 4.4 branch and all users are strongly encouraged to upgrade to it as soon as possible. This release wraps up all the outstanding patches for the PHP 4.4 series, and is therefore the last normal PHP 4.4 release. If necessary, releases to address security issues could be made until 2008-08-08.
Daarnaast heb jij het gehad over ondersteuning van zowel MySQL als PostgreSQL, met PDO wordt dat een stuk eenvoudiger. Alleen de SQL is dan hier en daar wat anders, de PHP-code is hetzelfde. Zonder PDO mag jij zelf 2 aparte database-classes gaan bouwen.
Ondersteuning voor versie 4 gaat je heel veel extra tijd kosten en levert je, behalve extra code en dus extra bugs, niks extra's op. Het PHP-team adviseert iedereen om over te stappen op versie 5, adviseer jouw gebruikers dan hetzelfde. Backwards compatible is leuk en aardig, maar alleen wanneer je tijd en geld teveel hebt. Of als het geen extra inspanning kost, maar daar is hier zeker geen sprake van!
Ik zal het gaan doen, php5.. en ik zal de twijfel in mij, opzij zetten al doe ik het niet geheel 100% met een goed gevoel, maar ik laat php4 los.. zal er niet meer over beginnen.
Maar dan moet ik me even in het PDO gebied gaan verdiepen.. zal ook wel goed komen, het enigste probleem die ik in mijn php leven ken is OOP, althans.. ik weet er wat van af, maak er nuttig gebruik van maar nog niet die 100%.
Vooral het plannen van de Classes, het extenden.. bv een DBMS bouwen, welke classes.. wat doet wat, hoe ga ik om met MVC, hoe ver moet ik gaan, of behoor ik te gaan..
Ik denk dat ik maar eens een heel DIK boek ga kopen over Php5 en OOP, of een ebook vinden..
Wat betreft het onder de knie krijgen van PDO: wellicht dat je wat aan deze tutorial hebt? Verder zijn er ook wat betreft die andere onderwerpen genoeg goede tutorials op het internet te vinden. Soms is het alleen even zoeken, dat wel...
Vooral op sites als www.devshed.org staan veel interessante artikelen over een breed scala aan onderwerpen. Zeker de moeite waard om eens een kijkje te nemen of raad te plegen als je op zoek bent naar informatie over een bepaald onderwerp.
http://www.phpclasses.org om andermans ideeën en concepten na te slaan.
Maar iig bedankt voor je link naar een tutorial over PDO.
Altijd handig en welkom...
Ja ben wel bekend met devshed.org, kom er zo af en toe wel eens op uit, en ik ben ook wel eens te vinden op Maar iig bedankt voor je link naar een tutorial over PDO.
Altijd handig en welkom...