Toon posts:

[JAVA]Singleton VS statische methodes

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb volgende topic gelezen.
[rml]whoami in "[ /14] nette code release versie *FAQ Upd..."[/rml]
nl punt 8. Vermijd het gebruik van static..

Het helpt me een deel, ik begrijp dat statische variabelen, als ze statisch zijn, gebruik worden, door alle instanties die aangemaakt worden van deze klasse, gemeenschappelijk gebruikt worden, dus van die statische variabele is er ook maar één.

Maar wat is nu echt het verschil tussen de twee

bv
code:
1
2
3
4
5
6
7
public class MyLogger{
     private static Logger logger = Logger.getRootLogger();

     public static void logThis(String message){
           logger.info(message);
     }
}

en
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyLogger{
     private static MyLogger instance = new MyLogger();
     private Logger logger;

      private MyLogger(){
           logger =  Logger.getRootLogger();
      }

      public static MyLogger getInstance(){
           return instance;
      }

     public void logThis(String message){
           logger.info(message);
     }      
}

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19-05 16:17

Robtimus

me Robtimus no like you

Het verschil is dat je bij de bovenste nog wel een instantie kan creeren. Als je daar ook een private constructor bij zet is er nog een verschil: bij static methods / vars kun je zelf nog wel meerdere instances creeren. De gebruikers van je class niet, maar jijzelf wel degelijk. Als je dit niet doet (geen of maximaal 1) dan is er in principe vrijwel geen verschil.

Waarom roep je trouwens in het tweede stuk logger.info() aan? Het is gebruikelijker om gewoon info van het huidige aanroepende object aan te roepen. Dat is toevallig altijd logger.

[ Voor 21% gewijzigd door Robtimus op 04-05-2004 11:57 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Als je gebruik maakt van een singleton object, dan kan je object 'state' bijhouden.
Als je gebruik maakt van een class met enkel static methods, dan kan je dat niet.

https://fgheysels.github.io/


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 19-05 07:31

Janoz

Moderator Devschuur®

!litemod

Bij de bovenste is er 1 RootLogger en vervolgens meerdere MyLoggers die allemaal 1 RootLogger aanroepen. Bij de onderste is er van de RootLogger en de MyLogger beide slechts 1. Elke keer als je getInstance aanroept krijg je dezelfde MyLogger terug.

De onderste is dus te prefereren omdat dit (oa) minder geheugen kost.

--edit--

Owh, ik zie nu pas dat het om een static methode gaat. In dat geval gaat mijn verhaal minder op :).

[ Voor 16% gewijzigd door Janoz op 04-05-2004 12:02 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
whoami schreef op 04 mei 2004 @ 11:58:
Als je gebruik maakt van een singleton object, dan kan je object 'state' bijhouden.
Als je gebruik maakt van een class met enkel static methods, dan kan je dat niet.
Die state is toch ook static anders kon ik hem niet gebruiken en mijn statische methode.

Verwijderd

Topicstarter
IceManX schreef op 04 mei 2004 @ 11:55:
Waarom roep je trouwens in het tweede stuk logger.info() aan? Het is gebruikelijker om gewoon info van het huidige aanroepende object aan te roepen. Dat is toevallig altijd logger.
Ik doe nog meer in die logger, normaal krijg de exception mee in die methode, zodat ik die dan kan afhandelen, bv een foutschermpje laten zien, zodat heel de exception afhandeling gecentraliseerd is.

[ Voor 28% gewijzigd door Verwijderd op 04-05-2004 12:11 ]


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

Alarmnummer

-= Tja =-

Het voordeel aan een singleton is dat het gewoon een class is waar je een instantie van kunt aanmaken (het is er maar 1.. maar toch.. het is er wel 1). Deze instantie kun je gewoon als argument aan allerlei objecten meegeven terwijl ze niets meer hoeven te weten over het feit dat het een singleton is. Dit krijg je niet zo snel voor elkaar met een 'static' class.

Trouwens Singletons kunnen zwaar naad worden binnen je systeem. Ik ben al meerdere keren op mijn bek gegaan nadat ik een systeem vol singletons geschikt wou maken voor client/server omgevingen. Ik geef daarom liever context/environment objecten mee waarin alle info staat. Singletons moet je dus heel erg goed mee oppassen.

  • Left
  • Registratie: Augustus 2001
  • Laatst online: 09-02 20:43
Er zijn maar heel weinig verschillen tussen statics en singletons.
Een verschil is performance: static methoden zijn ietsje sneller dan instance methoden.
Een ander verschil is dat je met een singleton een trucje uit kan halen: je kan de methode getInstance() ook een instantie van een subklasse van de singleton laten retourneren. Je kan bijvoorbeeld zoiets doen:

private static boolean testing;

protected Singleton() {}

public static Singleton getInstance() {
if(instance == null) {
if(testing) instance = new DebugSingleton();
else instance = new Singleton();
}
return instance;
}

Waarbij de klasse DebugSingleton een subklasse is van Singleton. Je moet de constructor van Singleton dan wel protected maken anders kun je geen subklasse maken. Of de methode getInstance() een interface laten retourneren, dat kan ook.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19-05 16:17

Robtimus

me Robtimus no like you

Verwijderd schreef op 04 mei 2004 @ 12:10:
[...]

Ik doe nog meer in die logger, normaal krijg de exception mee in die methode, zodat ik die dan kan afhandelen, bv een foutschermpje laten zien, zodat heel de exception afhandeling gecentraliseerd is.
Sorry, verkeerd gelezen. Ik dacht dat logger je static instance was, maar het is een gewoon field. Die ene statement boeit niet, is zelfs goed op deze manier. Je wilt nml niet je private field voor de buitenwereld zichtbaar maken, dus dan is dit de enige manier om te werken.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


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

Alarmnummer

-= Tja =-

Left schreef op 04 mei 2004 @ 12:37:
Er zijn maar heel weinig verschillen tussen statics en singletons.
Een verschil is performance: static methoden zijn ietsje sneller dan instance methoden.
vind ik een waardeloos argument:
-kans is groot dat dit gebonden is aan versies van een bepaalde vm. Misschien in de toekomst geen verschil meer in snelheid en toch heb je het in het systeem.
-hoe belangrijk is deze performance winst? Early optimization is the root of all evil!! Verder zijn macro optimalisaties meestal veel winstgevender dan microoptimalisaties (en die laatste verneuken je code meestal ook nog eens zwaar)
Een ander verschil is dat je met een singleton een trucje uit kan halen: je kan de methode getInstance() ook een instantie van een subklasse van de singleton laten retourneren.
Idd.. maar dan zit je al meer in de buurt van een abstract factory ipv een singleton.

[ Voor 9% gewijzigd door Alarmnummer op 04-05-2004 12:46 ]


  • Left
  • Registratie: Augustus 2001
  • Laatst online: 09-02 20:43
Ik wil helemaal niet zeggen of statics beter zijn of singletons. Ik heb voor allebei een eigenschap aangegeven die de ander niet had. En een verschil tussen statics en singletons is dat statics iets sneller zijn.
Welke eigenschap je belangrijker vindt hangt af van de specifieke eisen die jouw applicatie aan je klasse stelt. En stel dat performance optimalisatie je hoofddoel is, dan is het een overweging om statics te gebruiken ipv singletons.
Dit wordt bijvoorbeeld gedaan in Sun's eigen NetBeans.

Wat betreft dat 'trucje', inderdaad eigenlijk ben je een abstract factory aan het bouwen. Maar het met statics kan het niet, en deze post ging toch eigenlijk over het verschil tussen statics en singletons, niet wat er 'beter' is.

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

Alarmnummer

-= Tja =-

Ik flipte een beetje toen ik het woordje performance zag ;)

  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 19-05 17:00
Left schreef op 04 mei 2004 @ 13:36:
Ik wil helemaal niet zeggen of statics beter zijn of singletons. Ik heb voor allebei een eigenschap aangegeven die de ander niet had. En een verschil tussen statics en singletons is dat statics iets sneller zijn.
Welke eigenschap je belangrijker vindt hangt af van de specifieke eisen die jouw applicatie aan je klasse stelt. En stel dat performance optimalisatie je hoofddoel is, dan is het een overweging om statics te gebruiken ipv singletons.
Dit wordt bijvoorbeeld gedaan in Sun's eigen NetBeans.

Wat betreft dat 'trucje', inderdaad eigenlijk ben je een abstract factory aan het bouwen. Maar het met statics kan het niet, en deze post ging toch eigenlijk over het verschil tussen statics en singletons, niet wat er 'beter' is.
Is het ook niet zo dat statics aan de garbage collector gegeven kunnen worden indien er op dat moment geen references naar zijn, terwijl het bestaan van een singleton gedurende runtime gegarandeerd is?

If the world wouldn't suck, we'd all fall off


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

Alarmnummer

-= Tja =-

Swinnio schreef op 04 juni 2004 @ 16:37:
[...]
Is het ook niet zo dat statics aan de garbage collector gegeven kunnen worden indien er op dat moment geen references naar zijn, terwijl het bestaan van een singleton gedurende runtime gegarandeerd is?
Een static methode heeft geen object nodig, dus er valt niets te gc`en.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Alleen objecten worden door de garbage collector opgeruimd. Zowel de attributes van een singleton (zodra die geinstantieerd is) als die van de static attributes blijven gedurende de levensduur van het programma bestaan. Je zou eventueel wel kunnen overwegen om Singleton objecten tussentijds op te ruimen, maar ik kan me daar in de praktijk eigenlijk weinig bij voorstellen.

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
Waarom moet je binnen een Singleton klasse de instantie variabele en de methode getInstance nog static declareren? Is dat werkelijk nodig?

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

FallenAngel666 schreef op vrijdag 26 november 2004 @ 23:35:
Waarom moet je binnen een Singleton klasse de instantie variabele en de methode getInstance nog static declareren? Is dat werkelijk nodig?
Denk eens over je vraag na... :)

"Beauty is the ultimate defence against complexity." David Gelernter


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
Macros schreef op vrijdag 26 november 2004 @ 23:40:
[...]

Denk eens over je vraag na... :)
Nouja, je kan maar één instantie van de klasse maken (overervings trucjes en multi-thread problemen daargelaten). Wanneer je die variabele static declareert zorg je dat het een class variabele wordt i.p.v. een instance variable, maar in het geval van een Singleton maakt dat toch niet uit? Er bestaat maar één instantie van de klasse, dus je benaderd sowieso altijd dezelfde variabele. Toch?

[ Voor 31% gewijzigd door Kwistnix op 27-11-2004 00:09 ]


Verwijderd

FallenAngel666 schreef op vrijdag 26 november 2004 @ 23:55:
[...]


Nouja, je kan maar één instantie van de klasse maken (overervings trucjes en multi-thread problemen daargelaten). Wanneer je die variabele static declareert zorg je dat het een class variabele wordt i.p.v. een instance variable, maar in het geval van een Singleton maakt dat toch niet uit? Er bestaat maar één instantie van de klasse, dus je benaderd sowieso altijd dezelfde variabele. Toch?
en hoe zou jij dan garanderen dat er slechts 1 instantie is van die klasse? :+

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
Verwijderd schreef op zaterdag 27 november 2004 @ 00:17:
[...]


en hoe zou jij dan garanderen dat er slechts 1 instantie is van die klasse? :+
Nouja, de constructor is private en de getInstance methode controleert of er al een instantie bestaat. Is dat niet zo dan maakt ie er een, is dat wel zo dan geeft ie die instantie terug.

Verwijderd

FallenAngel666 schreef op zaterdag 27 november 2004 @ 00:25:
[...]


Nouja, de constructor is private en de getInstance methode controleert of er al een instantie bestaat. Is dat niet zo dan maakt ie er een, is dat wel zo dan geeft ie die instantie terug.
ja en hoe weet die getInstance() methode dan dat er al een instantie bestaat? ;) (ja daar komt idd static aan te pas :))

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
Verwijderd schreef op zaterdag 27 november 2004 @ 00:28:
[...]


ja en hoe weet die getInstance() methode dan dat er al een instantie bestaat? ;) (ja daar komt idd static aan te pas :))
OW NATUURLIJK!
Die variabele moet daavoor een class scope variabele zijn.
Sorry hoor, dat was wel heel erg lomp van me |:(
Af en toe heb ik van die absurd vage momenten...

[ Voor 8% gewijzigd door Kwistnix op 27-11-2004 00:33 ]


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Het gebruik van static beperken komt trouwens omdat je static methodes niet overgeerft worden door subclasses en dus als zodanig ook niet te overriden zijn.

Verwijderd

Glimi schreef op zaterdag 27 november 2004 @ 12:04:
Het gebruik van static beperken komt trouwens omdat je static methodes niet overgeerft worden door subclasses en dus als zodanig ook niet te overriden zijn.
Het gevolg daarvan is dat je vervalt in functioneel programmeren en niet optimaal bezig bent met object georiënteerd programmeren. Niet dat er iets mis is met functioneel programmeren, maar dat is niet de essentie van Java. Als je dat wilt doen, zou je een andere programmeertaal moeten overwegen.

Met een objectgeoriënteerde werkwijze kun je kiezen voor een dynamischer oplossing. Om bij het Logger-voorbeeld te blijven, zou je het singletonpattern eruit kunnen slopen, een algemene interface Logger kunnen declareren en verschillende implementaties daarvoor kunnen geven. Zo kun je naast elkaar een implementatie hebben die naar het scherm schrijft, eentje die naar een logfile schrijft en eentje die e-mails verstuurt met foutmeldingen. De impact van een wijziging beperkt enorm. Met een kleine toevoeging van functionaliteit kun je er zelfs voor zorgen dat er geen code aangepast hoeft te worden, maar de gebruiker kan kiezen in een configuratiebestand of scherm.

[ Voor 6% gewijzigd door Verwijderd op 28-11-2004 00:32 ]


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 16-05 13:05
Nadeel singleton: Je introduceert global data.
Nadeel static methods: terug naar procedureel programmeren.

Beiden zijn indicaties dat je in je ontwerp niet goed nagedacht hebt. Enkel in zeer specifieke situaties gebruik je een singleton. Persoonlijk denk ik dat dat bijna nooit is, geef me een voorbeeld en ik bedenk een andere betere oplossing.

Singleton vind ikzelf een pattern wat zwaar overgewaardeerd wordt en veel te gemakkelijk gebruikt wordt.

Static methods zijn gewoon ranzig. Als je naar dat middel moet grijpen dan ben je echt fout bezig. Static methodes krijg je vroeg of laat altijd spijt van. Wat je namelijk doet is verantwoordelijkheden van een bepaald object bij een andere partij neerleggen. (Static methodes in een vergaarbak met "handige" functies.) Voor zo'n situatie moet je juist gebruik maken van delegation.

Kortom: Gebruik je Singletons OF static methods en heb je geen stevig argument om dat te verdedigen, dan vind ik je een eikel... :Y) :P (No offence btw.... ;))

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 16-05 13:05
Verwijderd schreef op zaterdag 27 november 2004 @ 00:28:
[...]


ja en hoe weet die getInstance() methode dan dat er al een instantie bestaat? ;) (ja daar komt idd static aan te pas :))
Oh lachen, nu komen zulke constructies:
code:
1
2
3
4
5
6
MySingleton getInstance() {
  if (instance == null) {
    instance = new MySingleton();
  }
  return instance;
}



Of nog subtieler:
code:
1
2
3
4
5
6
7
8
9
10
MySingleton getInstance() {
  if (instance == null) {
    synchronized (MySingleton.class) {
      if (instance == null) {
        instance = new MySingleton();
      }
    }
  }
  return instance;
}


1 ding, threading... nog eenenorme zwakke plek van Singletons...
Beide constructies zijn niet threadsafe. Java garandeert niet dat een wijziging in een register atomair terug geplaatst wordt naar het geheugen. Lekker boeien denk je nu, ik draai toch single CPU. Eh, guess again, hyperthreading anyone... >:)

Kortom, singletons suck and you too if you use them. (Had ik al verteld dat ik radicaal tegenstander ben van Singletons?)

[ Voor 19% gewijzigd door The - DDD op 28-11-2004 15:49 ]


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19-05 16:17

Robtimus

me Robtimus no like you

Singleton is anders wel DE manier om maar 1 object te krijgen. Dat kan soms gewoon noodzakelijk zijn. Maar je hebt gelijk; als je die beperking niet hebt dan is singleton nergens voor nodig.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 16-05 13:05
IceManX schreef op zondag 28 november 2004 @ 16:59:
Singleton is anders wel DE manier om maar 1 object te krijgen. Dat kan soms gewoon noodzakelijk zijn. Maar je hebt gelijk; als je die beperking niet hebt dan is singleton nergens voor nodig.
Belangrijkste is dan om goed te kijken waarom een enkel voorkomen van het object noodzakelijk is. Ik ben zelf nog nooit een situatie tegen gekomen waarin een Singleton echt de enige oplossing was. Meestal kun je het op een nettere manier doen door gewoon goed de verantwoordelijkheden te verdelen (dit bevat dus ook object creatie)

Stel dat het voor DB toegang is, je hebt een pool met connecties waar je er eentje uit wil pakken. Dat zou betekenen dat zeer waarschijnlijk mensen die pool als een singleton op gaan zetten. Oh shit, nu moeten we opeens gaan connecten naar een tweede database.

De reden dat Singletons vaak gebruikt worden is dat men een manier wil hebben om makkelijk een wellknown object te kunnen benaderen. In geval van een Web applicatie, zet het ding dan op application scope. In het geval van een EJB container, haal het op uit JNDI (of het dan een Session bean is of een POJO maakt dan eigenlijk niet uit). In het geval van een Applet of Swing applicatie, what the fuck are you thinking? Bot gezegd, ok, maar in een Applet of Swing applicatie heb je volledige controle over de life cycle van je code (op GC na dan) en kun je prima de objecten uit delen die ieder object nodig heeft.

Uiteraard zijn er op dat moment ook nog instantiërings problemen die kunnen optreden. Maar over het algemeen kun je die dan veel beter beheersen omdat voor zover ik weet iedere omgeving wel een of andere vorm van bootstrapping mogelijkheid heeft.

[ Voor 27% gewijzigd door The - DDD op 28-11-2004 17:28 ]


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
In een project dat op dit moment loopt op mijn opleiding gebruiken wij het singleton patroon i.c.m. het Commenad Processor patroon.
De CP is dus een Singleton. Hoe zou je dat anders (beter?) kunnen oplossen?

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 16-05 13:05
FallenAngel666 schreef op zondag 28 november 2004 @ 19:10:
In een project dat op dit moment loopt op mijn opleiding gebruiken wij het singleton patroon i.c.m. het Commenad Processor patroon.
De CP is dus een Singleton. Hoe zou je dat anders (beter?) kunnen oplossen?
Die Command Processor is een typisch voorbeeld van een well known object.

Op basis van de info die je geeft kan ik nog geen uitspraken doen. Het hangt namelijk sterk af van de runtime omgeving waar je mee te maken hebt. Draait het in een container? (Web of EJB) Of is het een Swing applicatie?

Een globale lijst voor je undo historie zou een beweegreden kunnen zijn.

[ Voor 6% gewijzigd door The - DDD op 28-11-2004 22:03 ]


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
The - DDD schreef op zondag 28 november 2004 @ 21:51:
[...]


Die Command Processor is een typisch voorbeeld van een well known object.

Op basis van de info die je geeft kan ik nog geen uitspraken doen. Het hangt namelijk sterk af van de runtime omgeving waar je mee te maken hebt. Draait het in een container? (Web of EJB) Of is het een Swing applicatie?
Een globale lijst voor je undo historie zou een beweegreden kunnen zijn.
Het gaat om een Swing applicatie. De Command Processor wordt, naast het scheiden van aanroep en executie, vooralsnog uitlsuitend gebruikt voor undo - redo functionaliteit i.c.m. het het Memento pattern.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 16-05 13:05
Ok, en die undo - redo functionaliteit is waarschijnlijk de kern van het geheel. Die wil je uniek houden over je gehele applicatie.

Dat de command processor uniek is, lijkt me op basis van je gegevens van ondergeschikt belang. Echter de data die door de command processor gemanaged wordt (undo/redo lijst) is datgene wat uniek is.

Klopt het als ik vermoed dat je de memento gebruikt om de state van je commands te persisteren?

In ieder geval geeft dit me het vermoeden dat als je al een singleton zou gebruiken, dat dit dan eerder de undo/redo lijst zou moeten zijn. En niet de command processor. Die gebruikt enkel de lijst voor het opslaan van de laatste actie. Uiteraard kun je er dan voor keizen om deze twee samen te voegen tot 1 enkel object. De verantwoordelijkheden tussen deze twee zijn natuurlijk zeer nauw met elkaar verwoven.

Vraag blijft nu, een Singleton ja dan nee. Eerder zal de vraag zijn, is een Singleton te voorkomen? Dit hangt sterk af van de manier waarop je Commands aangemaakt worden. Wanneer deze uit een factory komen, dan heb je voor de factory waarschijnlijk ook een singleton gebruikt. Een factory is 1 van de weinige situaties waarin een Singleton wel de moeite waard is. In principe kun je het Singleton gedrag ook in de factory beleggen. Zodra jij de processor nodig hebt verzoek je deze aan de factory... functioneel gezien krijg je dan elke keer een nieuwe command processor, terwijl de factory hier een caching toepast.

Zeker als je een aparte factory voor je Command objecten gebruikt is het erg mooi om daar ook de Command Processor onder te brengen. Die twee horen bij elkaar zeg maar.

[ Voor 59% gewijzigd door The - DDD op 28-11-2004 22:53 ]


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 19-05 15:42
Ik maak geen gebruik van een Factory om Command objecten te creëren.
Het memento wordt inderdaad gebruikt om de state van een willekeurig object te bewaren in een Command object. De command objecten worden, afhankelijk van het type command, opgeslagen in een history list (stack) van de Command Processor. Om die reden is de CP een Singleton.

Alleen ga ik hiermee straks tegen een probleem aanlopen vrees ik.
De applicatie in kwestie moet tegelijkertijd meerdere instanties van hetzelfde model aan kunnen. Aan een model is een unieke view gekoppeld. De controller van deze view is verantwoordelijk voor het creëren van Command objecten.
De Command objecten van de verschillende model/view combinaties worden straks dus in dezelde historylist door elkaar opgeslagen en dat mag niet. Ik moet dus per model/view combinatie een unieke historylist gaan bijhouden.
Dus zal ik de CP en de history list moeten ontkoppelen, lijkt mij?
Dan hoeft de CP ook geen Singleton meer te blijven?

Nog een opmerking: ik vind in de huidige situatie wel handig dat de CP een singleton is, want dat betekend dat ik niet eindeloos referenties moet passen. Ik roep gewoon de getInstance() methode aan wanneer ik iets met de CP wil doen en ik krijg het CP object dat ik wil hebben.

[ Voor 66% gewijzigd door Kwistnix op 28-11-2004 23:19 ]


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 16-05 13:05
Op zich heb je een redelijk geldige reden om je CP singleton te maken, maar zoals jezelf al zegt loop je nu tegen problemen aan.

Mooiste zou zijn als je een enkel object blijft houden waartegen je kan blijven praten. Dat dus je CP je hele lijsten probleem oplost. Dat zou op zich kunnen, maar dan moet je op een of andere manier je Commands gaan koppelen aan specifieke lijsten. Aangezien je de implementer van de Commands hier niet direct mee wilt belasten, moet deze functionaliteit niet in de Command liggen. Wel kun je van de implementer te vragen een keuze te maken over het type command waar je mee te maken hebt.

Een mogelijkheid zou zijn om dit te doen via een extra interface/abstract class tussen je Command interface en je daadwerkelijke implementaties. Die gebruik je dan enkel als marker. Nadeel is dat je dan een stukje extra complexiteit krijgt in je CP en je moet iets gaan faciliteren wat betreft verschillende lijsten. Je krijgt dus bijvoorbeeld een hashmap undo/redo lijsten in je CP. De specifieke lijst benader je dan met 1 enkele methode waaraan je het type van de command mee geeft. Het is niet nice, maar volgens mij wel het minst erg.

Je zou er ook voor kunnen kiezen om een abstracte implementatie te maken voor je command met een final execute methode. Deze final execute methode doet het huishoudelijke werk, kiezen van de juiste lijst bijvoorbeeld. Je implementatie stop je vervolgens in een template methode. Zie GOF. Hierdoor kun je ervoor zorgen door een klein deel vast te leggen dat je wel de koppeling kan maken met de juiste lijst. (Ikzelf zou het eerst even uit moeten tekenen om te kunnen zeggen of dit een mooie manier is.)

Mij persoonlijk lijkt het in ieder geval het beste om in de Command vast te leggen werlke lijst het uiteindelijk uit moet komen. Wat je zo min mogelijk wil is het controleren op type met "instanceof", dat kan heel makkelijk de spuigaten uit lopen namelijk. Met mijn eerste suggestie probeer je dat te beperken door van ieder type lijst slechts 1 generieke interface te definiëren. Je hoeft dan enkel instanceof checks te doen op die interfaces.

De tweede optie belooft volgens mij iets beters. Je maakt nu in je CP een aantal methoden, voor iedere lijst 1. In je abstracte base Command met final execute methode definieer je dan welke lijst gebruikt moet worden. Dit doe je middels een call-back naar de CP.

Het zijn allemaal natuurlijk ruwe ideeën.

[ Voor 36% gewijzigd door The - DDD op 28-11-2004 23:52 ]

Pagina: 1