In "puur" OOP waar is dan de constructor voor bedoeld?

Voorbeeld. Stel we hebben een paths class en we willen (eenmalig) de path prefix instellen, dan lijkt me dit uitermate geschikt om via de constructor te doen:

<?php

private $path_prefix;

public function __construct($path_prefix) {
$this->path_prefix = $path_prefix;
}

?>
We hebben nu het voorbereidende werk gedaan, namelijk de path prefix instellen. Prima! Maar, wat zien we nu ook vaak? Dit:

<?php

private $path_prefix;

public function __construct($path_prefix, $paths = []) {
$this->path_prefix = $path_prefix;
$this->add($paths);
}

?>
Zoals je ziet is er nu in de constructor een mogelijkheid om direct bij het instantieren van de class een array met paden mee te geven. Hierdoor kunnen we dit doen...

<?php
$paths = new Paths($path_prefix, $paths);
?>
en hoeven we niet dit te doen...

<?php
$paths = new Paths($path_prefix);
$paths->add($paths);
?>
Nu is mijn vraag... als je de $paths direct via de constructor meegeeft, is dat dan eigenlijk wel goed OOP? Is de contructor daar ook echt voor bedoeld?
Oké. In het "echte" voorbeeld gebruik ik de constructor om een path prefix in te stellen. Deze path prefix wordt automatisch voor ieder path geprefixed. Deze path prefix is dus nodig om de paden te kunnen adden. Die path prefix stel ik dan ook in via de constructor.

<?php
$paths = new Paths($path_prefix);
$paths->add($array);
?>
Kijk, in dit geval gebruik je de constructor dus om een class te initialiseren. En volgens mij is dat waar de constructor voor is bedoeld.

Ik snap dat het makkelijk is om via de constructor meteen een paar paden mee te geven, maar wat ik dus wil weten is, is of dat goed OO is. Volgens mij is de constructor (officieel gezien) alleen bedoeld om een class te initialiseren, en niet om "extra" dingen te doen. Maar ik weet het niet zeker. Ik snap dat het heel makkelijk is om iets via de constructor toe te voegen, maar is dat ook de bedoeling van de constructor. Voor iets noodzakelijks als het toevoegen van een path prefix denk ik van wel, maar voor het toevoegen van paden zelf zou ik denken van niet. Dit is dus wat ik graag zou willen weten.
Wat versta je dan onder "gebruiksklaar"? Welke eigenschappen moeten direct na het initialiseren al "gebruiksklaar" zijn? En welke pas nadat je ze hebt "klaargezet" door een methode aan te roepen? Volgens mij zijn zulke vragen slechts ontwerpbeslissingen en is er niet een bepaalde keuze altijd "fundamenteel" beter OOP.

Bij jouw voorbeeld zou ik twee ontwerpbeslissingen laten meespelen.


<?php
$paths = new Paths($path_prefix);
$paths->add($array);
?>


1. Gebruik je altijd/meestal/vaak onmiddellijk Paths::add()new Paths()? Dan zou ik de methode add() toegankelijk maken via de constructor.

2. Kun je iets zinvols doen met het object na new Paths() zonder ooit de methode Paths::add() aan te roepen? Heb je iets aan het object zonder add()? Is het antwoord "Nee", dan zou ik add() ook toegankelijk maken via de constructor — misschien zelfs met een vereist argument als er altijd een pad moet worden opgegeven.
>> 1. Gebruik je altijd/meestal/vaak onmiddellijk Paths::add() ná new Paths()?

Ja, in feite altijd.

>> 2. Kun je iets zinvols doen met het object na new Paths() zonder ooit de methode Paths::add() aan te roepen?

Nee, want dan zitten er geen paden in. Ik snap nu wel wat je bedoelt... Iets om over na te denken inderdaad :-/
In PHP maakt het weinig uit, omdat alles gebeurt binnen de zelfde microseconde (nu ja...).


Maar stel je voor: je maakt een Windows programma.
Iets om foto's te resizen of filteren of zo.
Foto's in de GUI slepen; destination settings zetten; op de knop drukken ...


Je zult 200 foto objecten hebben (De fotograaf was nogal trigger happy).
Dan wil je pas zo laat mogelijk de resources in dat object zien; anders neemt dat veel te lang veel te veel geheugen in.

Dus in de constructor initieer je de variabelen die op settings lijken.
bv. het pad van de foto.

Pas wanneer je - 1 voor 1 - de foto's gaat resizen, roep je methode init() aan.
Dan pas maak je je object echt gebruiksklaar.
Zorg trouwens ook voor een methode free()

Je zit met een tijdsduur waar je op moet letten.
Kris, thanks voor je reactie, maar wat is dan in mijn voorbeeld met de Paths class volgens jou de juiste methode?

Reageren