REFERENCE · Architecture & package map · Blackjack Ensemble course

Reference card — print me

Repo Map

One page that tells you where everything lives and which way the arrows point. Ted's blackjack-ensemble-blue is a hexagonal (ports & adapters) Spring Boot app. Keep this next to the shortcut card.

1 · The dependency rule (memorise the arrow)

  adapters  ──▶  application  ──▶  domain
 (in / out)      (use cases,     (pure rules,
                  ports)          no framework)

        domain depends on NOTHING.
        arrows only ever point inward.
Why blue teams care The domain (Blackjack rules) knows nothing about Spring, HTTP, or the console. That's what makes it fast and trivial to unit-test — the whole point of the “Make Code More Testable” class. Adapters are the replaceable skin; the domain is the protected core.

2 · Package tour

PackageRoleLandmark classes
domainPure game rules & state. No imports of Spring/web.Game, Hand, Card, Rank, Deck, Shoe, PlayerAccount, Wallet, Bet
applicationUse-case orchestration (“services”). Drives the domain.GameService, GameCommand
application.portInterfaces the app needs — the “sockets”.GameRepository, GameMonitor, Shuffler, PlayerAccountRepository
adapter.in.webDriving adapter: Spring MVC controllers + view models.BlackjackController, WelcomeController
adapter.in.consoleDriving adapter: text UI.ConsoleGame, ConsoleCard, ConsoleHand
adapter.out.repositoryDriven adapter: persistence (CSV, in-memory event store).CsvGameRepository, *Dto
adapter.out.*Driven adapters: shuffler, game monitor.RandomShuffler, HttpGameMonitor
(root)Spring Boot startup & console entry point.BlackjackGameApplication, Blackjack
Honest note HexArchTest exists but is entirely commented out — the layering rules are documented there as intent, not enforced by CI right now. Re-enabling it could be a great ensemble task. Until then, the arrow is a discipline the team keeps by hand.

3 · “in” vs “out” adapters

Driving (in)Driven (out)
Calls into the app. The web/console uses GameService.The app calls out through a port; an adapter implements it (DB, HTTP, RNG).
adapter.in.web → applicationapplication.port ← adapter.out.repository

4 · Two ways state is held (know the difference)

StyleClassHow state changes
Plain objectWalletMutates a field directly (balance += amount).
Event-sourcedPlayerAccountRecords an event (MoneyDeposited), then apply() folds it into state. Rebuilt by replaying events via reconstitute().

The event vocabulary is a Java sealed interface PlayerAccountEvent permitting PlayerRegistered, MoneyDeposited, MoneyBet, PlayerWonGame, PlayerLostGame. apply() uses a switch with record patterns (a preview feature — that's the --enable-preview flag in pom.xml).

5 · Ubiquitous language (from Glossary.md)

TermMeaning
Blackjack / NaturalAce + 10-value card in exactly 2 cards → immediate win (unless dealer also has it → Push).
Standing playerDidn't bust, no Blackjack; waits for the dealer to resolve the outcome.
Busted playerHit and went over 21 → lost immediately.
TurnA decision point: Hit or Stand. Turn complete = standing, bust, or Blackjack.
PushA tie with the dealer.

6 · Build & run (command line — as the README insists)

./mvnw verify                         # compile + run all tests (needs JDK 25)
./mvnw package                        # build the jar
java -jar target/blackjack-1.0.0.jar  # play in a real terminal
JDK 25, not 21 The README says “Java 21+”, but pom.xml sets <java.version>25</java.version>, so Spring compiles with --release 25. Your machine's terminal and IntelliJ Project SDK must both be Temurin 25 (already installed at ~/.jdks/temurin-25).

Confused about where a class lives or which layer may call it? Ask me — I'll trace the call path in the real code.