Article View: be.comp.programming
Article #17710Re: JAVA-OO probleem
From: Frank Bailleul
Date: Tue, 09 Nov 1999 00:00
Date: Tue, 09 Nov 1999 00:00
143 lines
5871 bytes
5871 bytes
Hallo Bruno,
Je schreef:
> De vraag blijft dus: hoe kan je een statische method
> in een abstracte moederklasse een instantie laten cre�eren
> van het kind vanwaar de statische method wordt opgeroepen?
Ik weet niet of ik die vraag goed begrijp. Ik veronderstel dat je het
volgende wil kunnen doen:
Record the_record; // bevat oa. informatie over de tabel naam.
TableA table = (TableA)TableWrapper.makeInstance(the_record);
Je kan eventueel met een "prototype" werken. De statische method
in TableWrapper zoekt dan in zijn lijst van prototypes naar degene
die overeenkomt met het type dat je wil. Als je deze gevonden hebt
dan kan je een "clone" maken van dit prototype.
Elke tabel moet zich eerst natuurlijk registreren in de lijst van
prototypes.
Bijvoorbeeld (sorry voor de java code--het is weer al een tijdje geleden):
public abstract class TableWrapper {
private static Hashtable ht = new Hashtable; // mapt de table IDs op de
prototypes
public static TableWrapper makeInstance(String id) {
return ht.get(id).clone();
}
public static void registerTable(String id, TableWrapper prototype) {
ht.put(id, prototype);
}
}
Het nadeel is natuurlijk dat je ergens nog altijd de registratie van de
concrete
tabellen moet doen, bijvoorbeeld tijdens initialisatie van het programma. De
vraag
is dan of je wel iets wint t.o.v. juist een swich statement.
In C++ zou je gebruik kunnen maken van wat ik zou noemen "static
initializers"
voor de registratie. Iets van de volgende vorm (in java):
public class TableA extends TableWrapper {
class TableAInit {
TableAInit() {
TableWrapper.registerTable("A", new TableA);
}
}
static TableAInit init;
}
In C++ zou de constructor van de static member opgeroepen worden
voor main() en zouden alle tabellen dus vanzelf geregistreerd worden, maar
in Java wordt de static pas geinitializeerd wanneer de klasse de eerste keer
gebruikt wordt. Pech dus...
Een andere manier is het gebruiken van Reflection.
Ik veronderstel dat je de tabel naam kent. Dan zou je een of andere
conventie
kunnen kiezen voor de naamgeving van de concrete Table classes.
Bijvoorbeeld, voor de tabel "Employees" creeer je een overeenkomstige class
TableEmployees. Dan wordt de code vrij eenvoudig:
abstract class TableWrapper {
public static TableWrapper makeInstance(String tableName) {
try {
Class the_class = Class.forName("Table" + tableName);
TableWrapper table = (TableWrapper)the_class.newInstance();
// met wat coderen kan je ook de constructor direct oproepen en
// de parameters meegeven.
return table;
} catch (Exception e) {
return null;
}
}
Opmerking: Je kan ook de Record als parameter meegeven in de method
en daar je informatie uithalen.
Alles hangt er natuurlijk vanaf of de extra complexiteit van een "mooie"
(synoniem: "academische") oplossing opweegt tegenover een eenvoudigere
maar minder mooie implementatie. Als je niet veel tabellen
hebt, en als je database aan niet veel verandering onderhevig is qua nieuwe
tabellen, dan vind ik dat een gecentraliseerde switch perfect verantwoord is
en
niet opweegt tegen de kost (of: tijd) dat je moet steken in het zoeken naar
een
mooie, generieke OO oplossing. Als je aan de andere kant een framework
bouwt dat van toepassing is voor elke database, dan zou ik wel voor
de meest generieke oplossing kiezen.
Beste groeten,
Frank
Bruno Lowagie <bruno.lowagie@rug.ac.be> wrote in message
news:38282C86.3B09B996@rug.ac.be...
> > Fluit me maar terug als je dat nodig vindt ;) ik heb misschien
> > (waarschijnlijk?) je situatie verkeerd ingeschat.
>
> Mijn vraag was puur theoretisch en louter uit interesse,
> maar toch wil ik ter verduidelijking nog even schetsen
> wat ik bedoelde:
>
> De klasse Record is afgeleid van de klasse Tabel.
> Er wordt automatisch een Tabel-instantie gegenereerd
> met de meta-informatie van alle tabellen in onze database.
> De klasse Record voegt daar de gegevens van 1 record aan toe.
> Deze klassen zijn nauw verweven met een JNI waarmee ik
> mijn RDBMS kan aanspreken.
>
> Dit is mijn onderste laag.
>
> Daarboven heb ik een laag die van mijn RDBMS een soort
> ODBMS maakt en die moet verhullen dat de historisch
> gegroeide, archa�sche opgebouwde, slecht ontworpen
> database niet altijd even consistent is.
>
> Dat is de laag waarmee onze applicatie werkt.
> Ik wil niet dat de applicatie rechtstreeks gebruik
> maakt van de onderste laag.
> Je opmerking is misschien wel terecht, maar ik heb
> een keuze gemaakt waar ik mij aan wil houden.
>
> De vraag blijft dus: hoe kan je een statische method
> in een abstracte moederklasse een instantie laten cre�eren
> van het kind vanwaar de statische method wordt opgeroepen?
>
> Ik denk dat dit onmogelijk is in JAVA...
> Maar misschien heb ik het verkeerd voor.
>
> Bruno
Technical Details
Message-ID:
<GG0W3.399$M07.4012@news.chello.be>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<3821AFBF.D19B54FE@rug.ac.be> <3825FA4D.221DE8C6@student.kuleuven.ac.be> <38268FFE.3CF1A29F@rug.ac.be> <382708EA.766892DC@student.kuleuven.ac.be> <38282C86.3B09B996@rug.ac.be>Show Full Headers
Complete Article Headers
X-Google-Language: DUTCH,ASCII X-Google-Thread: fcea4,5cd683c88cd7912a X-Google-Attributes: gidfcea4,public From: "Frank Bailleul" <frank.bailleul@tvd.be> Subject: Re: JAVA-OO probleem Date: 1999/11/09 Message-ID: <GG0W3.399$M07.4012@news.chello.be> X-Deja-AN: 546615405 References: <3821AFBF.D19B54FE@rug.ac.be> <3825FA4D.221DE8C6@student.kuleuven.ac.be> <38268FFE.3CF1A29F@rug.ac.be> <382708EA.766892DC@student.kuleuven.ac.be> <38282C86.3B09B996@rug.ac.be> X-Priority: 3 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2014.211 X-Complaints-To: abuse@tvd.be X-Trace: news.chello.be 942184230 195.162.216.8 (Tue, 09 Nov 1999 22:50:30 MET) Organization: Chello Usenet Service X-MSMail-Priority: Normal NNTP-Posting-Date: Tue, 09 Nov 1999 22:50:30 MET Newsgroups: be.comp.programming