Toon posts:

[Java] Register van Instances; verstandig?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Java en ik kunnen het goed met elkaar vinden, behalve als het aankomt op het ontwerpen van een nette informatieflow binnen wat grotere applicaties. Een steeds terugkerend probleem is dat ik referenties naar Objecten nodig heb op plaatsen waar ik ze niet kan zien. Een klein fictief voorbeeld ter toelichting:

FRAME1 -> A -> B
-> SUBFRAME -> B

SUBFRAME wil hier data manipuleren binnen dezelfde B als de B die door A geinstantieerd is. Ik heb altijd de volgende aanpakken gebruikt om dit probleem te omzeilen:

1) klassevariabelen public maken
2) klassevariabelen en soms ook methoden static maken
3) referenties naar objecten het hele programma doorgooien
4) gebruik maken van IO

oplossingen waar aardig wat nadelen aan kleven. dus heb ik het volgende bedacht:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.Hashtable;

public class Register {

    private static Hashtable instanceTable = new Hashtable();

    public static void registerInstance(String name, Object obj) {
        instanceTable.put(name, obj);
    }

    public static Object getInstance(String name) {
        Object obj = instanceTable.get(name);
        if(obj != null)
            return obj;
        else {
            try {
                Class c = Class.forName(name);
                obj = c.newInstance();
                registerInstance(name, obj);
                return obj;
            } catch (WillekeurigeException e) {
                return null;
            }
        }
    }
}

spreekt aardig voor zichzelf, een object vraagt om een instantie van een object en krijgt of de bestaande instantie of een nieuwe instantie.
ik kan er iets meer mee, maar zit nog steeds met het probleem dat ik nu niet meer dan één verschillende instantie van zo'n klasse kan hebben (dan loopt het registeridee de soep in).
aangezien ik zelf al meerdere malen met de handen in het haar heb gezeten om dit soort problemen netjes op te lossen, hoopte ik dat er onder jullie ook mensen zijn die hiermee hebben zitten klooien en wel een nette oplossing weten. ik heb het gevoel dat dit het 'net' niet is.

mijn dank is groot ;)

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Het idee is opzich aardig.
Wat ik echter zou proberen is de objecten die je nodig hebt allemaal dezelfde interface te laten implementeren en dmv een factory de nieuwe instantie te laten creeren (Registerable ofzo :) ).

Waarbij je zowel een referentie-naam opgeeft als een type-naam.
In je hashtable kan je dus checken of de referentie al bestaat, zonee, dan de type instantieren vanuit je factory.
De factory is niet extreem noodzakelijk hierbij, maar is wel een wat nettere manier van abstractie dan je huidige voorstel :)

Vergeet trouwens niet, als het een multithreaded applicatie is, de 'synchronized' termen strategisch te plaatsen :)

Wellicht is het nog handig van je Register een Singleton-geinstantieerde gewone class te maken, dan kan je het evt mooier in je code toepassen en zit je niet met al die static methoden.

[ Voor 13% gewijzigd door ACM op 03-02-2003 22:35 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik denk dat je ook eens moet kijken naar de Singleton. (alhoewel hij voor dit geval niet een betere oplossing is, omdat je echt maar 1 instantie kan maken).

Verder kan je met jouw systeem geen compile time veiligheid garanderen en dat zou je eventueel met een indirection layer wel voor elkaar krijgen (dus bv een callback interface).

[ Voor 19% gewijzigd door Alarmnummer op 03-02-2003 23:04 ]


Verwijderd

Het idee is wel origineel. Misschien kan ik hier zelf ook wat mee. Ik loop er zelf ook wel eens tegenaan dat ik ergens een object nodig heb waar ik helemaal niet "bij kan komen". Mijn meest gebruikte oplossing is om inderdaad referenties naar een object mee te geven aan andere objecten.

Ik zou dit Register object zeker omzetten naar een singleton.
Ik kan er iets meer mee, maar zit nog steeds met het probleem dat
ik nu niet meer dan één verschillende instantie van zo'n klasse kan hebben
(dan loopt het registeridee de soep in).
Je zou het volgende kunnen doen: Wat jij als name gebruikt is eigenlijk de class name. Je zou een combinatie van de class name en een vrij te kiezen naam (identifier) kunnen gebruiken om het object in het Register op te slaan. Je kan dan meerdere instanties van dezelfde class opslaan onder verschillende namen.

Je krijgt dan zoiets:
Java:
1
2
3
    public static void registerInstance(String name, String className, Object obj) {
        instanceTable.put(name + ":" + className, obj);
    } 


Nu ik er echter wat langer over nadenk is het eigenlijk niet meer dan een verkapte vorm van globale variabelen. Misschien daarom niet echt fraai toch?

[ Voor 13% gewijzigd door Verwijderd op 04-02-2003 09:30 ]


Verwijderd

Topicstarter
Bedankt voor jullie reacties. ACM, kan je even toelichten wat het nut is van de interface in jouw verhaaltje?
compile time veiligheid, indirection layer, callback interface; tijd voor google 8)7
rmk, het toevoegen van de extra variabele aan de methodesignatuur heeft denk ik niet zoveel zin, omdat het object dat op zoek is naar een instantie dan weer over een lijst van namen moet beschikken (als ik je goed begrijp).

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 05 February 2003 @ 19:23:
Bedankt voor jullie reacties. ACM, kan je even toelichten wat het nut is van de interface in jouw verhaaltje?
Dat komt door de factory, daarmee kan je de verantwoordelijkheid over het maken van specifieke objecten uit besteden aan een ander object (de factory) waardoor dat niet verweven komt te zitten met je Register code, een Interface is niet verplicht oid, maar het is wat netter dan steeds maar domweg Objects retourneren als je maar een heel kleine subset daarvan retourneert, zeker als je daarna hoopt dat die Objecten bepaalde methodes kennen :)
het toevoegen van de extra variabele aan de methodesignatuur heeft denk ik niet zoveel zin, omdat het object dat op zoek is naar een instantie dan weer over een lijst van namen moet beschikken (als ik je goed begrijp).

Tuurlijk wel, dan kan je meerdere instanties van bepaalde objecten hebben, geidentificeerd met de naam.
Aangezien HashTable daar al functionaliteit voor biedt kan je heel simpel de boel opzoekbaar maken door de naam ipv het type van de instantie mee te geven aan de HashTable.
Of dat ook is wat jij wil is een ander verhaal :)

  • ari3
  • Registratie: Augustus 2002
  • Niet online
Aaai... klassiek probleem... is al generiek opgelost in de Java spec.... Zoek naar: java.util.Observable en java.util.Observer.

Jouw Register klasse biedt veel overhead: je moet namelijk referenties verwijderen uit deze klasse anders worden ze nooit opgeruimd. Maak van jouw objecten observers of observables, ben je daar vanaf.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

ari3 schreef op 05 februari 2003 @ 21:53:
Aaai... klassiek probleem... is al generiek opgelost in de Java spec.... Zoek naar: java.util.Observable en java.util.Observer.
Observer/Observable is handig als je wilt luisteren naar iets, zonder dat dat iets zich druk hoeft te maken over de structuur van de luisteraar. Ik zie niet in waarom hier de observer/observable van toepassing zou zijn, omdat er niet echt sprake is van een veranderende waarde.
Jouw Register klasse biedt veel overhead: je moet namelijk referenties verwijderen uit deze klasse anders worden ze nooit opgeruimd.
Daarom is het handig om ze in een WeakReference te verpakken zodat de garbage collector ze wel kan collecten.
Maak van jouw objecten observers of observables, ben je daar vanaf.
Als jij een observer bent, en je bent aangemeld bij een observable, dan moet je jezelf gaan deregisteren als observer. Hierdoor kan je als je niet oppast een memory leak krijgen en dat is exact dezelfde fout als jij met jouw aanpak probeerd op te lossen. Zie GoF boek,

Daarnaast zie ik dus niet in hoe observer/observable hier van toepassing kan zijn.

[ Voor 5% gewijzigd door Alarmnummer op 06-02-2003 00:04 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

*kick* wil nog ff reply :)

  • Stephan Oudmaijer
  • Registratie: Oktober 2000
  • Laatst online: 16-08-2023
singleton kan toch ook.. dat is in principe een globale static variabelle die je zo uit de vm kan plukken.. gewoon getInstance aanroepen...

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Denk nou eens goed na. De kans bestaat dat er meerdere schermen zijn van dezelde class, hierdoor zou een singleton al sowieso niet opgaan. En verder is door een SIngleton dit probleem echt niet opgelost. Dus denk aub even na voordat je antwoord geeft.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

dom dom, jij moet een Mediator hebben. Dat is een class die ervoor zorgt dat andere classes geen sterke binding krijgen met elkaar, maar alle communicatie laten verlopen via de mediator.
Pagina: 1