[ALG] State pattern bewaren

Pagina: 1
Acties:

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
Ik vroeg me af hoe je best een domain klasse die gebruik maakt van een state pattern persist naar een databank ofzo.

Stel ik heb een taak object die zich in verschillende staten kan bevinden: nieuw, bezig, afgewerkt,... (adhv lokale variabele weet ik in welke staat mijn taak zich bevindt) elk van deze staten is een implementatie van een staat interface die de mogelijke overgangsmethoden bevat.

Hoe bewaar je nu deze taak in je databank, zodat wanneer je deze terug opghaalt je terug in de oorspronkelijke staat terecht komt ?

Je kan bv met constanten werken (1 = Nieuwe staat, 2 = bezige staat, ...) maar het probleem is dat je dan ergens een logica moet hebben die weet dat constante 1 uit de datanbank overeenkomt met het nieuwe staat object, constante 1 overeenkomt met bezig staat object,... en dan 1 van deze taken in mijn taak object steekt.

Als ik die logica in mijn taak object zelf steek helpt dit me niet zoveel vooruit qua flexibiliteit, zou ik hiervoor een soort object gebruiken (klasse met verschillende factory methods) die mij adhv een constante het juiste staat object teruggeeft wat ik dan in mijn taak object kan setten ?

of hoe gaan jullie met dergelijke problemen om ? Om het nog wat concreter te maken: ik maak gebruik van hibernate en zou bv liefst kunnen een get doen in mijn DAO op ID van mijn Taak object en van zodra ik dit object terug krijg zou de taak zich in de juiste staat moeten bevinden...

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 07:20

.oisyn

Moderator Devschuur®

Demotivational Speaker

Cuball schreef op woensdag 11 april 2007 @ 11:40:
Je kan bv met constanten werken (1 = Nieuwe staat, 2 = bezige staat, ...) maar het probleem is dat je dan ergens een logica moet hebben die weet dat constante 1 uit de datanbank overeenkomt met het nieuwe staat object, constante 1 overeenkomt met bezig staat object,... en dan 1 van deze taken in mijn taak object steekt.
Euh, dat moet je sowieso als je willekeurige klassen wilt serializeren. Of je moet een OO database gebruiken die dat voor je doet, maar die doet intern exact hetzelfde. Ik weet niet in welke taal je werkt, maar je zou natuurlijk adhv reflection (Java, .Net) je klassen weer kunnen instantieren. Of een algemene factory waar je klassen zich kunnen registreren adhv een id (klassenaam) en die geinstantieerd kunnen worden met een blok data.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
De gebruikte taal is Java, maar ik vind het gewoon wat vreemd dat je zo weinig informatie vindt op het net waar ze dergelijke problematiek behandelen (persisten van staat)

Reflectie is inderdaad een mogelijkheid, maar klinkt beetje vies :-)

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Waarom is het zo'n probleem om gebruik te maken van een enum type die de state waarin het object zich bevind teruggeeft ?
Is het een probleem om ook deze enum in je tabel in je DB op te slaan, en te mappen naar een code-tabel in je DB die de beschrijving van iedere mogelijke state bevat ?

Kan je dan niet in je repository / DAO gewoon de juiste state-instantie creeëren adhv die enum ? (evt mbhv een factory ? )

Ik denk trouwens dat deze problematiek in het DDD boek van Jimmy Nilson een beetje / summier behandeld wordt. Als ik tijd heb, zal ik vanavond even kijken.

[ Voor 16% gewijzigd door whoami op 11-04-2007 12:07 ]

https://fgheysels.github.io/


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
Kan je dan niet in je repository / DAO gewoon de juiste state-instantie creeëren adhv die enum ? (evt mbhv een factory ? )
dit is het inderdaad zoals in eerste instantie had gedacht, via factory methods de juiste state instantie gaan ophalen
Ik denk trouwens dat deze problematiek in het DDD boek van Jimmy Nilson een beetje / summier behandeld wordt. Als ik tijd heb, zal ik vanavond even kijken.
boek heb ik nog niet gelezen, enkel deze DDD van Evans, maar daar als ik me goed herinner vind je daar weinig terug over dergelijke problemen

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Cuball schreef op woensdag 11 april 2007 @ 11:40:
Ik vroeg me af hoe je best een domain klasse die gebruik maakt van een state pattern persist naar een databank ofzo.

Stel ik heb een taak object die zich in verschillende staten kan bevinden: nieuw, bezig, afgewerkt,... (adhv lokale variabele weet ik in welke staat mijn taak zich bevindt) elk van deze staten is een implementatie van een staat interface die de mogelijke overgangsmethoden bevat.

Hoe bewaar je nu deze taak in je databank, zodat wanneer je deze terug opghaalt je terug in de oorspronkelijke staat terecht komt ?
Zou het erg zijn als je gewoon de default termen gebruikt voor deze dingen? State, Database, Task etc. Doet geen afbreuk aan het nederlands en iedereen weet waar je het over hebt. Ik moest nl. echt even kijken wat er met 'staat' bedoeld werd hier (ik dacht nl. even dat je namen van landen aan het opslaan was. Het eigenlijke NL woord is nl. Toestand)

Overigens is het nog maar de vraag of de state van een task bij de task an sig hoort of bij de context waarin de task gebruikt wordt. Immers, binnen de state machine heeft de task een zekere state en alleen de state machine bepaalt naar welke state de task gaat bij een zeker event E. Want wat te doen wanneer je nested statemachines hebt? Ga je dan 2 'state' variabelen aanleggen?
Je kan bv met constanten werken (1 = Nieuwe staat, 2 = bezige staat, ...) maar het probleem is dat je dan ergens een logica moet hebben die weet dat constante 1 uit de datanbank overeenkomt met het nieuwe staat object, constante 1 overeenkomt met bezig staat object,... en dan 1 van deze taken in mijn taak object steekt.
Tja, dat is dus problemen zoeken die er niet zijn. Ik bedoel, IEDERE variable van het type enum is bij deze een probleem in jouw ogen, want je kunt nooit die objects wegschrijven, want tja, wat stelt '1' nou voor?.

Je data in de database is 'data', geen informatie. Je maakt er informatie van door het in context te plaatsen. M.a.w.: de '1' of '2' die de state weergeven voor een zekere task instance T stellen de state voor van T en niets anders. In de context waarin je T gebruikt, bv een statemachine S, is 1 of 2 een zekere gedefineerde toestand. Ergens anders zijn het gewoon getallen. Ze stellen in theorie wel een state voor van de instance T, maar wat 1 en wat 2 is is niet gedefineerd op dat niveau en ook niet belangrijk, immers dat is alleen belangrijk voor S.
Als ik die logica in mijn taak object zelf steek helpt dit me niet zoveel vooruit qua flexibiliteit, zou ik hiervoor een soort object gebruiken (klasse met verschillende factory methods) die mij adhv een constante het juiste staat object teruggeeft wat ik dan in mijn taak object kan setten ?
Heeremetiid, je kunt ook tever doorschieten met abstractieniveaus creeeren zeg. :) Ik zou zeggen, gebruik een cast, lijkt me stukken simpeler. Factories om van een int naar een enum te komen, het moet niet gekker worden.
of hoe gaan jullie met dergelijke problemen om ? Om het nog wat concreter te maken: ik maak gebruik van hibernate en zou bv liefst kunnen een get doen in mijn DAO op ID van mijn Taak object en van zodra ik dit object terug krijg zou de taak zich in de juiste staat moeten bevinden...
Dat kan alleen als je T toevoegt aan een statemachine S die dan weet dat T een zekere state heeft. Waarom heb je anders die toestand nodig -> alleen voor een statemachine.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 07:20

.oisyn

Moderator Devschuur®

Demotivational Speaker

whoami schreef op woensdag 11 april 2007 @ 12:06:
Waarom is het zo'n probleem om gebruik te maken van een enum type die de state waarin het object zich bevind teruggeeft ?
Het nadeel is natuurlijk dat je de enum aan moet passen elke keer als je een bepaalde state introduceert. Bij een voorgedefinieerd aantal states is dat natuurlijk niet echt een probleem, maar het state pattern is nou juist zo flexibel omdat je willekeurige state instances erin kunt hangen en je dus ook niet per se vast zit aan een lijst met states. Ook zou het kunnen zijn dat client code zelf een state voor een object kan definieren, dan wordt het zo goed als onmogelijk om een enum bij te houden - je hebt immers geen controle over je clients.
Cuball schreef op woensdag 11 april 2007 @ 11:59:
Reflectie is inderdaad een mogelijkheid, maar klinkt beetje vies :-)
Onzin, dit is juist een van de voorbeelden waar reflection enorm handig is.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
.oisyn schreef op woensdag 11 april 2007 @ 12:40:

Het nadeel is natuurlijk dat je de enum aan moet passen elke keer als je een bepaalde state introduceert. Bij een voorgedefinieerd aantal states is dat natuurlijk niet echt een probleem, maar het state pattern is nou juist zo flexibel omdat je willekeurige state instances erin kunt hangen en je dus ook niet per se vast zit aan een lijst met states. Ook zou het kunnen zijn dat client code zelf een state voor een object kan definieren, dan wordt het zo goed als onmogelijk om een enum bij te houden - je hebt immers geen controle over je clients.
dat was ik nu ook net aan het denken, als ik zou gebruik maak van enums verlies ik een groot deel van de redenen waarom ik een state pattern zou willen gebruiken.
Onzin, dit is juist een van de voorbeelden waar reflection enorm handig is.
ahzo, dan ga ik het zo maar eens implementeren :-)

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
.oisyn schreef op woensdag 11 april 2007 @ 12:40:
[...]

Het nadeel is natuurlijk dat je de enum aan moet passen elke keer als je een bepaalde state introduceert.
Ik ben even niet mee ....
Als je een nieuwe state introduceert, dan impliceert dat toch ook dat je een nieuwe implementatie van je interface nodig hebt die je state definieert ? Wat is het probleem dan om een enum erbij te maken ?

https://fgheysels.github.io/


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 07:20

.oisyn

Moderator Devschuur®

Demotivational Speaker

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface IState
{
    public void doeIets();
}

class StateA implements IState { /* ... */ }
class StateB implements IState { /* ... */ }
class StateC implements IState { /* ... */ }

class MyClass
{
    enum States
    {
        stateA,
        stateB,
        stateC
    }

    void setState(IState state) { /* ... */ }
}


Nou komt er een meneer die vind dat er ook nog een state D nodig is. Hij implementeert dus een klasse die de IState interface implementeert, en zet die op een MyClass instance. Hij zal nu ook de enum aan moeten passen, wat A) onhandig is, en B) wellicht kan ie dat wel helemaal niet.

En als je toch al enums gebruikt, waarom dan überhaupt nog het state pattern gebruiken? En andersom: als je het state pattern gebruikt, waaom dan de extra redundantie van de enums?

[ Voor 5% gewijzigd door .oisyn op 11-04-2007 14:35 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Tja, ik zie niet direct een andere manier om je class te gaan persisten; tenzij, zoals je zelf al gezegd hebt, je via reflection in je DAO gaat kijken in welke state je object zich bevindt. Maar dan ga je toch ook in je DB moeten persisten (via een flag bv) in welke state dit record zich bevind, zodanig dat je, als je dat record uit je DB trekt, je de class correct kunt creeëren.

Echter, hier ook geldt dan dat, als er een nieuwe state komt, je een record in je DB moet bijmaken (in die code-tabel) die aangeeft welke state het is... Misschien kan die meneer dat dan ook wel niet ?

Hoedanook, het is idd niet nodig om ook nog eens een enum te gaan definieren. :)

De vraag is ook : moet je er vanuit gaan dat er een nieuwe state kan bijkomen ?

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
.oisyn schreef op woensdag 11 april 2007 @ 14:33:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface IState
{
    public void doeIets();
}

class StateA implements IState { /* ... */ }
class StateB implements IState { /* ... */ }
class StateC implements IState { /* ... */ }

class MyClass
{
    enum States
    {
        stateA,
        stateB,
        stateC
    }

    void setState(IState state) { /* ... */ }
}


Nou komt er een meneer die vind dat er ook nog een state D nodig is. Hij implementeert dus een klasse die de IState interface implementeert, en zet die op een MyClass instance. Hij zal nu ook de enum aan moeten passen, wat A) onhandig is, en B) wellicht kan ie dat wel helemaal niet.
Hoezo kan hij dat niet? Hoe komt het systeem dan in die toestand? Als de enum niet kan worden gewijzigd heb je de state transition tables ergens anders gedefinieerd dan de states die de table contents definieren, en dat lijkt me een beetje raar :)
En als je toch al enums gebruikt, waarom dan überhaupt nog het state pattern gebruiken? En andersom: als je het state pattern gebruikt, waaom dan de extra redundantie van de enums?
Een goede statemachine heeft geen enums nodig, correct (omdat de state value niet buiten de statemachine bekend is en binnen de statemachine niet meer is dan een index)

Je zou wel kunnen beargumenteren dat om te kijken in welke state een statemachine zit en in welke state een task zit, je met enums makkelijker weg komt want die kun je naar string converteren (cast) en dan heb je de naam :)

Overigens snap ik je interface niet, de state defineer je niet op het object dat in een state zit (want dan krijg je problemen bij nested state machines)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1