Top Banner
Scala Domain Modeling and Architecture Experience Report Hossam Karim
44

Scala Domain Modeling and Architecture

Nov 29, 2014

Download

Technology

Hossam Karim

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Scala Domain Modeling and Architecture

Scala  Domain  Modeling  and  Architecture  Experience  Report  

Hossam  Karim  

Page 2: Scala Domain Modeling and Architecture
Page 3: Scala Domain Modeling and Architecture
Page 4: Scala Domain Modeling and Architecture
Page 5: Scala Domain Modeling and Architecture
Page 6: Scala Domain Modeling and Architecture
Page 7: Scala Domain Modeling and Architecture

for {! ! locus ← Chromosome ⤞ Gene ⤞ Locus! if Locus ∈ range! ! path ← locus ⤞ Sequence ⤞ nucleotide! if nucleotide alignment (_ > 89)! ! } yield path!

Page 8: Scala Domain Modeling and Architecture
Page 9: Scala Domain Modeling and Architecture
Page 10: Scala Domain Modeling and Architecture
Page 11: Scala Domain Modeling and Architecture

inputMessage >>= fasta >>= {     case n: Nucleotide ⇒ ! ("media" → "nucleotide") ~> n.giNumber   case _: AminoAcid ⇒ ! fail[String](! "Expected a ‘nucleotide’ Sequence")   case _ ⇒ ! fail[String](! "Expected a ‘single’ Sequence representation”)     } >>= {     for {   query ← meta.Sequence ⤞ meta.nucleotide   if meta.nucleotide.giNumber === _   } yield query     } >>= xml  !

Page 12: Scala Domain Modeling and Architecture

inputMessage >>= fasta >>= {     case n: Nucleotide ⇒ ! ("media" → "nucleotide") ~> n.giNumber   case _: AminoAcid ⇒ ! fail[String](! "Expected a ‘nucleotide’ Sequence")   case _ ⇒ ! fail[String](! "Expected a ‘single’ Sequence representation”)     } >>= {     for {   query ← meta.Sequence ⤞ meta.nucleotide   if meta.nucleotide.giNumber === _   } yield query     } >>= xml  !

Page 13: Scala Domain Modeling and Architecture

inputMessage >>= fasta >>= {     case n: Nucleotide ⇒ ! ("media" → "nucleotide") ~> n.giNumber   case _: AminoAcid ⇒ ! fail[String](! "Expected a ‘nucleotide’ Sequence")   case _ ⇒ ! fail[String](! "Expected a ‘single’ Sequence representation”)     } >>= {     for {   query ← meta.Sequence ⤞ meta.nucleotide   if meta.nucleotide.giNumber === _   } yield query     } >>= xml  !

Page 14: Scala Domain Modeling and Architecture

inputMessage >>= fasta >>= {     case n: Nucleotide ⇒ ! ("media" → "nucleotide") ~> n.giNumber   case _: AminoAcid ⇒ ! fail[String](! "Expected a ‘nucleotide’ Sequence")   case _ ⇒ ! fail[String](! "Expected a ‘single’ Sequence representation”)     } >>= {     for {   query ← meta.Sequence ⤞ meta.nucleotide   if meta.nucleotide.giNumber === _   } yield query     } >>= xml  !

Page 15: Scala Domain Modeling and Architecture

inputMessage >>= fasta >>= {     case n: Nucleotide ⇒ ! ("media" → "nucleotide") ~> n.giNumber   case _: AminoAcid ⇒ ! fail[String](! "Expected a ‘nucleotide’ Sequence")   case _ ⇒ ! fail[String](! "Expected a ‘single’ Sequence representation”)     } >>= {     for {   query ← meta.Sequence ⤞ meta.nucleotide   if meta.nucleotide.giNumber === _   } yield query     } >>= xml  !

Page 16: Scala Domain Modeling and Architecture

trait Message[A, H] {   val body: Validation[H, Option[A]]   val headers: H   }        trait MessageBuilder {   def build[A, H: Monoid](   body: Validation[H, Option[A]],   headers: H): Message[A, H]   }  

Page 17: Scala Domain Modeling and Architecture

trait Message[A, H] {   val body: Validation[H, Option[A]]   val headers: H   }        trait MessageBuilder {   def build[A, H: Monoid](   body: Validation[H, Option[A]],   headers: H): Message[A, H]   }  

Page 18: Scala Domain Modeling and Architecture

implicit def m2m[H]! (implicit builder: MessageBuilder, ! monoid: Monoid[H]) =!  new Monad[({type λ[α] = Message[α, H]})#λ] {     def pure[A](a: => A): Message[A, H] = . . .!   def bind[A, B]! (a: Message[A, H], ! f: (A) => Message[B, H]): Message[B, H] = . . .  }  

Page 19: Scala Domain Modeling and Architecture

def pure[A](a: => A) = ! builder.build[A, H](Success(Option(a)), ∅[H])    

Page 20: Scala Domain Modeling and Architecture

def bind[A, B](! m: Message[A, H], ! f: (A) => Message[B, H]): Message[B, H] = {!   val mb: Message[B, H] = m.body match {   case Success(Some(value)) ⇒ f(value)   case Success(None) ⇒! builder.build[B, H](! Success(Option.empty[B]), ∅[H])   case Failure(a) ⇒! builder.build[B, H](! Failure(a), ∅[H] |+| a)   }!   builder.build[B, H](mb.body, m.headers |+| mb.headers)  }  

Page 21: Scala Domain Modeling and Architecture

implicit object BasicMessageBuilder extends MessageBuilder {   def build[A, H: Monoid](! body: Validation[H, Option[A]], headers: H) =   BasicMessage(body, headers)  }  !implicit object DiagnosisMessageBuilder extends! MessageBuilder {   def build[A, H: Monoid](! body: Validation[H, Option[A]], headers: H) =   DiagnosisMessage(body, headers)  }     def body[A](value: A)(implicit builder: MessageBuilder) :! Message[A, HL] =   builder.build(Success(Some(value)), List.empty[Header])      

Page 22: Scala Domain Modeling and Architecture

import Basic._!//import Diagnosis._!//import Transactional._!!gene map {   for (! e ← meta.Chromosome ⤞ meta.Gene ! if meta.Gene.uuid === _.uuid! ) yield e  } >>= search  

Page 23: Scala Domain Modeling and Architecture

(genex <**> geney) (_ ++ _) >>=   header("media-type", "application/vnd.x.gene+json") >>=   json        for {   m ← body(<gene xmlns="urn:model:gene:1.0">...</gene>)   gene ← xml(m)   } yield gene        gene map {   for {   e ← meta.Gene ⤞ meta.Gene.uuid   if meta.Gene.uuid === _.uuid   } yield e  } >>= search    

Page 24: Scala Domain Modeling and Architecture

import scalaz._!import Scalaz._!// profit!!

Page 25: Scala Domain Modeling and Architecture
Page 26: Scala Domain Modeling and Architecture
Page 27: Scala Domain Modeling and Architecture
Page 28: Scala Domain Modeling and Architecture

trait Resource {! val name: String!} !   trait Ontology extends Resource {! val nestingOntology: Option[Ontology]! val nestedOntology: List[Ontology]! val ownedType: List[Type]! val ownedRelation: List[Relation]!}!  

Page 29: Scala Domain Modeling and Architecture

trait GraphResource {   this: Resource =>   }     trait GraphVertex extends GraphResource {   this: Entity =>   val graphFeatures: List[PrimitiveFeature]   val master: Boolean   val rootToMasterEdge: GraphEdge with Relation   val masterToSelf: Option[GraphEdge with Relation] = None   }     trait GraphEdge extends GraphResource {   this: Relation =>   }    

Page 30: Scala Domain Modeling and Architecture

trait RelationalResource {   this: Resource =>   }     trait NamedRelationalResource extends RelationalResource {   this: Resource =>   val relationalName: String   }       trait RelationalEntity extends NamedRelationalResource {   this: Entity =>   }     trait RelationalCompositeFeature extends RelationalResource {   this: CompositeFeature =>   val mapping: Map[String, String]   }  

Page 31: Scala Domain Modeling and Architecture

object Chromosome extends   Entity   with RelationalEntity!    with GraphVertex   with XmlElement {   self =>     sealed trait ChromosomePart {   val ownerType = self   }     // Ontology Trait   val featuringType = self   val ownedFeature = chromatine :: Nil     // XML Trait   val namespace = "urn:domain:chromosome:1.0"   val prefix = "chr"     // Features   val chromatine =   new Chromatine(   name = "chromatine",   ownerType = Chromosome,   mapping = Map.empty[String, String])   }    

Page 32: Scala Domain Modeling and Architecture

implicit def enrich[A <: DomainModel](model: A) = new {   def metamodel: Option[Type] = Ontology.typeOf(model)  }    def xmlFilter[A <: DomainModel] =   (model: A) ⇒ model.metamodel match {   case Some(_: XmlElement) ⇒ body(XmlModel[A](model))   case _ ⇒ fail[XmlModel[A]]! ("No XmlElement meta-model definition could be found")  }    def ingoingEdges[A <: DomainModel] =   (model: A) ⇒ model.metamodel match {   case Some(vertex: GraphVertex) ⇒ ! Ontology.edges.filter(_.target == vertex)   case _ ⇒ List.empty[GraphEdge]  }  

Page 33: Scala Domain Modeling and Architecture

implicit def enrich[A <: DomainModel](model: A) = new {   def metamodel: Option[Type] = Ontology.typeOf(model)  }    def xmlFilter[A <: DomainModel] =   (model: A) ⇒ model.metamodel match {   case Some(_: XmlElement) ⇒ body(XmlModel[A](model))   case _ ⇒ fail[XmlModel[A]]! ("No XmlElement meta-model definition could be found")  }    def ingoingEdges[A <: DomainModel] =   (model: A) ⇒ model.metamodel match {   case Some(vertex: GraphVertex) ⇒ ! Ontology.edges.filter(_.target == vertex)   case _ ⇒ List.empty[GraphEdge]  }  

Page 34: Scala Domain Modeling and Architecture

trait Type extends Resource   trait SimpleType extends Type   trait Entity extends Type!! trait Relation extends Type     trait Feature[+T <: Type] extends Resource   trait SimpleFeature[+T <: SimpleType] extends Feature[T]   trait PrimitiveFeature extends SimpleFeature[Primitive]   trait EnumerationFeature extends SimpleFeature[Enumeration]   trait CompositeFeature extends SimpleFeature[Composite]     trait Primitive extends SimpleType   trait Enumeration extends SimpleType   trait Composite extends SimpleType      

Page 35: Scala Domain Modeling and Architecture

trait PrimitiveLogic {     val resource: Primitive         def ===[A](value: Primitive[A]): Operator = . . .              def in[A](values: PrimitiveList[A]): Operator = . . .  }        def find(operator: Operator): Option[T]  def list(operator: Operator): List[T]!

    import PrimitiveLogic._    dao list (Locus.locusUUID in list)     dao find (Locus.locusUUID === uuid)    

Page 36: Scala Domain Modeling and Architecture

import Logic._   val validation =   Sequence.nucleotide.accession.accessionNumber !== x     import GraphOps._   val path =   Sequence.nucleotide ⤞   Sequence.protein ⤞   Locus.typeOfGene where (_ !== y)    

Page 37: Scala Domain Modeling and Architecture

for {! ! locus ← Chromosome ⤞ Gene ⤞ Locus! if Locus ∈ range! ! path ← locus ⤞ Sequence ⤞ nucleotide! if nucleotide alignment (_ > 89)! ! } yield path!

Page 38: Scala Domain Modeling and Architecture
Page 39: Scala Domain Modeling and Architecture

trait Qvt[PIM, Query, View, PSM] {     def query(pim: PIM): List[Query]     def view(query: Query): View     def transform(view: View): PSM     }  

Page 40: Scala Domain Modeling and Architecture

class GraphSimpleQvt(   ontologyProfile: OntologyProfile,   graphProfile: GraphProfile)   extends SimpleQvt[Model, Package, GraphOntology] {     def query(pim: Model) = {   walk[Package](pim)(_.getNestedPackages).   filter(graphProfile.graphPredicate)   }     def transform(view: Package) = graph(view)     def graph(element: Package): GraphOntology = {   ...   }   .   .   .  }  

Page 41: Scala Domain Modeling and Architecture

def walk[A]   (element: A)   (f: A => Iterable[A]): List[A] = {   val children = f(element).toList   children ++ ! (children.flatMap(walk(_, f)))  }  

Page 42: Scala Domain Modeling and Architecture

def packageName(element: Package): String =   Stream! .iterate(element)(_.getNestingPackage)   .takeWhile(!_.isInstanceOf[Model])   .map(_.getName)   .reverse   .mkString(".") //.scala rocks !!  

Page 43: Scala Domain Modeling and Architecture
Page 44: Scala Domain Modeling and Architecture

Thank  You