Złota zasada: zdarzenia (czasowniki), a nie struktury danych (rzeczowniki)
Rozróżnienie między komendami (zmieniają stan systemu), a widokami
DDD taktyczne
Clean Architecture
Założenia
Budowanie ze słomy, z drewna, z cegieł
Po zdmuchnięciu domu - ucieczka do sąsiedniego
Rezygnacja wilka po próbach zdmuchnięcia domu z cegieł
Wyciągnięcie wniosków przez świnki, nauka
Przemilczane:
Wspinanie się wilka przez komin
Zjadanie świnek
Opowiadanie o mamie świnek
Imprezowanie świnek po skończonej pracy
User Story
Co system powinien "wystawić na świat"
Jako użytkownik, chcę poznać bajkę o trzech świnkach, żeby móc ją
opowiedzieć innym
...
Jako świnka, chcę zbudować dom, dostosowany do moich potrzeb
Dokumentowanie i utrwalanie informacji
Jako wilk chcę zdmuchnąć dom, żeby móc złapać świnkę
Rejestr - z tym domem już próbowano
Jaki agregat?
Big Picture
Design-Level
Jak zbudować dom?
public class BigBadWolfService {
private final DomainEventPublisher eventPublisher;
BigBadWolfService(final DomainEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void blowDown(final House target) {
try {
target.handleHurricane();
} catch (House.IndestructibleHouseException e) {
retryBlowing(target);
}
}
private void retryBlowing(final House target) {
try {
target.handleHurricane();
} catch (House.IndestructibleHouseException e) {
eventPublisher.publish(
new WolfResignedFromAttacking(target.getSnapshot().id())
);
}
}
}
Specyfikacja
@Unroll('house from #inputMaterial vs. #resource')
def 'should fail for material different than in specification'() {
given:
def house = houseFrom inputMaterial
expect:
!new ConstructionSpecification(resource).isSatisfiedBy(house)
where:
resource | inputMaterial
STRAW | BRICKS
WOOD | STRAW
STRAW | WOOD
}
@Before("handling()")
void logBeforeHandling(JoinPoint jp) {
if (logger.isInfoEnabled()) {
var command = jp.getArgs()[0];
if (command instanceof BuildHouse buildCommand) {
switch (buildCommand.getOwner()) {
case VERY_LAZY -> logger.info("The first little pig was very lazy");
case LAZY -> logger.info("The second little pig was a bit more ambitious");
case NOT_LAZY -> logger.info("The third little pig was ready for hard work");
}
}
}
}