1 / 23

INHERITANCE

Explore the implementation of inheritance in enterprise applications and its relationship with relational databases. Learn about the different patterns of inheritance and their strengths and weaknesses. Discover how to use inheritance mappers to handle complex business logic and persistent data.

diamondj
Télécharger la présentation

INHERITANCE

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. INHERITANCE

  2. What this presentation ...won’t be about • Inheritance as one of the pillars of OOP • Implementation of inheritance

  3. What this presentation ...will be about • Inheritance as a part of “Enterprise application” • Inheritancein relationwith relational database • Martin Fowler: Patterns of Enterprise Application Architecture (2002/2003)

  4. Enterprise applications “Enterprise software, also known as enterprise application software (EAS), is computer software used to satisfy the needs of an organization rather than individual users.!” Wikipedia • Persistent data • A lot of data • Concurrent data access • Complex business (il)logic • Integration with other enterprise systems

  5. Player name Footballer Cricketer Bowler club bowlingaverage battingaverage

  6. Object Mapper create load save Table

  7. Object Mapper create load save Table Relational databases don’t support inheritance

  8. Object-Relational structural patterns • Single table inheritance • Class table inheritance • Concrete table inheritance • Inheritance mappers

  9. Single table inheritance <<table>> Players Player name club baiting average bowling average type name Footballer Cricketer Bowler club bowlingaverage battingaverage

  10. Single table inheritance • Strengths of STI: • Single table in database • No joins in retrieving data • Moving fields up/down the hierarchy does not require database changes • Weaknesses of STI: • Fields might not be relevant for everybody • Fields used only by some subclasses lead to wasted space • Single tables may end up being too large – may hurt performance • Single namespace for fields

  11. Concrete table inheritance <<table>> Footballers <<table>> Cricketers <<table>> Bowlers Player name baiting average name baiting average bowling average name club name Footballer Cricketer Bowler club bowlingaverage battingaverage

  12. Concrete table inheritance • Strengths of CTI: • No irrelevant fields • No joins when reading the data from concrete mappers • Each table is accessed only when concrete class is accessed • Weakness of CTI: • Primary keys can be difficult to handle • Moving fields up/down the hierarchy does require database changes • Superclass fields are duplicated across the tables – changes in superclass mean changes in each table • A find on superclass forces you to check all the tables

  13. Class table inheritance <<table>> Players <<table>> Bowlers <<table>> Cricketers <<table>> Footballers Player baiting average bowling average club name name Footballer Bowler Cricketer club bowlingaverage battingaverage

  14. Class table inheritance • Strengths of CTI: • All columns are relevant for every row – no wasted space • The relationship database x domain model is straightforward • Weaknesses of CTI: • Need of accessing multiple tables in order to load object – joins or multiple queries • Moving fields up/down the hierarchy does require database changes • The supertype tables may become bottleneck because they have to be accessed frequently

  15. Single table vs. Class table vs. Concrete table • Trade-off between performance, duplicate data, readability,… • Trio of patterns can coexist in a single hierarchy: • Concrete table inheritance + Single table inheritance • Class table inheritance + Concrete table inheritance • Possibly more…

  16. Generic inheritance mapper Abstract player mapper Footballer mapper Cricketer mapper Bowler mapper Mapper Player mapper + find(key) : Footballer # save # load + find(key) : Cricketer # save # load + find(key) : Bowler # save # load + find(key) : Player # insert # update + insert + update + delete # save # load # save # load

  17. // The gateway's data property is a data set that can be loaded by a query. classMapper { ... protectedDataTabletable { get {returnGateway.Data.Tables[TableName];} } protectedGatewayGateway; abstractprotectedStringTableName {get;} } // Since there is only one table, this can be defined by the abstract player mapper. classAbstractPlayerMapper : Mapper { ... protectedoverrideStringTableName { get {return"Players";} } }

  18. // Each class needs a type code to help the mapper code figure out what kind of player it's dealing with. The type code is defined on the superclass and implemented in the subclasses. classAbstractPlayerMapper : Mapper { ... abstractpublicStringTypeCode {get;} } classCricketerMapper : AbstractPlayerMapper { ... publicconstStringTYPE_CODE = "C"; publicoverrideStringTypeCode { get {returnTYPE_CODE;} } }

  19. // The player mapper has fields for each of the three concrete mapper classes. classPlayerMapper : Mapper { ... privateBowlerMapperbmapper; privateCricketerMappercmapper; privateFootballerMapperfmapper; publicPlayerMapper (Gatewaygateway) : base (gateway) { bmapper = newBowlerMapper(Gateway); cmapper = newCricketerMapper(Gateway); fmapper = newFootballerMapper(Gateway); } }

  20. // Loading an Object from the Database // Each concrete mapper class has a find method to get an object from the data. classCricketerMapper : AbstractPlayerMapper { ... publicCricketerFind(longid) { return (Cricketer) AbstractFind(id); } }

  21. // This calls generic behavior to find an object. classMapper { ... protectedDomainObjectAbstractFind(longid) { DataRowrow = FindRow(id); return (row == null) ? null : Find(row); } protectedDataRowFindRow(longid) { Stringfilter = String.Format("id = {0}", id); DataRow[] results = table.Select(filter); return (results.Length == 0) ? null : results[0]; } publicDomainObjectFind (DataRowrow) { DomainObjectresult = CreateDomainObject(); Load(result, row); returnresult; } abstractprotectedDomainObjectCreateDomainObject(); }

  22. // I load the data into the new object with a series of load methods, one on each class in the hierarchy. classCricketerMapper : AbstractPlayerMapper { ... protectedoverridevoidLoad(DomainObjectobj, DataRowrow) { base.Load(obj,row); Cricketercricketer = (Cricketer) obj; cricketer.battingAverage = (double)row["battingAverage"]; } }classAbstractPlayerMapper : Mapper { ... protectedoverridevoidLoad(DomainObjectobj, DataRowrow) { base.Load(obj, row); Playerplayer = (Player) obj; player.name = (String)row["name"]; } } classMapper { ... protectedvirtualvoidLoad(DomainObjectobj, DataRowrow) { obj.Id = (int) row ["id"]; } }

  23. // I can also load a player through the player mapper. It needs to read the data and use the type code to determine which concrete mapper to use. classPlayerMapper : Mapper { ... publicPlayerFind (longkey) { DataRowrow = FindRow(key); if (row == null) returnnull; else { Stringtypecode = (String) row["type"]; switch (typecode){ caseBowlerMapper.TYPE_CODE: return (Player) bmapper.Find(row); caseCricketerMapper.TYPE_CODE: return (Player) cmapper.Find(row); caseFootballerMapper.TYPE_CODE: return (Player) fmapper.Find(row); default: thrownewException("unknown type"); } } }

More Related