New Style

Data Oriented Java

Java Software Engineer

Line of Business Public

Merlin Bögershausen / @mboegie

Warning

Heavy use of preview features!

Data Oriented Programming?

Monolithic history

Monolith

Self-Contained Systems

SelfcontainedSystems

Even smaller

text

Data Orientation means

  • Data is Data and nothing but the data

  • Strict separation between data and logic

  • like functional programming

How to DOP

Analyze Domain

Domain

Model only valid state

BeispielKlasssenDiagramm

Write Domain

sealed interface Rechnung
  permits InterneVerechnung, ExternVersandt {}

record ExternVersandt(Kunde kunde, double wert)
  implements Rechnung {}

record InterneVerechnung(String abteilung, double wert)
  implements Rechnung {}

Write Domain

// omitted interface Kunde and record Businesskunde

record Privatkunde(String name, List<String> mail)
  implements Kunde {
    Privatkunde {
        Objects.requireNonNull(name);
        mail = List.copyOf(mail);
    }
}

Write Logic - OOP

static double calculateMwSt(Kunde kunde, double wert) {
  if (kunde instanceof Privatkunde)
    return calculateMwSt((Privatkunde) kunde, wert);
  else if (kunde instanceof Businesskunde)
    return calculateMwSt((Businesskunde) kunde, wert);
  else
    throw new IllegalArgumentException(/* */);
}

static double calculateMwSt(Privatkunde p, double wert) {
  return wert * 0.1d;
}

static double calculateMwSt(Businesskunde b, double wert) {
  return b.isVorsteuerAbzugsberechtigt() ? 0d : wert * 0.1d;
}

Instanceof Pattern

static double calculateMwSt(Kunde kunde, double wert) {
  if (kunde instanceof Privatkunde) {
    return wert * 0.1d;
  } else if (kunde instanceof Businesskunde b) {
    if (b.isVorsteuerAbzugsberechtigt()) return 0.0d;
    else return wert * 0.1d;
  } else {
    throw new IllegalArgumentException(/* */);
  }
}

Switch Expression

static double calculateMwSt(Kunde kunde, double wert) {
  return switch (kunde) {
    case Privatkunde p -> wert * 0.1d;
    case Businesskunde b
      when b.isVorsteuerAbzugsberechtigt() -> 0.0d;
    case Businesskunde b -> wert * 0.1d;
  };
}

Deconstruct

static double calculateMwSt(Kunde kunde, double wert) {
  return switch (kunde) {
    case Privatkunde p -> wert * 0.1d;
    case Businesskunde(String n, var m, var noMwSt)
      when noMwSt -> 0.0d;
    case Businesskunde b -> wert * 0.1d;
  };
}

Ignore Parts

static double calculateMwSt(Kunde kunde, double wert) {
  return switch (kunde) {
    case Privatkunde _ -> wert * 0.1d;
    case Businesskunde(_, _, var noMwSt) when noMwSt -> 0.0d;
    case Businesskunde _ -> wert * 0.1d;
  };
}

Format the Text

static String produceInvoiceText(
        Kunde kunde, double wert, double mwst) {
  return FMT. """
    Hallo \{
      switch (kunde) {
        case Privatkunde(String name, _) -> name;
        case Businesskunde(var name, _, _) -> name;
      } },
    Bitte senden Sie uns den Rechnungsbetrag in Höhe von \
    %.2f\{ wert }€ plus %.2f\{ mwst }€ MwSt \
    %2.f\{ wert + mwst }.

    Mit freundlichen Grüßen
    Merlin Bögershausen
    """ ;
}

Real World

Testing

@Test
void invoiceValue100() {
  var customer = new Privatkunde("test", "test@dummy.de");

  var actualMwSt = MwStRechner.calculateMwSt(customer, 100d);

  assertThat(actualMwSt).isEqualTo(10d);
}

6 Test to rule them all

Modules

modularization

Integrate in EE

@Path("/invoice")
public class InvoiceResource {
  @Inject KundenRepository kundenRepo;
  @Inject MailService mailService;
  @GET
  public void sendInvoice(long kundeID, double wert) {
    var kunde = kundenRepo.findById(kundeID);
    var mwst = MwStRechner.calculateMwSt(kunde, wert);
    var text = InvoiceFormatter.
        produceInvoiceText(kunde, wert, mwst);
    mailService.sendMail(kunde, text);
  }
}

Final Thoughts

Make your Opinion

For every te am there are different trade-offs:

  • Readability - learn and use

  • Duplication - not always bad

  • Testability - no brain needed

  • Performance - don’t guess, measure!

Micro steps and huge gain for small disruption.

Try it!

Contact

Me

MBoegie@fosstodon.org // @MBoegi // MBoegers

adesso

Infos // DevBlog

Approach direct

I'm here all day with cookies!

Jobs

qrcode adesso jobs

Image Credits