8000 GitHub - lukasito/actor-model-ddd
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

lukasito/actor-model-ddd

Repository files navigation

#Domain driven design in actor model using akka This project tries to demonstrates how to design domain using actor model paradigm.
I was drawing knowledge from great book with title Applied Akka Patterns By Michael Nash and Wade Waldron.

#Domain Entities Entity is something that is uniquely identifiable by key.
Can be mutable, which means its state can change, but its key remains unaffected.
Akka actor is entity. It's identified by its path or by its ID as key and its state can change e.g

  class User(id: UUID) extends Actor {
    override def receive: Receive = ...
  }

#Value Objects Value objects are not identified.
Are immutable - if their properties change, they become different value objects and are no longer equal.
In Akka messages send between actors are natural value objects e.g.

  object UserProtocol {
    case class SetName(name: String)
  }

#Aggregates and Aggregate Roots Aggregates are sort of logical grouping of many different elements of system.
They are bound to aggregate root.
Aggregate root is special entity that has responsibility for other members of that aggregate.
In Akka aggregate roots are represented by parent actor, so when you delete this root, all children go with him.
Example of aggregate root:

  object Player {
    def props = Props(new Player)
  }
  
  class Player extends Actor { ... }
  
  class Game(id: UUID) extends Actor {
    private val player = createPlayer()
    
    private def createPlayer() = context.actorOf(Player.props)
  }

#Repositories Standard DDD theorems will tell you, that basic approach when working with aggregates, is to go to repository, retrieve aggregate from repository, do some stuff and commit changes with repository again It seems like Ask pattern in Akka BUT Ask pattern violates principle of "Tell, Don't Ask" that fits actor model best. In Akka repositories might have different appearance. Instead of asking the repository for aggregate, you instruct repository to send a message to that aggregate, so now repository will act a "manager". You inform repository, that you want specific actor to process your message. The responsibility of repository is to locate that actor (or create it) and pass the message on.
Since you want your implementation be part of infrastructure instead of domain, repositories in domain define only message protocol like so:

  object UserRepository {
    case class Send(userId: UUID, message: Any)
  }

Then your implementation in infrastructure might look like this:

  class JdbcSQLUserRepository extends Actor {
    override def receive: Receive = {
      case Send(id, message) => ...
    }
  }

#Factories In Akka factories are very similar to repositories. Instead of Ask pattern, its better to use tell pattern where factory will create given actor and pass message to newly created instance.
Because of its similarity to a repository, it doesn't make much sense to distinguish between them.

#Domain event publisher Responsible for publishing domain events like person updated, or created etc. Its implemented as event bus.

#TODO

  • Commands and Events
  • Domain event publisher
  • Domain Services
  • Implement example of Domain Service

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

0