Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we have base types to avoid boilerplate code? #33

Open
hschwentner opened this issue Oct 21, 2020 · 3 comments
Open

Should we have base types to avoid boilerplate code? #33

hschwentner opened this issue Oct 21, 2020 · 3 comments
Labels
module: ddd Domain-Driven Design related support type: enhancement New feature or request

Comments

@hschwentner
Copy link
Member

hschwentner commented Oct 21, 2020

The DDDBITS provide two kinds of things:

  1. Architectural annotations -> These have been superseded by jMolecules now
  2. Base types with infrastructure to avoid boilerplate code
  • Should we move 2. also to jMolecules?
  • If yes: would that be a part of jmolecules-ddd or a new library to keep jmolecules-ddd as an “implementation free” lib?

From the DDDBITS documentation:

Entities

From the Blue Book we know that entities must have an identity.
Typically we want that equals() and hashcode() are based on this identity.
The base class Entity<ID> provides implementations for this.

Example:

import io.hschwentner.dddbits.annotation.*;
import io.hschwentner.dddbits.basetype.*;

@Entity
public class BankAccount extends Entity<IBAN> {

    public BankAccount(IBAN iban) {
        super(iban);
    }

}

Value Objects

Since we don't have value types in Java yet, we have to simulate values with objects.
(That may change with the advent of Project Valhalla.)
For the time being, this means unfortunately that we have to write a lot of boilerplate code for a well-implemented value object.
DDDBITS provide so called tiny types that help to reduce that boilerplate code for simple value types.

Example:

import io.hschwentner.dddbits.annotation.*;
import io.hschwentner.dddbits.basetype.*;

@ValueObject
public class IBAN extends TinyType<String> {

    private IBAN(String ibanString) {
        super(ibanString);
    }

    public IBAN of(String ibanString) {
        return new IBAN(ibanString);
    }

}

Value Objects are identityless and immutable.

Immutability in Java comes with only final fields plus methods that never mutate the state.
(That means we only have commands in the sense of command-query-separation[3].)

No identity in Java is reached by overwriting equals() with an implementation that is based on the values of the fields.
Such an implementation and similar implementations for hashcode() and toString() are provide by the TinyType<V> super class.


Something similar could be done with Lombok, but many projects do not want to couple their domain layer to a technical library.

@hschwentner hschwentner added type: enhancement New feature or request module: ddd Domain-Driven Design related support labels Oct 21, 2020
@odrotbohm
Copy link
Member

odrotbohm commented Oct 27, 2020

There are already building block types in jMolecules that follow the type constraints outlined in John Sullivan's Advancing Enterprise DDD blog post. I just checked our interfaces and it looks like they deserve a round of polish. PR coming.

Regarding TinyType: I'm not sure it's worth a superclass to basically default equals(…)/hashCode(). That said I am not decidedly opposed to introduce it. It leaves us with a few open questions though:

  1. So far user domain types are supposed to either use annotations or the base types. I.e. it feels odd having to extend the class and also annotate it with @ValueObject. Following the patterns for the other types, shouldn't TinyType become ValueObject in the first place?
  2. All other building blocks types are interfaces. TT being a class would break that to some degree and we'd have to argue why you can implement one and have to extend the other.
  3. Value objects cannot only be types wrapping a single value. I.e. TT currently seems to cater the common but still a bit special case of a single value in that type defining equals(…)/hashCode().

Summarizing, the existence of TT seems to be entirely catering technical convenience. Does it maybe make sense to introduce ValueObject<T> exposing T value() and leave TinyType as an implementation of that living in a different project or potentially even in user land completely?

@mstine
Copy link

mstine commented Feb 9, 2021

Where did y'all land on the ValueObject discussion? I notice that it has not yet landed in the building block types. I'm starting to pull jMolecules into my teaching codebase, and ValueObject is noticeably absent.

@odrotbohm
Copy link
Member

odrotbohm commented Feb 11, 2021

I am still not sure we want to get in the business of defining domain implementation classes as it's way too easy for them to become unusable in a certain technical context which is at odds with the importance their sole existence implies, should we ship them.

For now, I'd vote those implementations to live in a dedicated, separate library, so that's an opt-in and also is slightly less prominent than the interfaces and annotations we ship as core jMolecules. For all already existing technology integration, we just recently decided to move code of similar kind into a separate repository so that it can be released independently and is also perceived as something "transitive".

Does that make sense?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module: ddd Domain-Driven Design related support type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants