[oop] wat hoort in 1 class?
Kan iemand me uitleggen wat in 1 class hoort? Ik heb hier al een zelfde soort vraag gesteld, maar aangezien daar geen antwoord op komt, vermoed ik dat mijn vraag niet duidelijk is.
In de meeste gevallen is het heel duidelijk wat er in 1 class hoort. In sommige gevallen (vind ik) echter niet.
Een voorbeeld: ik wil in mijn systeem XML bestanden kunnen inlezen en genereren. Hoort deze functionaliteit thuis in 1 class, of moet je dit zien als 2 verschillende dingen en hoort het in 2 classes thuis?
Je zou kunnen zeggen, het is allemaal XML dus het hoort in 1 class, maar je kunt ook zeggen "inlezen" en "genereren" zijn 2 verschillende dingen, dus het hoort in 2 classes.
Kan iemand uitleggen hoe ik de juiste keuze kan maken hierin? Gelden hier "regels" voor?
Ik hoop dat ik het een beetje goed heb uitgelegd, kijk hier eens naar: https://www.youtube.com/playlist?list=PLfdtiltiRHWF_SLCBqWZshazWM8qLA2Ns
De grap is alleen dat ik natuurlijk zelf de naam kan bepalen.
Ik kan bijv. kiezen voor een XmlHandler, dit is dan een handler die van alles kan, lezen, schrijven enz.
Ik kan het ding ook een XmlReader noemen, en dan mag ie logischerwijs alleen iets lezen.
Mijn vraag heeft vooral betrekking op wat er bij elkaar hoort:
Ik wil een xml-string kunnen lezen en schrijven, en hetzelfde geldt voor bestanden, ook die wil ik kunnen lezen en schrijven. Hoort deze functionaliteit nu in 1 class thuis? Dus een XmlHandler class? Of moet je die functionaliteit verdelen? Dus een XmlReader class en een XmlWriter class... of misschien zelfs nog opsplitsen naar string of bestand: XmlFileReader, XmlStringReader enz.
Hoe bepaal je dat???
Gewijzigd op 01/06/2014 15:07:00 door Ozzie PHP
Daarnaast heeft SOLID helemaal niks met de naam van de klasse te maken. Goed om te lezen: http://code.tutsplus.com/tutorials/solid-part-1-the-single-responsibility-principle--net-36074
Die voorbeelden zijn allemaal erg duidelijk. Het gaat daar ook echt om classes. In dit geval gaat het eigenlijk meer om een "tool" om XML te kunnen lezen en schrijven.
Als je dan kijkt naar wie het "publiek" voor deze tool is, dan is dat in feite alleen een programmeur. Alleen een programmeur zou kunnen besluiten om de tool aan te passen. Is dan de conclusie dat je alles in 1 class zet?
Een reader, die leest het van... Juist de server! Dus de sysadmin behoort ook al tot je publiek :)
Maar er zijn ook heel veel situatie waarin het inderdaad maar gewoon mooi in 1 klasse kan.
Tevens raad ik alle 4 de artikelen in die serie aan, mocht je alleen artikel 1 gelezen hebben.
En wat heeft dan jouw voorkeur in deze concrete situatie als ik vragen mag?
Dus we hebben 4 functionaliteiten:
- xml string lezen
- xml string schrijven
- xml bestand lezen
- xml bestand schrijven
Hoe zou jij dat persoonlijk aanpakken? Eén class, meerdere classes?
Je kunt bijvoorbeeld een klasse maken als XML_Node. Als je dan een XML bestand wilt bouwen, kun je die nodes weer doorgeven aan een klasse die ze bewaart, etc.
Dus dit zou ik met meerdere klassen doen.
Ik heb ook al vaker gelezen dat het beter is om iets te veel klassen te maken, dan te weinig.
Kun je een voorbeeld geven van wat je hiermee bedoelt? Er zijn toch veel objecten die een handeling beschrijven? Een loader, een configurator, een processor enz. ?
foute class benaming
goede class benaming
Om maar even een overdreven duidelijk voorbeeldje te geven. Overigens hoef je niet zelf een xml class te maken gelukkig want die bestaat al. ^^
http://www.php.net/manual/en/class.xmlreader.php
Nee, die ga ik ook niet zelf maken ;)
Maar bijvoorbeel bij Yaml wil ik m'n eigen class maken die gebruik maakt van een bestaande library, zodat ik (indien nodig) de library kan vervangen, zonder dat ik de rest van de code hoef aan te passen.
Mijn vraag gaat niet over naamgeving, maar over wat in 1 class thuishoort.
Yaml is vergelijkbaar met xml en er zijn 4 belangrijke functies: een string schrijven, een string lezen, een bestand schrijven, een bestand lezen.
Mijn vraag is, horen deze 4 functies in 1 class thuis? Of horen ze bijv. in 2 classes thuis, namelijk een YamlReader en een YamlWriter? Of moet ik zelfs voor iedere functie een aparte class maken? Dus: YamlStringReader, YamlStringWriter, YamlFileReader en YamlFileWriter?
Als de Writer uit de voeten moet kunnen met bestaande YAML-bestanden, is zelfs een class YamlWriter extends YamlReader niet eens zo onlogisch. Dan staan ze niet meer los naast elkaar, maar gebruik je het extenden vrij letterlijk voor het bouwen van een logisch verlengstuk.
"Te" is nooit goed, maar meer in het algemeen kun je beter iets te veel kleine klassen hebben dan één te grote klasse.
Dat je voorlopig één library gebruikt, is geen doorslaggevende reden om er dan maar één klasse van te maken die (alle) functies uit die library implementeert. Hooguit is "overzicht" daarvan een tijdelijk voordeel, maar je wilt nu juist een OO-variant maken om niet voor eeuwig aan die ene library vast te zitten.
Van de andere kant... dan zou je dus ook een DatabaseReader class en een DatabaseWriter class kunnen maken, in plaats van één Database class. Maar dat is toch niet gebruikelijk?
In wezen doe je dat ook wel, want je spreekt de database zelden of nooit rechtstreeks aan vanuit applicaties: er zit vaak een mapper, een data access object of iets anders tussen. Bovendien heb je zelden één database-klasse, maar aparte klassen voor bijvoorbeeld connecties, prepared statements en results.
Yup, maar die maakt toch ook gebruik van de Database class? Normaal gesproken (zover ik weet) kan één database class lezen en schrijven, en gebruik je daar niet 2 afzonderlijke classes voor.
Nou, dat houdt dus in dat wanneer mensen op je site komen en niks wijzigen (wat meestal het geval is) dat toch iedere keer ook de "writer" functionaliteit van de database wordt geladen maar niet gebruikt (tenzij je alles hebt gecachet, maar dat even terzijde). Dus als je dan consequent bent, zou je ook hier een aparte DatabaseReader en DatabaseWriter moeten maken.
Kortom... waar leg je de grens? Je kunt ook zeggen, alles wat met YAML te maken heeft, stop ik in één class. En dit is dus precies waar mijn vraag over gaat. In de meeste gevallen is het duidelijk wat in 1 class hoort, maar in sommmige gevallen zoals deze vind ik het niet heel duidelijk.
Gewijzigd op 02/06/2014 17:08:05 door Ozzie PHP
Ozzie PHP op 02/06/2014 17:07:27:
Nou, dat houdt dus in dat wanneer mensen op je site komen en niks wijzigen (wat meestal het geval is) dat toch iedere keer ook de "writer" functionaliteit van de database wordt geladen maar niet gebruikt (tenzij je alles hebt gecachet, maar dat even terzijde). Dus als je dan consequent bent, zou je ook hier een aparte DatabaseReader en DatabaseWriter moeten maken.
Een cache is geen bijzaak, maar dat terzijde :-)
Dat het vaak sub-optimaal wordt aangepakt, wil niet zeggen dat het niet beter kan. Waarom zou je inderdaad een front-end applicatie die slechts content toont volledige rechten op een database geven? Wat moet zo'n applicatie met DELETE- en CREATE-rechten?
Ik denk dan voorzichtigheidshalve altijd maar: wat ergens in zit maar nooit gebruikt wordt, kan alleen nog worden misbruikt. Dus ik geef je helemaal gelijk: het kan ook anders en beter.
Het nadeel van design patterns is dat het vooral standaardoplossingen van veelvoorkomende standaardproblemen zijn. Laat dat je er nooit van weerhouden om zelf afwijkende specifieke oplossingen te ontwerpen voor ontwerpproblemen die zich minder gemakkelijk laten generaliseren.
Van generiek naar specifiek. Een generieke databaseoplossing volstaat, een specifieke is waarschijnlijk beter.
En dan gaat het nog niet eens om de rechten, maar om het feit dat de update en insert methods gewoon aanwezig zijn in de class, terwijl je die niet eens kunt gebruiken als de rechten dit niet toelaten.
De keerzijde zou dan weer kunnen zijn... stel we moeten in één bestand een yaml string en bestand lezen en schrijven, we daar 4 classes voor nodig hebben... da's ook weer niet lekker.
Al met al... genoeg stof om over na te denken...