Reference types in beheerschermen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ik zit met een design probleempje. Wanneer ik een object wil beheren geef ik deze vaak mee aan een beheersform (zie code).

C#:
1
2
3
4
5
6
7
8
Person person = new Person("Voornaam", "Achternaam");
formPerson form = new formPerson(person);
if (form.ShowDialog() == DialogResult.OK) {
    // OK button has been pressed
}
else {
    // Canceled
}


Nu is dit niet zo spannend maar ik krijg problemen als ik ook validatie toevoeg in het form. Ik maak gebruik van Fluent Validation. Dit framework valideert objecten door instanties mee te geven. Ook dit is niet echt spannend.

C#:
1
2
3
Person person = new Person("Voornaam", "Achternaam");
PersonValidator validator = new PersonValidator();
ValidationResult results = validator.Validate(person);


De problemen waar ik mee in mijn maag zit zijn alsvolgt:

Vóórdat ik ga valideren update ik de object instantie in het beheersform met de ingevulde waardes op het scherm. Als de validatie NIET goed gaat en ik druk op cancel dan zijn de waardes natuurlijk nog steeds geset omdat het object als reference is doorgegeven aan het beheersform. Als ik dan op cancel druk, dan is het object uiteraard niet meer in zijn oorspronkelijke staat omdat het kortgeleden ervoor is geset om validatie te kunnen uitvoeren.
  • Ik kan een clone maken waar de waardes op geset gaan worden. Tevens zal ik dan de validatie op de clone uitvoeren. Ik kan een ICloneable interface implementeren alleen moet ik dan handmatig aangeven wat ik wel en niet wil clonen. Ook ga je in de toekomst problemen krijgen als je een class uitbreidt en je vergeet de clone uit te breiden. Geen mooie oplossing naar mijn idee.
  • Ik kan gebruik maken van reflectie bij het clonen maar naar mijn idee maakt dit alles ook niet veel duidelijker en het wordt gevoeliger voor fouten en performance issues. Ook niet echt een oplossing dus.
  • Ik kan het gecancelde object opnieuw ophalen uit de database maar bij complexere objecten en relaties krijg je hier misschien problemen mee (parent / child relaties waarvan de referentie dezelfde hoort te zijn maar bij een refresh niet meer gelijk is omdat de ene referentie een gerefreshed object bevat terwijl de andere nog de orginele is). Geen idee of dit ook daadwerkelijk een probleem kan gaan worden.
  • Ik valideer alleen de input zonder het object daadwerkelijk te setten. Het nadeel hiervan is dat ik mijn logica niet kan hergebruiken wat onderhoudbaarheid niet ten goede komt.
Ik zit er sterk aan te denken om gewoon het object te refreshen. Zijn er toevallig richtlijnen hoe je hier het beste mee om kan gaan?

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

Ik kan een clone maken waar de waardes op geset gaan worden. Tevens zal ik dan de validatie op de clone uitvoeren. Ik kan een ICloneable interface implementeren alleen moet ik dan handmatig aangeven wat ik wel en niet wil clonen. Ook ga je in de toekomst problemen krijgen als je een class uitbreidt en je vergeet de clone uit te breiden. Geen mooie oplossing naar mijn idee.
Dat is wel vervelend als je die classes iedere dag moet aanpassen ja ;)
Ik kan gebruik maken van reflectie bij het clonen maar naar mijn idee maakt dit alles ook niet veel duidelijker en het wordt gevoeliger voor fouten en performance issues. Ook niet echt een oplossing dus.
Je kan natuurlijk een eigen attribuut maken op de properties en velden van het object.
C#:
1
2
3
4
5
6
7
8
9
10
public class CloneableAttribute : Attribute {}

class Person : ICloneable {
      [Cloneable]
      public string Naam {get;set;}

      public ... Clone ( ... ) {
           // reflecteren op jezelf, juiste properties danwel velden kopieren
      }
}
Qua performance hoeft het niet een super groot probleem te zijn. Tenzij je van plan bent 1000x per seconde te clonen, moet het vrij soepel gaan. En zo ver ik weer worden de resultaten van de reflectie gecached, dus de eerste keer is traag maar de rest zou sneller moeten gaan.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]