Download presentation
Presentation is loading. Please wait.
1
Architecture Patterns and Refactoring
Identity Map Layer Supertype Removing Replication
2
Architecture Patterns and Refactoring
Identity Map Layer Supertype Removing Replication XP: eXtreme Programming, Kent Beck et al DSDM: Dynamic System Development Method, DSDM Consortium, UK Crystal: Crystal Clear and other Crystal methods by Alistair Cockburn Evo: Evolutionary development, Tom Gilb FDD: Feature Driven Development, Jeff De Luca Lean: Lean Software Development, Mary and Tom Poppendieck 2
3
Identity Map Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them. An old proverb says that a man with two watches never knows what time it is. If two watches are confusing, you can get in an even bigger mess with loading objects from a database. If you aren't careful you can load the data from the same database record into two different objects. Then, when you update them both you'll have an interesting time writing the changes out to the database correctly. An Identity Map keeps a record of all objects that have been read from the database in a single business transaction. Whenever you want an object, you check the Identity Map first to see if you already have it.
4
Searching by Id Related to this is an obvious performance problem. If you load the same data more than once you're incurring an expensive cost in remote calls. Thus, not loading the same data twice doesn't just help correctness, but can also speed up your application.
5
Code Sample: GetOrNull(int id)
Search a record by its identity Return null if not found In LinqMapper layer Supertype for LinqRoomMapper, LinqPersonMapper, ... Optimization: Only perform a search if id not already in Identity Map
6
Mapper Structure Reminder
…
7
Searching Based on Other Criterias
Searching must always load first to find the id When searching on other criteria than id In LinqRoomMapper Two phases Search data records var roomRecords = RecordsForName(roomName); Load data records into domain objects return (Room)LoadUniqueOrNull(roomRecords);
8
Search Data Records Set up a Linq search In LinqRoomMapper
Returns a set of database record copies DataSource.Room is a data record Based on the database structure IQueryable is an interface for a list Allowing for queries to be performed on the list elements
9
Load Data Records into Domain Objects
LoadUniqueOrNull is a Template Method The actual work is done in DoLoad An abstract method, implemented in the subclasses Only they know how to load a class from the database structure Template Method Design Pattern is also called Hollywood Pattern
10
Do the Actual Loading of the Domain Object
The LinqRoomMapper does the actual mapping and loading The unique id for the records is now known roomRecord.RoomId The Identity Map is queried before a new domain object is created if (!InMap(roomRecord.RoomId)) If new, an object is created and inserted in the Identity Map
11
The Identity Map The map itself is a dictionary
In the topmost Mapper supertype Is manipulated by a small set of methods
12
Architecture Patterns and Refactoring
Identity Map Layer Supertype Removing Replication XP: eXtreme Programming, Kent Beck et al DSDM: Dynamic System Development Method, DSDM Consortium, UK Crystal: Crystal Clear and other Crystal methods by Alistair Cockburn Evo: Evolutionary development, Tom Gilb FDD: Feature Driven Development, Jeff De Luca Lean: Lean Software Development, Mary and Tom Poppendieck 12
13
Mapper Layer Supertypes
…
14
Layer Supertype A type that acts as the supertype for all types in its layer. It's not uncommon for all the objects in a layer to have methods you don't want to have duplicated throughout the system. You can move all of this behavior into a common Layer Supertype. LinqMapper examples GetOrNull(id) GetAll(dataTable) DomainSupertype examples Constructor DomainSupertype(int id) int Id property with setter and getter Commonly Hollywood Template Methods Filled in by details implemented in concrete subclasses
15
Layer Supertypes are Not primarily LSP Classes
Inheritance from a Layer Supertype is for convenience only To enhance changeability, reduce redundancy, and support DRY Not for subtype modelling or for polymorphism (except for some Hollywoods) You normally don’t declare a variable of the Layer Supertype You declare the concrete layer classes You are mostly interested in the specific methods in the concrete classes Often for a different aspect of the class Domain supertype: For database identity Mapper supertype: For common search and load logic, for identity mapping DRY: Don’t Repeat Yourself
16
Supertype Methods Declare Variables of Supertypes
Downcasted to a concrete class before they reach the client Applies covariance, as opposed to LSP and polymorphism LinqMapper refers to DomainSupertype LinqRoomMapper refers to Room Typed through generic type parameters
17
Layer Supertypes may cover a Different Aspect
Domain supertype Database unique key LinqMapper supertype Some search and load logic Common for all Linq mappers Dummy mappers may have different needs Mapper super supertype Identity mapping Needed for all kinds of mapping
18
Architecture Patterns and Refactoring
Identity Map Layer Supertype Removing Replication XP: eXtreme Programming, Kent Beck et al DSDM: Dynamic System Development Method, DSDM Consortium, UK Crystal: Crystal Clear and other Crystal methods by Alistair Cockburn Evo: Evolutionary development, Tom Gilb FDD: Feature Driven Development, Jeff De Luca Lean: Lean Software Development, Mary and Tom Poppendieck 18
19
Similar Code occurs with Similar Logic
Once is nothing, and twice is once too often Database searches need Set up a search Perform the search Check the identity map Load domain objects from database search result Some parts are common, some are not Factor out the common parts Frequently moved to a layer supertype Calling the specific parts through Hollywood Pattern
20
Code Sample: public Room GetOrNull(int roomId)
In LinqRoomMapper Identical code for Person, Booking, etc Except for the data types This code does not check the Identity Map until after the DB operation Needs to be added in all the copies There is a need for refactoring
21
Amendment: Add Identity Map Check
Add if (!InMap(id)) To be repeated for all mappers
22
Observations Method name
Get, but may return null from LoadUniqueOrNull Change to GetOrNull Checking the Identity Map before loading is an optimization Does not affect the correctness of the code Identity Map is checked later, in LoadUniqueOrNull Only affects speed, by potentially avoiding some database round-trips Only actual measurements can testify if that is significant The code gets more complex, opposes KISS Three Laws of Optimization: Don’t do it, don’t do it, don’t do it unless proven Refactoring pushes the method up in the Layer Supertype Untyping the intermediate results
23
Untyping of Intermediate Results
Retyping is upcasting Room is upcast to DomainSupertype Search result IQueryable<DataSource.Room> from RecordFromId upcast to object Must be downcasted before return Using generic types in the supertype result = (DomainType)LoadUniqueOrNull(domainRecords); In LinqMapper.GetOrNull(id) Using direct type casting in the concrete subclasses return (Room)LoadUniqueOrNull(roomRecords); In LinqRoomMapper.GetByName(roomName)
24
Refactoring Result Generic return type Returns DomainSupertype
Introduce generic types Returns object Downcast Downcast Returns DomainSupertype Downcast
25
Refactoring Conclusion
Includes renaming Needs tool support May increase complexity Pushing functionality up through inheritance layers Introducing generic methods or up-casting of data Doesn’t pay of until later But then it does, if well done Alternative is stepping towards chaos So well worth its price
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.