[C#] 'State' Object

Pagina: 1
Acties:

  • cenix
  • Registratie: September 2001
  • Laatst online: 05-05 19:45
In de code van iemand anders moet ik wat zaken wijzigen. Deze persoon heeft een aparte klasse gemaakt waarin hij een tussenwaarde van diverse variabelen vasthoudt, deze heeft hij nodig omdat hij de oude informatie nog tijdelijk wil bewaren, totdat hij zeker weet dat de nieuwe gegevens in orde zijn.

Een voorbeeldje

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class TempObjectState
{
  private int id;
  private string waarde;
  // en nog veel meer...

  public TempObjectState()
  {}

  public string Waarde
  {
    get { return waarde; }
    set { waarde = value; }
  }
  // etc..
}


Nu wil het dat er iets moet komen waardoor ik de huidige waarde kan vasthouden en de eventuele nieuwe waarde toch kan opslaan. Hiervoor was een 'soort van' oplossing, namelijk hij gebruikte een 2e set variabelen om de oude en de nieuwe waarde vast te houden, zoiets dus

C#:
1
2
3
4
5
6
7
8
  private string oudwaarde;
  private string nieuwwaarde;

  public string Waarde
  {
    get { return oudwaarde; }
    set { nieuwwaarde = value; }
  }


bij een soort van commit actie werd van de oudwaarde overschreven met de nieuwwaarde.
Deze manier werkt opzich redelijk aardig, maar heeft toch bepaalde gevolgen -- wat als ik de nieuwwaarde nu al wil weten?

Is dit een goede/aardige oplossing?
Ik heb tevens ook al gehoord dat 2e klassen (een voor de oude en een voor de nieuwe waardes) een andere manier is.

Wat is nu de beste oplossing of moet het helemaal anders?
Ik wil gewoon wat meer onderbouwde informatie over hoe zoiets het beste aan te pakken is.

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 07-05 11:11

alienfruit

the alien you never expected

Geen idee hoor, maar ik zou gewoon een clone() functie toevoegen aan je klasse. Vervolgens een kloon maken van je waardes en in deze instantie de nieuwe waarden opslaan. Als vervolgens gecontroleerd is of de gegevens correct zijn, dan de juiste object commit-en. Zo zoui ik het in iedergeval doen, maar er zijn vast meer zoals whoami of Alarmnummer die je beter kunnen adviseren.

Verwijderd

Afhankelijk van de context heb je weinig aan een gekloont object als je e.e.a. over al je lagen wilt doorgeven (of je moet zowel de oude als de nieuwe waarden als params meegeven)

je kan ook zoiets bedenken;

maak een nieuw class met twee (public) properties "OldValues" (alleen get) en "NewValues" (get en set) van het type "TempObjectState". De oude waardes kan je dan getten via OldValues.EenOfAndereParameterDieJeWildeOpslaan

en de nieuwe waarde kan je dan vai NewValues.EenOfAndereParameterDieJeWildeOpslaan ophalen of setten.

Verder nog 1 of 2 methods ofzo ("CommitData()" en "RevertChanges()") voor het overkopieren van de oude naar de nieuwe of andersom, wat jij leuk vind (bij het kopieren van de nieuw naar de oude wel via de private kopieren, anders dan ga je nat omdat de public propertie get-only is)

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:00
Ik vind het maar een rare oplossing....

Ik zou aan mijn object zelf een 'BeginEdit', Commit en Rollback method ofzo toevoegen.

De begin-edit zorgt er dan bv voor dat de huidige state in een stack (binnen jouw object) bewaard wordt.
Dan kan je wijzigingen doen, en mbhv de rollback method kan je altijd terugkeren naar de waardes die je in die stack hebt opgeslagen.
Met een Commit gooi je gewoon het bovenste item van de stack weg.

Zo bv:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyObject
{
   private Stack _stateStack = new Stack();

   private string melp;
   private int bliep;

   public void BeginEdit()
   {
        // Serialize melp en miep naar een memorystream en push die op de stack
   }

   public void Rollback()
   {
         // Haal de laatst toegevoegde memory-stream van de stack (de 'bovenste')
         // en restore de waarden.
   }

   public void Commit()
   {
        // Pop de laatst toegevoegde mem-stream van de stack, en behou gewoon je waardes.
   }

}


Het voordeel van het werken met zo'n stack is dat je nu meerdere keren na elkaar je beginedit() kunt oproepen, en zo heb je dus meerdere 'states'.

code:
1
2
3
4
5
6
7
8
9
MyObject o = new MyObject();
...
o.BeginEdit();
...
o.BeginEdit();
...
o.Rollback();
....
o.Commit();

[ Voor 52% gewijzigd door whoami op 24-05-2005 20:33 ]

https://fgheysels.github.io/


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Ik zou een aggregatie maken, een class die aanspreekpunt is, deze klasse heeft twee member classes van hetzelfde type, een met de newvalues en een met de oldvalues. Standaard geeft je met get de oldvalues terug (zoals bovenstaand, ivm backward compatibility) en met extra properties geef je de nieuwwarde terug.

Bij een commit save je het new object bij een rollback het old object.

If you are not wiping out you are nog pushing enough...


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:00
Die backward compatibility is natuurlijk wel een goeie.

Bij mijn systeempje heb je dat nl. niet....

https://fgheysels.github.io/


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Lees je oplossing nu pas whoami. Daar zit ook wat in, maar zou ik het als volgt doen.

Op de stack bewaar je oude objecten van dit type, d.m.v. een clone functie. Vervolgens kun je met properties/ functie met een parameter aangeven hoeveel revisies je terug wilt gaan en van die objecten de waarden retourneren.

If you are not wiping out you are nog pushing enough...


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:00
MaxxRide schreef op dinsdag 24 mei 2005 @ 20:57:
Op de stack bewaar je oude objecten van dit type, d.m.v. een clone functie. Vervolgens kun je met properties/ functie met een parameter aangeven hoeveel revisies je terug wilt gaan en van die objecten de waarden retourneren.
Mja, er zit wat in, mocht dat nodig zijn.
Echter, door ze te serializen denk ik dat je minder geheugen gaat vreten.

https://fgheysels.github.io/


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Tja het scheelt misschien wel wat geheugen, alhoewel het beide 'gewoon' in de heap komt te staan. Ik denk dat het voordeel van het geheugengebruik nihil zal zijn.

If you are not wiping out you are nog pushing enough...


  • cenix
  • Registratie: September 2001
  • Laatst online: 05-05 19:45
Bedankt.. ik heb een aantal ideen nu die ik eens ga proberen..

Verwijderd

MaxxRide schreef op dinsdag 24 mei 2005 @ 20:40:
Ik zou een aggregatie maken, een class die aanspreekpunt is, deze klasse heeft twee member classes van hetzelfde type, een met de newvalues en een met de oldvalues. Standaard geeft je met get de oldvalues terug (zoals bovenstaand, ivm backward compatibility) en met extra properties geef je de nieuwwarde terug.

Bij een commit save je het new object bij een rollback het old object.
hmmz oplossing komt mij erg bekend voor ;)

  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Je hebt gelijk lijkt erop (had je post overigens nog niet gelezen :D ). Er is alleen een nuance verschil in mijn oplossing behoudt je de oude properties waardoor je nieuwe object "backward" compatible is ;)

If you are not wiping out you are nog pushing enough...

Pagina: 1