[oop] lege class
Pagina: « vorige 1 2 3 4 volgende »
Volgens mij proberen vele mensen al maanden jouw van deze zin af te zetten. Hoe kun je gedachte hebben over een concept dat niet "het exacte concept" is maar zomaar een "hersenspinsel van ozzie"? Kom eerst met een exact reallife use-case en dan kunnen we daar onze mening over geven. Er is geen one-size-fits-all principe in OO, elke situatie heeft weer een andere gedachte erachter en een andere aanpak.
In dit geval: Als je config niet meer is dan een array, dan moet je nog eens goed gaan nadenken over wat config precies doet. En ja, daarin gebruik je ergens een array, maar nee, als je het goed hebt uitgewerkt gebruik je hier geen object voor, omdat die precies hetzelfde als een array zou doen.
Thanks Dos. Misschien moet ik de data class abstract maken. En als ik dan bijv. een config class heb, dan laat ik die de Data class extenden. Dan heb ik wel een aparte Config class, alleen staan er dan geen methods in. Mocht het zo zijn dat ik in de toekomst toch extra methods nodig heb, dan kan ik die Config class uitbreiden en hoef ik niet te rommelen in de algemene Data class. Snap je wat ik bedoel?
En waarom zou je dan Data nooit mogen gaan gebruiken?
Dat is nu dus iets waar ik over zit te denken... in hoeverre is data niet gespecificeerd? Heb je ooit ongespecificeerde data? Het zou kunnen, en dan moet je 'm dus niet abstract maken.
Mijn 1e vraag is vooral of ik voor een specifieke toepassing een algemene class moet gebruiken, of dat ik een specifieke class moet maken (zonder methods) die de algemene class extend.
Quote:
Stel we hebben een algemene class Auto. Die kunnen we gewoon ergens voor gebruiken: $auto = new Auto(). Nu wil ik op een gegeven moment een Ford maken, maar die class is hetzelfde als de class Auto. Dus ik zou kunnen zeggen $ford = new Auto(). Ik zou ook een class Ford kunnen maken die ik de class Auto laat extenden en waar ik verder geen andere methods in plaats. Of misschien is het het handigst om de Auto class abstract te maken. Daar zat ik dus even over te denken. Maar laat anders maar zitten, ik verzin wel wat... thanks voor het meedenken in ieder geval.
Dit is niet eens een hele gekke gedachte Ozzie. alleen hoef je het hier niet abstract te maken. Wat je wel kan doen is een interface maken en deze implementeren in al die klasses. zo maak je gebruik van het programmeren naar een interface toe en niet naar een implementatie. ( Ook een OO principe )
OFTEWEL je kan een inversion of control ( IoC ) container gebruiken.
leesvoer:
http://www.bennorthrop.com/Essays/2008/program-to-interface-not-implementation.php
Ik kan de algemene Auto class een AutoInterface laten implementeren. Als ik dan een Ford class zou maken en die extend weer de Auto class, dan is ook in de Ford class de AutoInterface geimplementeerd.
Mijn vraag is dus (nog steeds). Moet ik voor een specifieke toepassing, de Ford, een aparte class maken die de Auto class extend? Of moet ik gewoon zeggen dat Ford een Auto class is?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
// optie 1
$ford = new Auto();
// optie 2
class Ford extends Auto {
}
$ford = new Ford();
?>
// optie 1
$ford = new Auto();
// optie 2
class Ford extends Auto {
}
$ford = new Ford();
?>
Dit is natuurlijk een fictief voorbeeld, maar in de praktijk zou je bijvoorbeeld dit kunnen krijgen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
// optie 1
$config = new DataContainer();
// optie 2
class Config extends DataContainer {
}
$config = new Config ();
?>
// optie 1
$config = new DataContainer();
// optie 2
class Config extends DataContainer {
}
$config = new Config ();
?>
Wat is nu wijsheid?
Gewijzigd op 09/03/2014 23:47:49 door Ozzie PHP
Je wilt niet een klasse die doet wat jij hem verteld hebt volgens een bepaalde implementatie. Je wilt een object waarvan het niet uitmaakt wie wat hoe of waar het is zolang hij bepaald gedrag overneemt.
Naar mijn mening is php niet echt een taal die polymorfisme goed tot zijn recht laat komen en de manier waarom je dit in Java of C# bijv. kan doen is veel beter dan kan je bijv doen
Auto is hierbij de interface en Ford is het object waaruit je dit wilt creëren
uitgebreid vb in java is:
http://www.sitepoint.com/quick-guide-to-polymorphism-in-java/
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
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
<?php
class Vehicle {
public function move()
{
return 'ride a vehicle';
}
}
class Ford extends Vehicle {
public function move()
{
return 'ride a Ford';
}
}
class Mercedes extends Vehicle {
public function move()
{
return 'ride a mercedes!';
}
}
$Ford = new Ford();
echo $Ford->move();
echo '<br>';
$Ford = new Mercedes();
echo $Ford->move();
?>
class Vehicle {
public function move()
{
return 'ride a vehicle';
}
}
class Ford extends Vehicle {
public function move()
{
return 'ride a Ford';
}
}
class Mercedes extends Vehicle {
public function move()
{
return 'ride a mercedes!';
}
}
$Ford = new Ford();
echo $Ford->move();
echo '<br>';
$Ford = new Mercedes();
echo $Ford->move();
?>
Dus in dit geval optie 2 denk ik. :) ( dit is dan ook echt je auto voorbeeld ) voor een config bestand weet ik niet of ik dit zou doen.
>> ... voor een config bestand weet ik niet of ik dit zou doen.
Wat zou je beweegreden zijn om het NIET te doen?
dus gewoon heel simpel een bestand met config.php
( dit doen veel grote frameworks ook en soms is het niet verkeerd om een beetje af te kijken )
Gewijzigd op 10/03/2014 09:42:41 door Reshad F
Reshad, het geval met auto's moet je oplossen met het Strategy pattern, niet met inheritance.
We hebben een algemene class om data in vast te houden. Deze class kun je gebruiken voor diverse toepassingen. Bijv. om route objecten in op te slaan. Zou jij dan voor de route objecten gebruik maken van die algemene class, dus $route_collection = new DataCollection($routes), of zou jij een aparte RouteCollection class maken, die niks meer doet dan de algemene DataCollection extenden?
Ozzie, het gaat niet over het algemeen. Lees mijn reactie helemaal boven aan deze pagina nog maar eens...
Wat zou je in deze concrete situatie doen?
Dus, we hebben een algemene DataCollection class, waar we een aantal specifieke toepassingen voor hebben. We willen een route collection maken, een paths collection en een config collection. Gaan we nu zeggen $route_collection = new DataCollection($routes), of gaan we een aparte RouteCollection class maken, die niks meer doet dan de algemene DataCollection extenden? Idem voor de paths en config collection?
Een PathsCollection, zoals al gezegd, naar mijn mening heeft een object die als array functioneert geen nut.
Een ConfigCollection, configuration moet je valideren, parsen, uitlezen en toepassen. Dit gaat veel verder dan een Collection alleen en dan ook weer: Op gegeven moment zul je gaan werken met een array van values, het heeft geen nut om dat om te zetten in een object.
Het hoeft toch ook niet een algemene data collection te zijn. Je gebruikt een algemene data class en kunt daarnaast extra methods toevoegen. In dat geval moet je dus een aparte RouteCollection class maken die de algemene data class extend.
>> Een PathsCollection, zoals al gezegd, naar mijn mening heeft een object die als array functioneert geen nut.
Op zich vind ik dat dan wel weer grappig, omdat jij ook classes bouwt om single key-value paren :)
En daar is naar mijn mening dus geen behoefte aan, aangezien je praktisch alle methods van die algemene data class moet overriden. Tevens zorgt het gebruik van een algemene class voor coupling tussen componenten van je library. Ik geloof in zo veel mogelijk losstaande componenten.
Je moet oorzaak-gevolg omkeren. Het draait niet om het nu extenden van een class, maar om het voor later afdwingen van een interface. Dat kan dus inderdaad betekenen dat je begint met een lege class OzzieFrameworkException extends Exception. Of, om dichter bij je concrete voorbeeld te blijven, met een class DataCollection implements ArrayAccess.
Dat lijkt dan in te gaan tegen het DRY principe. Als je classes kunt hergebruiken moet je dat toch juist doen? (Even afgezien van de vraag of het in dit specifieke geval wel of niet zinvol is.)
>> Je moet oorzaak-gevolg omkeren. Het draait niet om het nu extenden van een class, maar om het voor later afdwingen van een interface.
Hoi Ward :)
Ik snap niet helemaal wat je hiermee bedoelt. Ik heb dus al een algemene data class. Behalve voor het opslaan van algemene data, kan ik deze class ook gebruiken voor meer specifieke toepassingen. Bijvoorbeeld voor het opslaan van paden.
Nu kan ik hier 2 wegen voor bewandelen.
De 1e en meest simpele:
$paths = new DataCollection();
De 2e:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
class Paths extends DataCollection {
// deze class bevat geen methods
}
$paths = new Paths();
?>
class Paths extends DataCollection {
// deze class bevat geen methods
}
$paths = new Paths();
?>
Het verschil is dus dat ik in situatie 1 een algemeen, niet nader gespecificeerd object gebruik om data in op te slaan. In situatie 2 creëer ik een object dat specifiek is bedoeld voor de opslag van paden.
Beide objecten doen exact hetzelfde, maar in situatie 2 zeg je dus feitelijk: dit object is specifiek bedoeld voor de opslag van paden.
Het is een heel subtiel verschil, waarvan ik graag wil weten wat de voorkeur heeft.
Dat is precies wat ik bedoel :-) Zodra je extends of implements inklopt, ben je al een paar ontwerpfasen verder. Kennelijk heb je in dat voortraject besloten dat er verschillende soorten DataCollection-objecten zullen ontstaan en dan is class Paths extends DataCollection de meest logische oplossing. Dat je daarmee in eerste instantie één lege klasse (Paths) of misschien zelfs twee lege klassen (Paths en DataCollection) krijgt, is voor nu niet eens zo spannend; het draait erom dat je voor later een bruikbare structuur hebt.
Ik wist dus niet of mijn aanpak de juiste was, en of de 1e optie $paths = new DataCollection niet de meest logische was. Als ik echter naderhand iets moet aanpassen, dan wordt dat lastig. Dus vandaar dat ik dacht dat het misschien beter is om een PathsCollection te maken die DataCollection extends. Ik ben blij dat je het met me eens bent :)
Als ik nu ergens een PathsCollection object wil afdwingen, moet ik dan een extra PathsCollectionInterface maken? Of moet ik typehinten op de DataCollectionInterface? (zie ook mijn andere topic hierover)