oopdnsdomain-driven-designooad

Simple domain objects attribute values


Let's say you've got a domain model class for a Song. Song's have a tempo attribute (an int) that should always be a positive number. Should this requirement be part of the domain model or externally (such as in a SongManager / business logic layer class)?

Let's say you've chosen to implement it like so:

class Song {
  private int tempo;
  // ...

  public void setTempo(int tempo) {
    if (tempo > 0) {
      this.tempo = tempo;
    } else {
      // what?
    }

  }

}

Would you replace // what? above with:

  1. Nothing. Given a Song instance s, s.setTempo(-10) would simply not modify the object's state.
  2. Set tempo to some minimum value, eg 1.
  3. Mark setTempo with a checked throws InvalidTempoException and throw it in the else clause. That way, a controller or other component is responsible for catching the invalid tempo value and making a decision about how to handle the exception.
  4. Throw a runtime InvalidTempoException.
  5. Extract the tempo attribute into a Tempo class with the "must be greater than 0" encapsulated there.
  6. Something else.

I ask because I've been exploring the common "layered architecture" approach lately and in particular the domain layer.


Solution

  • If a Song is not valid with a zero or negative tempo value, this certainly should be an invariant modelled within Song.

    You should throw an exception if an invalid value is attempted - this makes certain you don't have a Song in invalid state.