Juiste denkwijze gebruik methodes?
Ik ben al een tijdje geregistreerd op dit forum, echter, mijn gegevens zijn niet meer bekend. Heb destijds waarschijnlijk een ander e-mailadres gebruikt, maar dat terzijde.
Ik zit met een vraagje. Ik ben sinds twee weken wat meer bezig met OOP en ik weet nog steeds niet hoe bepaalde dingen het handigst zijn op te lossen.
Mijn vraag:
Ik heb zojuist een database-klasse geschreven (genaamd 'Database') en hier enkele methodes aan toegevoegd. Verbinding maken en queries uitvoeren gaat middels MySQLi, maar dat terzijde. Nu wil ik bedrijfsgegevens ophalen uit de database, dus ik heb een klasse 'Bedrijf' aangemaakt. Hoe kan ik dan het beste de gegevens ophalen? Hieronder mijn code met de twee/drie methodes die mij het beste lijken. Welke raden jullie mij aan voor toekomstig en universeel gebruik? Hieronder dus mijn code:
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
class Bedrijf
{
private $bedrijfsid;
public function setBedrijfsID($bedrijfsid)
{
$this->bedrijfsid = (int)$bedrijfsid;
}
public function getBedrijfsID()
{
return $this->bedrijfsid;
}
// Hieronder methode 1
// Één methode voor het ophalen van gegevens en die aanroepen middels een andere methode
// Voordeel: éénmaal lange(re) code voor de query, kan onderaan in de code, zit dus niet in de weg
public function getBedrijfsnaam()
{
return getBedrijfsgegevens('naam');
}
private function getBedrijfsgegevens($kolom)
{
$oDatabase = Database::getInstance();
$result = $oDatabase->setQuery("SELECT ". $kolom ." FROM bedrijf WHERE id = ". $this->bedrijfsid ." LIMIT 0,1");
if ( $oDatabase->countResults($result) == 1 )
{
$fetch = $oDatabase->fetchResults($result);
return (!empty($fetch[$kolom])) ? $fetch[$kolom] : 'onbekend';
}
else
{
return 'onbekend';
}
}
// Hieronder methode 2
// Dus per gegeven een aparte verbinding en methodes
// Voordeel: per waarde is een specifieke output te genereren
public function getBedrijfsnaam()
{
$oDatabase = Database::getInstance();
$result = $oDatabase->setQuery("SELECT naam FROM bedrijf WHERE id = ". $this->bedrijfsid ." LIMIT 0,1");
if ( $oDatabase->countResults($result) == 1 )
{
$fetch = $oDatabase->fetchResults($result);
return (!empty($fetch['naam'])) ? $fetch['naam'] : 'onbekend';
}
else
{
return 'onbekend';
}
}
// Verder zag ik ook een methode 'load()' die alle velden uit de database haalt.
// Deze velden worden in de $this-variabelen gezet middels methodes.
// Dit lijkt me onhandig, want ik hoef niet alles te selecteren als ik enkel de
// bedrijfsnaam wil selecteren. Ongeveer een voorbeeld:
public function load()
{
$oDatabase = Database::getInstance();
$result = $oDatabase->setQuery("SELECT * FROM bedrijf WHERE id = ". $this->bedrijfsid ." LIMIT 0,1");
if ( $oDatabase->countResults($result) == 1 )
{
$fetch = $oDatabase->fetchResults($result);
$this->bedrijfsid = $fetch['id'];
$this->bedrijfsnaam = $fetch['naam'];
// enz.
}
else
{
return 'onbekend';
}
}
public function getBedrijfsnaam()
{
return $this->bedrijfsnaam;
}
}
?>
class Bedrijf
{
private $bedrijfsid;
public function setBedrijfsID($bedrijfsid)
{
$this->bedrijfsid = (int)$bedrijfsid;
}
public function getBedrijfsID()
{
return $this->bedrijfsid;
}
// Hieronder methode 1
// Één methode voor het ophalen van gegevens en die aanroepen middels een andere methode
// Voordeel: éénmaal lange(re) code voor de query, kan onderaan in de code, zit dus niet in de weg
public function getBedrijfsnaam()
{
return getBedrijfsgegevens('naam');
}
private function getBedrijfsgegevens($kolom)
{
$oDatabase = Database::getInstance();
$result = $oDatabase->setQuery("SELECT ". $kolom ." FROM bedrijf WHERE id = ". $this->bedrijfsid ." LIMIT 0,1");
if ( $oDatabase->countResults($result) == 1 )
{
$fetch = $oDatabase->fetchResults($result);
return (!empty($fetch[$kolom])) ? $fetch[$kolom] : 'onbekend';
}
else
{
return 'onbekend';
}
}
// Hieronder methode 2
// Dus per gegeven een aparte verbinding en methodes
// Voordeel: per waarde is een specifieke output te genereren
public function getBedrijfsnaam()
{
$oDatabase = Database::getInstance();
$result = $oDatabase->setQuery("SELECT naam FROM bedrijf WHERE id = ". $this->bedrijfsid ." LIMIT 0,1");
if ( $oDatabase->countResults($result) == 1 )
{
$fetch = $oDatabase->fetchResults($result);
return (!empty($fetch['naam'])) ? $fetch['naam'] : 'onbekend';
}
else
{
return 'onbekend';
}
}
// Verder zag ik ook een methode 'load()' die alle velden uit de database haalt.
// Deze velden worden in de $this-variabelen gezet middels methodes.
// Dit lijkt me onhandig, want ik hoef niet alles te selecteren als ik enkel de
// bedrijfsnaam wil selecteren. Ongeveer een voorbeeld:
public function load()
{
$oDatabase = Database::getInstance();
$result = $oDatabase->setQuery("SELECT * FROM bedrijf WHERE id = ". $this->bedrijfsid ." LIMIT 0,1");
if ( $oDatabase->countResults($result) == 1 )
{
$fetch = $oDatabase->fetchResults($result);
$this->bedrijfsid = $fetch['id'];
$this->bedrijfsnaam = $fetch['naam'];
// enz.
}
else
{
return 'onbekend';
}
}
public function getBedrijfsnaam()
{
return $this->bedrijfsnaam;
}
}
?>
Alvast bedankt voor het meedenken en voor de tips.
EDIT: de code kan fouten bevatten, is puur een voorbeeld :)
Gewijzigd op 24/07/2012 14:18:44 door Kevin de Groot
zie ook).
Dus je wil dan in 1x het hele model laden. Daar zijn 2 veelgebruikte methoden voor: het active record (AR) en de data mapper (DM). Jouw load() functie is een implementatie van het AR, een save() functie maakt het dan af. Een DM is een apart object dat de opslag van je modellen regelt, dit is misschien mooier, maar voegt ook een extra laag van complexiteit toe. Ik raad je dus methode 3 aan.
Bedenk wel dat je load() functie ofwel een exception wil laten gooien als het fout gaat, ofwel false terug laten geven (en true als het goed gaat). Een of andere string teruggeven is volstrekt nutteloos.
Richt je niet op onvolledige objecten, maar vul ze altijd volledig. Als je je, zoals jij nu doet, met Object Relational Mapping bezighoudt, het maken van dergelijke 'Bedrijf' objecten a.d.v. DB tabellen vormen onvolledige objecten een groot probleem, omdat je dan niet uit kan gaan van het werken van je code. Je weet immers niet of objecten geladen zijn of niet (Dus je wil dan in 1x het hele model laden. Daar zijn 2 veelgebruikte methoden voor: het active record (AR) en de data mapper (DM). Jouw load() functie is een implementatie van het AR, een save() functie maakt het dan af. Een DM is een apart object dat de opslag van je modellen regelt, dit is misschien mooier, maar voegt ook een extra laag van complexiteit toe. Ik raad je dus methode 3 aan.
Bedenk wel dat je load() functie ofwel een exception wil laten gooien als het fout gaat, ofwel false terug laten geven (en true als het goed gaat). Een of andere string teruggeven is volstrekt nutteloos.
Ik heb even "rond-gegoogled" en sommige dingen worden me nu wél wat duidelijker :)
Echter, heb je een kort voorbeeld voor mij hoe ik dit moet aanpakken in mijn voorbeeld? Ik kan dus properties van waarden voorzien middels setters en deze:
- óf laden, als voorbeeld middels load()
- óf saven, als voorbeeld middels save()
Zit ik in de goede richting? Ik ben nieuw met OO. Tutorials op dergelijke websites bevatten niet echt de juiste voorbeelden die ik kan toepassen in mijn eigen code.
Thanks! :)
Zo zul je bijvoorbeeld altijd te maken hebben met verschillende kolomnamen. Dan is het niet slim om voor elke kolomnaam een aparte membervariabele aan te maken. Het is veel handiger om een array aan te maken en die te laten uitlezen door een parentclass die alle kolomnamen uit je databasetabel trekt. Andere classen kunnen die basisclass dan extenden.
Denk ook na over welke functies je public maakt en welke private, en lees iets over interfaces en abstract classes. Een boek dat ik je kan aanraden is 'Head First Design Patterns'. Maar dan niet het hele boek, alleen de eerste paar hoofdstukken. Die zijn prima om een idee te krijgen van de voordelen van OOP.
Het blijkt dat ik me er maar verder in moet gaan verdiepen :)