@binout
https://github.com/binout
asciidoctor-ant
)Tackling Complexity in the Heart of SoftwareEric Evans, 2003
1) Lire Domain-Driven Design Vite fait
2) Mettre le focus sur la modélisation du métier
Ubiquitous Language
)Un Pokemon :
pikachu
)public class Pokemon {
private Long id;
private String type;
private String name;
private int pv;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPv() {
return pv;
}
public void setPv(int pv) {
this.pv = pv;
}
}
public class Pokemon {
private final String id;
private final PokemonType type;
private String name;
private int pv;
public Pokemon(PokemonType type) {
this.id = UUID.randomUUID().toString();
this.type = Objects.requireNonNull(type);
this.name = type.value();
this.pv = 100;
}
public String id() {
return id;
}
public PokemonType type() {
return type;
}
public String name() {
return name;
}
public boolean isDead() {
return this.pv == 0;
}
public void die() {
this.pv = 0;
}
public void rename(String newName) {
this.name = newName;
}
public Optional<Pokemon> evolve() {
return type.evolution()
.map(evolutionType -> {
Pokemon pokemon = new Pokemon(evolutionType);
pokemon.name = this.name;
pokemon.pv = this.pv;
return pokemon;
});
}
4) S’appuyer sur une architecture hexagonale
5) La couche application doit définir des cas d’utilisation
public class EvolvePokemon {
private final PokemonBox box;
public EvolvePokemon(PokemonBox box) {
this.box = box;
}
public Pokemon execute(Trainer trainer, Pokemon pokemon) {
if (trainer.candies() > 50) {
Pokemon evolvedPokemon = pokemon.evolve()
.orElseThrow(() -> new RuntimeException("This pokemon cannot evoluate"));
this.box.remove(pokemon);
this.box.add(evolvedPokemon);
trainer.removeCandies(50);
return evolvedPokemon;
}
throw new RuntimeException("Not enough candies to evolve this pokemon");
}
}
public class CatchPokemon {
private final PokemonBox box;
public CatchPokemon(PokemonBox box) {
this.box = box;
}
public void execute(Trainer trainer, Pokemon pokemon) {
if (pokemon.isDead()) {
throw new RuntimeException("Cannot catch dead pokemon !");
}
this.box.add(pokemon);
trainer.addCandies(3);
}
}
6) Bien comprendre la notion de service
public class PokemonStatsCalculation {
private final Pokedex pokedex;
public PokemonStatsCalculation(Pokedex pokedex) {
this.pokedex = pokedex;
}
int attack(Pokemon pokemon) {
return awesomeAlgo(pokedex.baseStatAttack(pokemon));
}
int defense(Pokemon pokemon) {
return awesomeAlgo(pokedex.baseStatDefense(pokemon));
}
int stamina(Pokemon pokemon) {
return awesomeAlgo(pokedex.baseStatStamina(pokemon));
}
7) Living Documentation FTW !
Annotations :
@DDD.Entity
, @DDD.Repository
, @DDD.DomainService
, …8) Se débarrasser de ses à-priori de développeur !
public class Pokemon {
@Id
private final String id;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="value", column=@Column(name="TYPE"))
})
private final PokemonType type;
@Column(name = "name", columnDefinition = "VARCHAR(255)")
private String name;
@Column(name = "pv",length=2, nullable = false)
private int pv;
....
}
Utilisation de META-INF/orm.xml
9) Faire des tests d’intégration en utilisant le Behavior Driven Development
Scenario: Catch a pokemon
Given a pikachu with PV=512
When you give a cloudberry
And you throw a pokeball
Then the pikachu is caught
And you win 500 XP
10) Impliquer son Product Owner
/