define Relationships? API Easy example Advanced example Object-Relational Programming Simon Olofsson [email protected] | @solofs http://simono.github.com/scala-orp/ 14 December 2012
define Relationships? API Easy example Advanced example What is ORP? Object-Relational Programming = OOP + Relationships Objects are useless without Relationships between them There are no high-level abstractions to define Relationships Instance variables and direct References are used
define Relationships? API Easy example Advanced example Defining a Relationship - manually class Customer { val c o n t r a c t s = L i s t B u f f e r [ Contract ] ( ) } class Contract ( var domain : Domain ) class Domain ( val name : S t r i n g )
define Relationships? API Easy example Advanced example The Representation of Relationships depends on the Multiplicity class Contract { val domains = L i s t B u f f e r [ Domain ] ( ) }
define Relationships? API Easy example Advanced example class Contract { val domains = L i s t B u f f e r [ Domain ] ( ) def addDomain (d : Domain ) { d . contract . domains −= d domains + = d d . contract = t h i s } } class Domain ( val name : String , var contract : Contract ) { def setContract ( c : Contract ) { contract . domains −= t h i s c ontract = c c ontract . domains + = t h i s } }
define Relationships? API Easy example Advanced example Two Problems with Relationships 1 The Representation of Relationships depends on the Multiplicity 2 Bidirectional Relations are hard to maintain A simple solution 1 Always use Collection semantics 2 Generate the Code to maintain bidirectional Relations
define Relationships? API Easy example Advanced example How do we define Relationships? We don’t define them inline (i. e. in a Class) We define them separately What do we need? A Relationship Two Roles, that belong to a Relationship Classes that can "play" these Roles
define Relationships? API Easy example Advanced example The API Annotation Meaning @relationship Define a Relationship @role Define a Role @plays(role[<Rolename>]) Play a Role @playsFor(role[<Rolename>], Play a Role for another Class classOf[<Classname>])
define Relationships? API Easy example Advanced example Defining a Relationship - with ORP @r e l a t i o n s h i p object CustomerContract { @r o l e (One) t r a i t Customer @r o l e t r a i t Contract } @r e l a t i o n s h i p object ContractDomain { @r o l e (One) t r a i t Contract @r o l e t r a i t Domain { val name : S t r i n g } }
define Relationships? API Easy example Advanced example @p l a y s ( r o l e [ CustomerContract . Customer ] ) class Customer @p l a y s ( r o l e [ CustomerContract . Contract ] , r o l e [ ContractDomain . Contract ] ) class Contract @p l a y s ( r o l e [ ContractDomain . Domain ] ) class Domain ( val name : S t r i n g )
define Relationships? API Easy example Advanced example @r e l a t i o n s h i p object PartWhole { @r o l e t r a i t Part { def belongsTo ( whole : Whole ) = partOf ( whole , t h i s ) } @r o l e (One) t r a i t Whole { def c o n t a i ns ( part : Part ) = partOf ( this , part ) } def partOf ( whole : Whole , part : Part ) = whole . getParts . c o n t a i n s ( part ) }
define Relationships? API Easy example Advanced example @p l a y s ( r o l e [ PartWhole . Part ] ) class Engine @p l a y s ( r o l e [ PartWhole . Whole ] ) class Car
define Relationships? API Easy example Advanced example @playsFor ( r o l e [ PartWhole . Part ] , c l a s s O f [ Car ] ) @playsFor ( r o l e [ PartWhole . Whole ] , c l a s s O f [ Valve ] ) class Engine @playsFor ( r o l e [ PartWhole . Whole ] , c l a s s O f [ Engine ] ) class Car @playsFor ( r o l e [ PartWhole . Part ] , c l a s s O f [ Engine ] ) class Valve ( val brand : S t r i n g )
define Relationships? API Easy example Advanced example val car = new Car () val engine = new Engine () val v a l v e = new Valve ( "Jimma" ) engine . addValve ( v a l v e ) engine . addPart ( v a l v e ) a s s e r t ( v a l v e . belongsTo ( engine )) a s s e r t ( engine . c o n t a i n s ( v a l v e )) car . addPart ( engine ) a s s e r t ( engine . belongsTo ( car )) a s s e r t ( car . c o n t a i n s ( engine )) // Won ’ t work // car . addPart ( v a l v e )