-
Notifications
You must be signed in to change notification settings - Fork 0
SimpleEntity
Before starting to play with the basics of Morpheus, we have to install the Morpheus Scala compiler plugin. The instructions can be found here. This plugin generates so called fragment classes for all fragments found in the project.
We can run this tutorial in REPL or as standalone programs that can be found in the tutorial repository.
This tutorial is conceived as a step-by-step development of an imaginary chat application, in which each step reveals a new Morpheus feature.
Before delving into this tutorial, however, I definitely recommend going through the README file, which gives a brief overview of the basic Morpheus concepts.
In this and all following lessons we assume that the following import statements are used.
import org.morpheus._
import Morpheus._
Let's begin with the designing of the Contact
entity, which represents the central object of the chat application.
Since we plan to use Contact
as a fragment in morphs, we have to decorate it by the fragment
annotation.
@fragment
trait Contact {
var firstName: String = _
var lastName: String = _
var male: Boolean = _
var nationality: Locale = _
}
Upon the compilation the Morpheus compiler plugin intercepts this trait and generates its fragment class, which can be then instantiated by the runtime part of Morpheus.
Now we can use the singleton
macro to instantiate the Contact
entity. The morph type consists of Contact
type only. It actually describes the simplest morph model with just one fragment and one alternative.
The singleton
macro creates the so called morph kernel, which can be used for assembling various alternatives described by the morph model. There is just one alternative in this case, so we can immediately call use either !
or ~
operators to obtain the reference to the Contact
morph.
val contact = singleton[Contact].!
val contact = singleton[Contact].~
The !
operator produces something what is so called immutable morph, while ~
returns a mutable morph.
The difference between is not obvious now, since there is only one alternative. When re-morphed, the immutable morph produces a new instance of the newly chosen alternative, while its internal state is not affected in any way. On the other, the mutable morph maintains a mutable reference to an immutable morph. Upon re-morphing this reference is set to the new instance of the immutable morph.
Whether we created one morph or another, both can be used as a plain Contact
instance.
contact.firstName = "Pepa"
contact.lastName = "Novák"
contact.male = true
contact.nationality = Locale.CANADA
println(s"${contact.firstName} ${contact.lastName} ${contact.nationality} ${contact.male}")
Note: We used the mutable version of the Contact entity just because of its sheer simplicity and since the immutable version would require more Morpheus stuff to be explained. We will switch to the immutable entity later on.
In the following lesson we will add some behavior to entity Contact
.
####Morpheus Tutorial####
- Modelling simple entity
- Adding some behavior
- Abstracting fragment
- Reusing fragment
- Using fragment in Java
- Multidimensional morphs
- Morphing strategies
- Mutable morphs
- Delegating and sharing
- Dimension wrappers
- Fragment wrappers
- Using a morph as a fragment
- Kernel references
- Kernel references use cases
- Promoting, masking and rating