Skip to content
Sergey Starodubtsev edited this page May 8, 2017 · 3 revisions

Welcome to the scala-samples wiki!

There are the list Ideas or notes or more often takeouts about scala and not only - I would say more about Software Development in general. All will start with "I found that..."

DDD

I found that Domain Driver Design (DDD) concepts are quite useful, when it comes to domain modeling (surprise!).

Useful - to separate domain logic from the rest. To be simple (not talking about Aggregates or whatsoever for now): The separation part is crucial.

Algebra and Laws of Algebra

I found that thinking in terms of Algebra of API and Laws of Algebra fits better to Domain modeling comparing to the traditional terms like Code and Test of/for the domain logic. When we say Laws that quite clear that those law should be obeyed then it is quite clear that you may not miss the to write it (in the form of unit test), and then it is quite clear that the law is also the code.

Example, Algebra of API for the domain of ThingAdder (all about parameters and types):

trait ThingAdder[Thing] {
      def add(thing1: Thing, thing2: Thing): Int
      def takeAway(thing1: Thing, thing2: Thing): Int
}

The interesting part here is that we use generics, the Thing does not exist yet. And it is quite powerful when you think about it from the very beginning, abstracting over - that I guess should be the first part one should do when she start modeling - describing the model. ( For me it is strange that GoLang doesn't have generics. I understand that it could be slow on compilation or run-time or to mentally grasp what's going on with code. But human are quite complex too, but they still in use )

Example of Laws of Algebra (using ScalaTest integrated with ScalaCheck):

 import ThingAdder._ // the impl of of `ThingAdder` trait
 forAll {things: (thing1: Thing, thing2: Thing) =>
  add(thing1, thing2) should equal (thing2, thing1)
 }

 forAll{ (thing1: Thing, thing2: Thing) => {
  for {
    twoThings <- add(thing1, thing2)
    result <- takeAway(thing1, twoThings)
  } yield (result)
    thing2 should equal result
  })

The interesting part for me was that there is code - algebra of the domain - the interface (as one may call it) and the law - the test without any implementation just yet!

I think that using property based testing (with forAll and such) should come first as one describes the laws of the domain. The last (second) that should come to mind is to write manual unit test. By far forAll with generators.

Basically it's primary school math in action n+m = m+n; n+m-n = m. Where n, m is whatever. Where whatever depends on generators. For known types Int, String, Date - scalatest comes with predefined generators. So we can save time - concentration on the model testing. Quite nice I think.

Here we go

Clone this wiki locally