de OOP manier
Pagina: « vorige 1 2 3 volgende »
Je laadt in de servicecontainer alleen de servicedefinitie:
- dit is de service-id;
- dit is het pad naar de class;
- dit zijn de eventuele parameters.
Pas bij de $container->get('id') tovert de servicecontainer de juiste new class tevoorschijn.
Strikt genomen is dit type service container dus meer een service mapper: de services zitten er niet bij voorbaat automatisch al in. Vandaar ook dat Wouter terecht zegt dat je eigenlijk nog een service loader moet gebruiken om de juiste service container te vullen. Daarmee krijg je een nog striktere scheiding van het "laden" en het "hebben" van een service,
>> Pas bij de $container->get('id') tovert de servicecontainer de juiste new class tevoorschijn.
Ja, precies! Maar volgens jullie moet ik de "mailer" service pas in de container inladen op het moment dat ik 'm nodig heb.
Dus eerst werkt dit niet:
$container->get('mailer')
Vervolgens laad ik de servicedefinitie van de mailer in de container, en dan werkt dit wel:
$container->get('id')
Dat is toch wat jullie bedoelen te zeggen de hele tijd? Of begrijp ik het verkeerd?
Nee, je splits alles op in bestanden. Vervolgens laad je die bestanden (dus meerdere, niet 1 default bestand, maar meerdere bestanden) die je altijd nodig hebt. Vervolgens bepaal je dynamisch (aan de hand van configuratie) welke andere bestanden je nog meer nodig hebt.
Merk op dat dit niet wordt gedaan wanneer je de service nodig hebt, maar wanneer je de container maakt. Dus je workflow:
Request 1
1. Container aanmaken
2. Laden van configuratie
3. Aan de hand van de configuratie de services in de container laden (doormiddel van ContainerLoaders)
4. Container compilen (vast zetten)
5. Container cachen
6. Container gebruiken
Request 2
1. Gecachete container ophalen
2. Container gebruiken
Nee, je laadt de servicedefinitie meteen. Via die definitie lever je pas een service op als daarom wordt gevraagd.
Vergelijk de servicecontainer met een menukaart. We hebben hamburger en cheeseburger op het menu staan. De servicecontainer weet welke burgers we kunnen leveren en waar die precies vandaan komen. Maar we gaan natuurlijk pas een cheeseburger maken als erom wordt gevraagd.
Vandaar dat ik zei dat dit type servicecontainer eigenlijk in de eerste plaats een mapper is. De menukaart-service weet waar de cheeseburger vandaan komt. Maar bij het opstarten bak je niet meteen een hamburger én een cheeseburger omdat er "misschien" iemand een cheeseburger bestelt.
Ah zo, duidelijk verhaal! Ook met dat lijstje. Helemaal top. Wat houdt "compilen" in? Is dat een algemeen gebruikte term?
@Ward:
>> Nee, je laadt de servicedefinitie meteen. Via die definitie lever je pas een service op als daarom wordt gevraagd.
Dit is duidelijk. Maar uit het verhaal van Wouter, en waarschijnlijk is dat ook wat jij bedoelt, leid ik af dat je dus niet ALLE definities inlaadt in de container, maar alleen díe definities die je per applicatie nodig hebt. Correct?
Compile is het omzetten van het ene naar een andere taal. In dit geval heb ik het woord gewoon van symfony gestolen. Tijdens het compilen maak je van een container builder een geslote container die gereed is voor gebruik in je code.
Allright. Thanks voor de input! Hier kan ik wel weer even mee vooruit :)
Je classes krijgen een directe dependancy met je ServiceLocator (SL). En al geef je je SL door als parameter, dan is het nog steeds geen goede OO.
Het strookt bijvoorbeeld niet met de "Law of Demeter". De classes die de SL gebruiken moeten niet alleen de API van de SL kennen, maar ook van alle children die de SL heeft. Zelfde geldt voor " Single Responsibility Principle". Ook Unit Tests kunnen een probleem vormen en nog een hele lijst aan andere dingen.
Dus als je echt goed OO wilt doen, zou ik niet aan een SL beginnen.
Dan kan je beter een Inversion of Control (IOC) class maken. Daarmee geef je via interfaces door welke objecten classes/methods nodig hebben. Dan is zo'n class niet afhankelijk van een SL. Zo'n SL geeft namelijk ook toegang tot veel meer classes/services dan wanneer je in een methods parameter aangeeft welke classes hij mag krijgen.
Dus als je nog niets over IoC weet zou ik daar ook eens naar kijken.
Dan valt er vervolgens ook weer heel wat over IoC's te zeggen, Snel voorbeeld:
Stel bijvoorbeeld dat je in een Controller een "new object" aan maakt. Dat object geef je door aan een Model class. Die geeft het op zijn beurt weer door aan een andere class en dat nog een keer of 3. Dan weet je uit eindelijk dat je een "code smell" hebt. Omdat je een object een stuk of 5/6 keer moet doorgeven.
Bij een IoC zou je zo'n code smell al niet opmerken omdat je rechtstreeks een object kan meegeven aan de class die hem nodig heeft. Je hoeft dus niet al die classes langs om een object door te geven.
Zo zijn er nog wel een aantal voorbeelden te noemen. Ik zou niet zo snel aan allerlei termen en patterns hechten en gebruiken omdat het maar overal wordt geroepen. De meeste dingen zijn slechts in specifieke gevallen echt handig en sommige zijn helemaal niet handig, maar komen theoretisch gezien wel heel goed en logisch over. Zoals met Service Locators en IoC's.
D Vivendi, naast het feit dat je een leuke opsomming noemt met design patterns die door een DIC worden gebruikt en anti patterns die je niet met doen met DIC vraag ik me zeer af wat dit te maken heeft met dit topic...
Hmmm... dan vraag ik me af of we het wel over hetzelfde hebben. Juist via een service container kun je via de constructor precies aangeven welke classes er mogen worden gebruikt, dus ik snap niet helemaal wat je bedoelt te zeggen.
Ozzie, SL (Service Locator) pattern geldt wanneer je de container injecteert in een class i.p.v. alleen de services die je nodig hebt.
Ah oké, maar dat is niet echt de bedoeling lijkt me.
Nee, daarom is het ook een anti pattern :)
hehe... oke :)
Hehe... en welke wijze les kunnen we daar dan uit trekken Ward?
Stel dat je PSR-compatibele namespaces met een bijbehorende PSR-compliant autoloader hebt. Dan kan elke PHP-applicatie redelijk trefzeker elke beschikbare klasse uit een namespace laden.
Dat staat lijnrecht tegenover de servicecontainer waarin je gericht specifieke services voor specifieke applicaties beschikbaar stelt.
Beetje theoretisch en opzettelijk overdreven, maar die tegenstelling is wel interessant.
Ward, maar als antimaterie en materie bij elkaar komen wordt het 0 en dat wil je niet in je code. Als er bij het ontstaan van het heelal niet net iets meer materie was dan antimaterie (het is nog vaag waarom er wel meer antimaterie is) was er geen heelal geweest. :)
No, no different.
Only different in your mind.
You must unlearn what you have learned.
Geen alcohol meer voor jullie vanavond!