EfBe schreef op donderdag 11 augustus 2005 @ 09:23:
[...]
Je haalt er weer weet ik wat bij, maar ik beschreef een duidelijke situatie: een framework dat INTERNE functionaliteit wil gebruiken en daar kun je geen interface voor gebruiken, want dan zijn die methods PUBLIC. (tenzij je die methods public wilt natuurlijk).
Dat ben ik met je eens. De troep die in een class staat waar niemand iets mee te maken heeft, kieper ik ook in private methodes.
In zn algemeenheid gebruik je daarnaast een abstract base class voor verplichte plumbing code en is het veelal zo dat je een interface daar al implementeert met abstract methods.
Gedeeltelijk. Als er al bepaalde logica in die abstract class zit, dan is het soms gigantisch lastig om daar andere implementaties van te leveren. En als je richting herbruikbare componenten zit, kan dit grote beperkingen opleveren. Ik ben er al te vaak tegen aangelopen.
Het nadeel van veel interfaces is dat het systeem complexer wordt. Als ik kijk naar Lucene zie ik dat de api relatief eenvoudig is om te gebruiken doordat ze niet veel interfaces hebben en omdat ze veel package friendly (dus buiten de package onzichtbaar) classes hebben. Tja.. de een vind het fijn, ik vind het minder prettig. Stukken code gebruiken is lastig omdat je er niet bij kan en omdat je niet een implementatie erin kan prikken waarover je 100% controle hebt.
1) spring is AOP, en heeft hier niets mee te maken
Spring kan AOP toepassen maar daar ging mijn opmerking niet over. Spring is een extreem uitbreidbaar platform (zie het al een normaal stuk java code) en doordat ze als basis bijna altijd een interface hebben, is het een genot om daar plugins voor te schrijven. Je hebt een algemeen contract.. als jij iets beters weet dan dat standaard in Spring zit.. nou.. maak maar een implementatie van dat contract en je bent klaar. En ik maak dus ook regelmatig uitbreidingen.
Voor veel andere frameworks waar ik mee bezig ben geld hetzelfde.
2) je begrijpt niet welke situatie ik bedoelde. Functionaliteit voor INTERN gebruik in een framework kun je niet in een interface stoppen, tenzij je die private implementeert.
Dat ben ik met je eens. Mijn interfaces zijn over het algemeen erg klein (meestal 2 tot 3 methodes) en die laten zeker geen implementatie-detail methodes zien (dat zou ook onzin zijn).
Maar op het moment dat je een framework hebt die op veel punten uitgebreid moet kunnen worden zorg ik ervoor dat ik contracten opstel waarmee verschillende implementatie geleverd kunnen worden. En mijn basis is dan bijna altijd een interface waarna ik steeds meer ga toewerken naar specifiekere implementatie.
Zie bv een de class hierarchie van:
ThreadPoolExecutor
Deze erf van een abstract class
AbstractExecutorService omdat er veel overeenkomstig gedrag is tussen de meeste ExecutorServices.
Maar als jij denkt dat jij iets beters kan leveren, dan kan dat:
De ThreadPoolExecutor die implementeerd de
ExecutorService een interface waarin beschreven wordt waar iedere executorservice aan moet voldoen. En een client vande executor service die heeft nog minder behoefte aan functionaliteit en die krijgt de meest minimale interface aangeboden:
Executor
Dit is een goed ontwerp waarbij je minimale contracten hebt, concretere contracten voor concretere situaties en abstract implementaties die de pijn weg kunnen nemen van het volledig zelf bouwen.
Dit beschouw ik als een goed ontwerp en deze manier van werken zie ik graag terug in mijn en ander mans code. Ik begin trouwens altijd bij wat is mijn client-wens voor deze interface, in dit geval de Executor. Vanaf dat punt ga ik dan werken naar concretere situaties. Op het moment dat ik in de herbruikbare componenten zit die uitgebreid moeten worden is dit mijn manier van werken. Als ik in een of ander eindproduct zit is dit niet mijn manier van werken aangezien herbruikbaarheid dan een veel minder grote rol spelen. Als je dan zo gaat werken ga je de baas geld kosten.
[
Voor 7% gewijzigd door
Alarmnummer op 11-08-2005 09:52
]