[alg] hoe erg zijn side effects?

Pagina: 1
Acties:

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik ben bezig met het bouwen van een CMS waarbij ik echt serieus goede coding practices probeer te volgen en ik stuit nu eigenlijk voor het eerst op een echt side effect probleem. Het is niet zozeer dat de side effect zelf een probleem is, maar ik kan nu moeilijk inschatten hoe erg het is dat deze side effect aanwezig is. Ik zal even uitleggen hoe de situatie is.

Ik heb een class Page waarop operaties uitgevoerd kunnen worden welke soms effect hebben op het uiterlijk/indeling van de pagina. Nu ben ik ook bezig om caching in te bouwen en wil ik dat op het moment dat bepaalde acties worden uitgevoerd, dat de huidige cache, indien aanwezig, wordt verwijderd (wordt geinvalideerd) en dat de pagina wordt opgeslagen (met geen waarde als cache dan).

De bepaalde acties waar ik het over heb zijn bijvoorbeeld operaties voor het wisselen van de posities van 2 items of het toevoegen van een content item aan de pagina. Het probleem is nu dat ik niet goed weet wanneer ik de invalidatie van de cache moet uitvoeren. Ik heb de keuze om de invalidatie in de functie zelf te doen, of iedere keer nadat de functie is aangeroepen. Ik weet zeker dat deze actie iedere keer uitgevoerd moet worden als de functie wordt aangeroepen. Het invalideren hoort echter niet bij de operatie die de functie moet voorstellen en is daarom een side effect. Zoals ik heb gelezen zijn side effects slecht, je moet ze zien te voorkomen, maar in dit geval lijkt het me niet zo erg.

De twee opties die ik dus heb zijn:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Page
{
  function addItem(item)
  {
    // voeg het item toe
    this.invalidateCache();
  }

  function invalidateCache()
  {
    // invalideer de cache
  }
}

page = bestaande page instantie;

page.addItem(new Item());

of
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Page
{
  function addItem(item)
  {
    // voeg het item toe
  }

  function invalidateCache()
  {
    // invalideer de cache
  }
}

page = bestaande page instantie;

page.addItem(new Item());
page.invalidateCache();


Hoe staan jullie hier tegenover? Persoonlijk heb ik de voorkeur voor de 2de methode ook omdat het mogelijk is om meerdere operaties uit te voeren die allen de cache zouden invalideren. Echter zit je wel met dubbele code als je een bepaalde methode op meerdere plaatsen aanroept. Zijn jullie hier erg strict in of maken jullie wel eens een uitzondering?

Noushka's Magnificent Dream | Unity


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

Alarmnummer

-= Tja =-

Is het niet handiger om caching meer over te laten aan de or mapper? (als je deze gebruikt). Je applicatie kun je dan normaal opzetten, maar door caching heb je toch een betere performance. Met Hibernate kun je zelfs aangeven uit welke level cache je objecten opgehaald moeten worden. Het kan cachen zijn binnen een enkele transactie (standaard), maar je kunt ook objecten caching binnen de hele applicatie (proces)

[ Voor 3% gewijzigd door Alarmnummer op 15-05-2005 12:17 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Alarmnummer schreef op zondag 15 mei 2005 @ 12:14:
Is het niet handiger om caching meer over te laten aan de or mapper? (als je deze gebruikt). Je applicatie kun je dan normaal opzetten, maar door caching heb je toch een betere performance. Met Hibernate kun je zelfs aangeven uit welke level cache je objecten opgehaald moeten worden. Het kan cachen zijn binnen een enkele transactie (standaard), maar je kunt ook objecten caching binnen de hele applicatie (proces)
Het gaat in dit geval niet om het cachen van objecten die uit de database gehaalt en gemapt zijn. Het gaat in dit geval om het cachen van HTML output van de pagina. Het cachen objecten gebeurt nu gelukkig in de OR mapper. Maar dat is eigenlijk allemaal niet relevant voor het onderwerp van dit topic.

Noushka's Magnificent Dream | Unity


Verwijderd

Mijn voorkeur, zeker in een multi-user omgeving: methode 1.
Laat het object zelf bepalen of de boel gerefreshed moet worden, en wanneer je in je invalidateCache() ook een mechanisme opneemt om andere aangesloten clients te vertellen dat er gerefreshed moet worden, werkt dat heel prettig.

Wat betreft side effects: wanneer een metselaar een muurtje metselt, en hij begint aan een nieuwe laag, dan is een side effect dat het muurtje 10 centimeter hoger is geworden. Maar dat effect is integraal onderdeel van het object (muurtje) wanneer een method van dat object wordt aangeroepen (muurtje.beginNieuweLaag).
Je mag kiezen of je de side effect afhandeling laat doen door de metselaar of het muurtje zelf, maar ik zou gaan voor het muurtje. Dan voorkom je dat een andere metselaar vergeet om door te geven dat 'ie met een nieuwe laag is begonnen.

Verwijderd

Imo geef je de oplossing zelf al...

Als het invalidaten van de cache een integraal onderdeel is van het proces "Voeg item toe aan page object", waarom zou je het dan niet opnemen in de functie die dat item toevoegt? Volgens mij kun je niet echt spreken van een side-effect als het niet uitvoeren van de invalidate een invalid state betekent.

Als je dit puur vanuit refactoring standpunt bekijkt, dan zie je dat je bij het toevoegen van een item altijd 2 functioncalls doet: 1 voor het toevoegen van het item en 1 voor het invalidaten van de cache. Als je het invalidaten niet in de additem wilt doen, dan zou je kunnen overwegen om 1 functie te maken (bv. "AddItemFlush") die beide functioncalls afhandelt. Op deze wijze zijn beide functioncalls nog gewoon beschikbaar, mocht je ze toch onafhankelijk van elkaar nodig blijken te hebben. Voordeel is wel dat je op de plekken waar je de door jou beschreven functionaliteit nodig hebt maar 1 functioncall gebruikt, die ook nog eens duidelijk maakt wat je aan het doen bent...

Just my 2 cents

[ Voor 7% gewijzigd door Verwijderd op 16-05-2005 00:28 ]


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025

kvdveer

Z.O.Z.

Ik ben geneigd het eens te zijn met AfterLife.
Sideeffects zijn onvermijdelijk. Als je een item toevoegt aan een tabel of zo, wordt er misschien ergens geheugen gealloceerd of juist gedealloceerd, zonder dat dit in de functiebeschrijving duidelijk wordt. Er is ook niemand die het interresseert. Het is pas een probleem als de sideeffects andere functies gaan beinvloeden, of als het niet duidelijk is dat bepaalde side-effects plaats vinden.

Ik houd zelf ongeveer aan, dat een side-effect onwenselijk is als het meer doet dan het object belooft.
Bijvoorbeeld: De belofte van een database-klasse is meestal dat 'ie de verbinding met de database legt. Als je op de database een query uitvoert, dan vind ik het leggen van de verbinding meestal geen ongewenst side-effect. Ik vind het wel een ongewenst side-effect als de databaseklasse zelf queries gaat toevoegen zonder dat dit ergens genoemd wordt.

Als een object belooft dat hij zelf zijn eigen cache zal regelen, vind ik InvalidateCache geen ongewenst side-effect, al is het wel netjes dit in de documentatie te vermelden.
Als het object die taak echter niet heeft (en dus de cache ook niet zelf aanmaakt) dan vind ik dat het side-effect ongewenst is. Het hangt w.m.b. er dus vanaf of het object verantwoordelijk is voor de cache.

Localhost, sweet localhost


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025

kvdveer

Z.O.Z.

Nog een detail: Als het Invalidaten van de Cache veel kost (bijvoorbeeld alle dependencies doorzoeken oid), dan is het waarschijnlijk beter om het buiten de functie te laten, zodat het toevoegen van meerdere items niet extra veel kost...

Localhost, sweet localhost


  • windancer
  • Registratie: Maart 2000
  • Laatst online: 05-05 14:39
Volgens mij kun je de implicaties van de side-effects onmogelijk beoordelen zonder kennis van het domein waarin de applicatie gebruikt wordt. Stel je voor dat je een foute keuze maakt en je applicatie wordt onbruikbaar (worst case scenario). Ik ken applicaties waarin dit de klanten tien-duizenden dollars per uur kost en ik ken klanten waarin dit alleen de kosten van een work-around kost, zeg enkele seconden productiviteit.

Kortom, alles hangt af van de domein waarin je software gebruikt wordt.

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik heb er toch voor gekozen om de call wel binnen de functie te doen. Ook staat er nu een extra controle bij zodat de cache niet ge-invalidate wordt als hij dat al is. Ik merk al dat er nooit een voorgestelde correcte methode voor is en dat je dit per situatie moet inschatten. Bedankt voor de tips iig, nu ik er wat meer over nadenk en jullie reacties lees kan ik het al wat beter inschatten denk ik.

Noushka's Magnificent Dream | Unity

Pagina: 1