In Fowler's PoEAA wordt voorgesteld om tussen de domain layer en de data-access layer (in mijn geval DataMappers die met behulp van een Mapper Registry worden ingezet door een transactionele Unit of Work) een soort van globale Dictionary te plaatsen, waar domein-objecten -met als key hun GUID- kunnen worden gecached. Zo'n globale cache heeft uiteraard als voordeel dat veel datastore roundtrips overbodig worden enkelvoudige entity fetches vlotter worden. Niet geheel triviaal overigens: het betreft hier een web-omgeving (ASP.NET).
Nu overerven mijn domein objecten van een layer supertype ("DomainObject"), welke onder andere een simpel State-mechanisme voor domeinobjecten implementeert. Bijv: bij aanpassing van een property wordt een 'clean' object als 'dirty' gemarkeerd en registreert het zich bij de toegewezen Unit of Work.
Gegeven de volgende situatie:
Andere clients die voordat bovenstaande plaatsvond ook al een referentie hadden naar het desbetreffende User object hebben nu een 'dirty' object met allemaal mogelijke vervelende gevolgen vandien.
Hoe kan je deze situatie het beste tackelen?
Enkele (mogelijke?) oplossingen waar ik al aan dacht:
Nu overerven mijn domein objecten van een layer supertype ("DomainObject"), welke onder andere een simpel State-mechanisme voor domeinobjecten implementeert. Bijv: bij aanpassing van een property wordt een 'clean' object als 'dirty' gemarkeerd en registreert het zich bij de toegewezen Unit of Work.
Gegeven de volgende situatie:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // Object is al aanwezig in de globale cache en een state-check // in de cache wijst uit dat die op dat moment 'clean' is; dit leidt // ertoe dat het teruggegeven object een referentie bevat naar het // object in de cache. Het is natuurlijk mogelijk dat andere clients // op dat moment ook al een referentie hebben naar dit object. IUser user = UserRepository.FindById(user_Id); IUnitOfWork localUnitOfWork = UnitOfWorkFactory.Create(); user.FirstName = "Foo"; user.LastName = "Bar"; // om de een of andere reden ontstaat hier een exception (of // bijvoorbeeld tijdens onderstaande commit) localUnitOfWork.Commit(); |
Andere clients die voordat bovenstaande plaatsvond ook al een referentie hadden naar het desbetreffende User object hebben nu een 'dirty' object met allemaal mogelijke vervelende gevolgen vandien.
Hoe kan je deze situatie het beste tackelen?
Enkele (mogelijke?) oplossingen waar ik al aan dacht:
- Een soort van Undo-functionaliteit op het domein-object aanroepen, zodat deze wordt teruggezet in de 'clean' state door de unit of work als er een fout optreedt?
- Uniquing laten schieten en in plaats daarvan klonen van de domein objecten in de cache teruggeven? (bijv. mbv. ICloneable op domein objecten)
- Domein objecten locken terwijl die worden bijgewerkt?
- DTO's cachen ipv de domein objecten zelf?
[ Voor 47% gewijzigd door Verwijderd op 11-05-2006 15:53 ]