Voor een applicatie waar ik op dit moment mee bezig ben, heb ik een zwaar redeneer proces op een aparte thread lopen om de gui te ontlasten (anders blijft die helemaal stil staan). Daarna moet de thread ook weer contact op kunnen nemen met de gui om vragen te laten beantwoorden. Tijdens dit beantwoorden kan de gebruiker er oa voor kiezen om een andere sessie te beginnen, om een andere vraag opnieuw te beantwoorden, of om de redeneer sessie gewoon te laten stoppen. Tijdens het evalueren kunnen er fouten optreden (bv een rekenkundige fout of een database fout) en dezen moeten ook afgehandeld worden. Zoals je ziet heb je een groot scala aan mogelijkheden en dit zijn ze nog niet eens allemaal.
Ik heb 1 1/2 jaar geleden ook eens een oplossing voor gemaakt, maar ik was er eigelijk nooit tevreden over. Ik heb daar in de tussentijd veel over nagedacht hoe ik voor dit soort problemen (een probleem met een hele lading toestanden en toestandovergangen) een sluitende oplossing kon vinden.
Het ontwerp dat ik er voor heb gebruikt vond ik zelf eigelijk zeer ellegant. Ik heb op basis van een toestandsdiagram alle toestanden en alle events hiervoor geschreven vb:
Je kan nu vanaf de starttoestand, alleen in de running toestand komen, of je kan gereinitialiseerd worden. Door op deze manier te werken, kan ik garanderen dat je nooit in een verkeerde toestand kan komen. Daarnaast heb ik een object (de wrapper om de current state heen) gemaakt dat in zich een bepaalde toestand heeft, en voor ieder toestandsovergang een methode. Hij controleert eerst of je wel in de juiste toestand zit en stelt daarna de nieuwe toestand in (en is ook nog even zo vriendelijk om wat events te versturen naar listeners zodat de gui leuk kan reageren op de events).
Ik was eigelijk wel erg tevreden over dit ontwerp omdat ik nu eindelijk eens een sluitende oplossing had voor iedere toestand waarin de engine kan verkeren. Ik wist gewoon dat hiervoor wel ergens een design pattern voor moest bestaan. De 'State' design pattern lijkt hier wel een beetje op, maar deze had zich niet zozeer bezig met de toestandsovergangen, en deze doet dat wel.
Ik was gisteravond even aan het bladeren in thinking in patterns van Bruce Eckel, en zag daar ineens de State Machine design pattern staan.. en ik had zoiets van tjakkaa... dat is hem.. Ik raad dus iedereen aan om eens wat te gaan lezen over het state machine design pattern... echt een geweldige design pattern waarmee je inzicht krijgt en houdt in een systeem vol toestandsovergangen.
Ik heb 1 1/2 jaar geleden ook eens een oplossing voor gemaakt, maar ik was er eigelijk nooit tevreden over. Ik heb daar in de tussentijd veel over nagedacht hoe ik voor dit soort problemen (een probleem met een hele lading toestanden en toestandovergangen) een sluitende oplossing kon vinden.
Het ontwerp dat ik er voor heb gebruikt vond ik zelf eigelijk zeer ellegant. Ik heb op basis van een toestandsdiagram alle toestanden en alle events hiervoor geschreven vb:
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
27
28
29
30
31
32
33
34
| public class BeginEngineState implements EngineState { private static BeginEngineState s_instance = new BeginEngineState(); public static BeginEngineState getInstance() { return s_instance; } private BeginEngineState() { } public BeginEngineState reinit(){ return BeginEngineState.getInstance(); } public RunningEngineState start() { return RunningEngineState.getInstance(); } public void accepts(EngineStateVisitor v) { v.visit(this); } public String toString() { return "begin"; } } public class StartEvent extends EngineEvent { public StartEvent(EngineManager manager) { super(manager); } } |
Je kan nu vanaf de starttoestand, alleen in de running toestand komen, of je kan gereinitialiseerd worden. Door op deze manier te werken, kan ik garanderen dat je nooit in een verkeerde toestand kan komen. Daarnaast heb ik een object (de wrapper om de current state heen) gemaakt dat in zich een bepaalde toestand heeft, en voor ieder toestandsovergang een methode. Hij controleert eerst of je wel in de juiste toestand zit en stelt daarna de nieuwe toestand in (en is ook nog even zo vriendelijk om wat events te versturen naar listeners zodat de gui leuk kan reageren op de events).
Java:
1
2
3
4
5
6
7
8
9
10
11
12
| public void start() { if (!(_state instanceof BeginEngineState)) throw new EngineStateException(BeginEngineState.getInstance(), _state); _state = ((BeginEngineState) _state).start(); //stuur aan alle luisteraars het nieuwe event StartEvent startEvent = new StartEvent(_manager); for (Iterator<EngineListener> itt = _listenerList.iterator(); itt.hasNext();) { itt.next().start(startEvent); } } |
Ik was eigelijk wel erg tevreden over dit ontwerp omdat ik nu eindelijk eens een sluitende oplossing had voor iedere toestand waarin de engine kan verkeren. Ik wist gewoon dat hiervoor wel ergens een design pattern voor moest bestaan. De 'State' design pattern lijkt hier wel een beetje op, maar deze had zich niet zozeer bezig met de toestandsovergangen, en deze doet dat wel.
Ik was gisteravond even aan het bladeren in thinking in patterns van Bruce Eckel, en zag daar ineens de State Machine design pattern staan.. en ik had zoiets van tjakkaa... dat is hem.. Ik raad dus iedereen aan om eens wat te gaan lezen over het state machine design pattern... echt een geweldige design pattern waarmee je inzicht krijgt en houdt in een systeem vol toestandsovergangen.
[ Voor 11% gewijzigd door Alarmnummer op 05-08-2003 12:02 ]