Skip to content

Latest commit

 

History

History
119 lines (84 loc) · 2.69 KB

modeling.md

File metadata and controls

119 lines (84 loc) · 2.69 KB

Overview

  1. How to make go enforce your invariants
  2. See abstraction doc
  3. For comparison, see the rust version of this doc

Key Concepts

  1. Goal: Make illegal states in the domain model unrepresentable (compiler enforced)

  2. Languages with strong modeling tools represent invariants with types

    1. Compiler is responsible for enforcing invariants
  3. Languages with weak modeling tools represent invariants with methods/logic

    1. Runtime is responsible for enforcing invariants
  4. Go has relatively weak modeling tools

    1. (but still stronger than c, javascript, python, all dynamic languages, ...)
    2. Compare to rust
    3. Compare to kotlin

Patterns

Absence

  1. Use nilable type
  2. sql package also provides nilable types
var favoriteBook *Book = nil

At-most-one (aka "Maybe")

  1. Use nilable type
type Employee struct {
    FavoriteBook *Book // at most one
}

Zero-or-more

  1. Use a slice
type Employee struct {
    PreviousEmployers []Employer // zero or more
}

Exactly-one

  1. TODO
TODO

Exactly-one of bounded set (Sum Algebraic data type)

  1. TODO
TODO

At-least-one

  1. TODO
TODO

Non-negative value

  1. Use uint8, uint16, uint32 or uint64
var age uint8 = 30 // compiler enforced non-negative

Group of related fields (Product Algebraic data type)

  1. Use a struct

Semantic wrapper (user-defined primitive types)

  1. TODO
TODO
  1. Use a field on a struct
TODO
  1. Implement an interface
    1. REMINDER: almost any type can implement an interface (numbers, strings, structs, ...)

Visibility/Encapsulation

  1. Use Upper/lower case
  2. Separate code into different packages
    1. See abstraction doc

Mutability

  1. TODO
  1. TODO

TODO/Unorganized

  • TODO: embedding
  • TODO: pattern matching
  • TODO: preconditions (logic)

Other Resources

  1. https://markoengelman.com/ddd-anemic-vs-rich-domain-model/