Een kwestie waar ik over het internet nogal tegenstrijdige berichten van krijg is het gebruik van subclasses en/of 'wrapper' klassen. In dit thread wil ik hier jullie meningen over hebben welke nu 'beter' of 'netjeser' is.
Als voorbeeld neem ik Java's List interface, een interface voor verschillende 'lijsten' met gegevens / objecten. Ik kwam erop toen ik een List wilde gebruiken in een JSP / JSTL pagina:
welke, in theorie, de 'size()' methode van List aan moet vragen. Het probleem is echter dat JSTL (of wat dan ook, weet ik niet eens zeker) er van uit gaat dat alle objecten waar je gegevens uit haalt voldoet aan de JavaBeans specificatie. Het specifieke onderdeel hier van toepassing is het gebruik en de naam conventie van Accessors, namelijk dat ze altijd voorafgegaan zijn door 'get'.
In het bovenstaande geval probeert de JSP parser de methode 'getSize()' van List aan te roepen. Echter, List heeft geen getSize() methode, alleen een 'size()' methode.
Nu, meer bij het punt van dit topic. Je wilt nu eigenlijk een getSize() methode toevoegen aan de List interface. Gezien List een onderdeel is van de standaard Java library, wil je hier eigenlijk niet aan beginnen, gezien je dan eventuele aanpassingen in de Java standaard library ook telkens aan moet passen.
Dus, je wilt een klasse die de functionaliteit van List uitbreidt met een getSize() methode. Dit kan nu op in ieder geval twee manieren: een subklasse of een wrapper klasse.
Een subklasse is een uitbreiding op de bestaande klasse, zodat de nieuwe klasse ook automatisch de methoden van het origineel heeft. In dit geval is het een interface, gezien List ook een interface is.
De andere methode is een 'Wrapper' klasse, waar je een klasse maakt waar de List een veld in is:
*puf*. Juist, nu weet ik sowieso dat je met de subclass methode het zogenaamde 'Fragile Base Class' probleem kunt krijgen, misschien niet in dit voorbeeld, maar anderen wel. Je bent afhankelijk van de implementatie van List, en wanneer deze verandert, moet je code ook veranderen (tenminste, indien de methode namen veranderen of indien je de accessors niet gebruikt).
Aan de andere kant heb je de wrapper class, waarbij je telkens de getList() methode moet aanroepen om bij je daadwerkelijke List te komen. Je kunt je ListWrapper natuurlijk List laten implementeren, maar dan krijg je een lange lijst met methoden die niets anders doen dan de aanroep delegeren naar de lijst die opgeslagen is in de wrapper.
Mja, om maar een discussie op gang te laten komen in dit forum: Wat denk jij, subclass of wrapper class, of heb je nog een ander idee?
Als voorbeeld neem ik Java's List interface, een interface voor verschillende 'lijsten' met gegevens / objecten. Ik kwam erop toen ik een List wilde gebruiken in een JSP / JSTL pagina:
Java:
1
| <c:out value="${list.size}"/> |
welke, in theorie, de 'size()' methode van List aan moet vragen. Het probleem is echter dat JSTL (of wat dan ook, weet ik niet eens zeker) er van uit gaat dat alle objecten waar je gegevens uit haalt voldoet aan de JavaBeans specificatie. Het specifieke onderdeel hier van toepassing is het gebruik en de naam conventie van Accessors, namelijk dat ze altijd voorafgegaan zijn door 'get'.
In het bovenstaande geval probeert de JSP parser de methode 'getSize()' van List aan te roepen. Echter, List heeft geen getSize() methode, alleen een 'size()' methode.
Nu, meer bij het punt van dit topic. Je wilt nu eigenlijk een getSize() methode toevoegen aan de List interface. Gezien List een onderdeel is van de standaard Java library, wil je hier eigenlijk niet aan beginnen, gezien je dan eventuele aanpassingen in de Java standaard library ook telkens aan moet passen.
Dus, je wilt een klasse die de functionaliteit van List uitbreidt met een getSize() methode. Dit kan nu op in ieder geval twee manieren: een subklasse of een wrapper klasse.
Een subklasse is een uitbreiding op de bestaande klasse, zodat de nieuwe klasse ook automatisch de methoden van het origineel heeft. In dit geval is het een interface, gezien List ook een interface is.
Java:
1
2
3
4
5
6
| interface CustomList extends List { /** * roept de superklasse z'n size() methode aan. */ public int getSize(); } |
De andere methode is een 'Wrapper' klasse, waar je een klasse maakt waar de List een veld in is:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class ListWrapper { private List list; public ListWrapper(List list) { this.list = list; } public List getList() { return this.list; } public int getSize() { return getList().size(); } } |
*puf*. Juist, nu weet ik sowieso dat je met de subclass methode het zogenaamde 'Fragile Base Class' probleem kunt krijgen, misschien niet in dit voorbeeld, maar anderen wel. Je bent afhankelijk van de implementatie van List, en wanneer deze verandert, moet je code ook veranderen (tenminste, indien de methode namen veranderen of indien je de accessors niet gebruikt).
Aan de andere kant heb je de wrapper class, waarbij je telkens de getList() methode moet aanroepen om bij je daadwerkelijke List te komen. Je kunt je ListWrapper natuurlijk List laten implementeren, maar dan krijg je een lange lijst met methoden die niets anders doen dan de aanroep delegeren naar de lijst die opgeslagen is in de wrapper.
Mja, om maar een discussie op gang te laten komen in dit forum: Wat denk jij, subclass of wrapper class, of heb je nog een ander idee?