Class Diagram
Legend
@startuml
class ToDo #fff
class InProgress #ff9
class Done #6f6
note bottom of InProgress
still has open issues / tickets
including tests
but it may already be functional
endnote
note top of Done
has no open issues / tickets
and it is functional
endnote
ToDo -right-> InProgress
InProgress -right-> Done
@enduml
Model
Global Diagram
Dand le package de Model on troi sub-package:
Players
,
Dice
et
Games
;
et une class Abstraite Imanager qui vas etre implementé par:
GameManager
,
PlayerManager
et
DiceManager
pour avoir les method du CRUD.
Dand le sub-package Dice on a une class abstraite Dice
class maire de homogenouseDie
, cela nous permet de creer des un Die
avec le meme type des Face
.DieGroupeManager
ce compose de plusieur DieGroup
qui lui meme ce compose de plusieur Die
.
Le sub-package Players a un PlayerManager
qui a une list de Players
pour Games ona la classe MasterOfCeremonies
qui joue le role d'une façade et orchestre tous le model, où on peut trouver le GameManager
qui a une list des Game
,Game
have a list of Dice
and Turn
qui a une relation manyToMany avec Dice
et Face
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
package Model <<Frame>> #bada55 {
interface IManager<T> $done
package Dice #fdb {
class DiceGroupManager $inprogress
class DiceGroup $done
abstract class Die $done
abstract class HomogeneousDie<T> $done
package Faces #9ff {
abstract class Face $done
}
}
package Players #bcf {
class PlayerManager $done
class Player $done
}
package Games #daf {
class GameManager $done
class MasterOfCeremonies $done
class Game $done
class Turn $done
}
}
PlayerManager .right.|> IManager
PlayerManager --> Player : "[*]"
Turn .. (Die, Face) : [*]
Face "[1]" -- "[1]" Die
Turn --> Player
DiceGroupManager .up.|> IManager
DiceGroupManager --> DiceGroup : "[*]"
DiceGroup --> Die : "[*]"
GameManager .left.|> IManager
GameManager --> Game : "[*]"
Die --> Face : "[*]"
HomogeneousDie --|> Die
MasterOfCeremonies --> IManager
MasterOfCeremonies --> IManager
MasterOfCeremonies --> IManager
Game --> Turn : "[*]"
Game --> IManager
Game --> Die : "[*]"
@enduml
App / Data / Model.Games.MasterOfCeremonies
MasterOfCeremonies est le coeur du modèle de notre application(la façade).
MasterOfCeremonies
peux charger les donner du Stub
ou DiceAppDBContext
.
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
class System.Data.Entity.DbContext
package Data <<Database>> #ddd {
interface ILoader $done {
+LoadApp(): MasterOfCeremonies
}
class Stub $done
class DiceAppDbContext $inprogress {
#OnConfiguring(optionsBuilder: DbContextOptionsBuilder)
}
class DiceAppDbContextWithStub $inprogress {
#OnModelCreating(modelBuilder: ModelBuilder)
}
}
package App <<Cloud>> #fff {
class Program $inprogress {
+Main()
}
}
package Model <<Frame>> #bada55 {
package Games #daf {
class MasterOfCeremonies $done {
/+GlobalPlayerManager: IManager<Player>
/+DiceGroupManager: IManager<DiceGroup>
/+GameManager: IManager<Game>
{static} +PlayGame(game: Game)
+StartNewGame(name..., players..., dice...): Game
}
}
}
Stub ..|> ILoader
ILoader ..> MasterOfCeremonies
Program ..> ILoader
Program ..> MasterOfCeremonies
DiceAppDbContextWithStub --|> DiceAppDbContext
DiceAppDbContext --|> System.Data.Entity.DbContext
DiceAppDbContext ..|> ILoader
@enduml
Games
IManager est une interface de CRUD.
Game représente une partie spécifique, et contient son propre PlayerManager (pour faire du CRUD sur sa propre collection de Player) une collection de Turn, et une collection de Die que MasterOfCeremonies lui a donné quand il l'a créé. Game contient des méthodes pour créer un Turn ("lancer des dés").
Turn sera utile pour garder un historique des tours d'une partie.
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
package Model <<Frame>> #bada55 {
abstract class Die $done
abstract class Face $done
class Player $done
interface IManager<T> $done {
+Add(toAdd: T): T
+GetAll(): [*] T
+GetOneByName(name: string): T
+GetOneByID(ID: Guid): T
+Update(before: T, after: T): T
+Delete(toDelete: T)
}
package Games #daf {
class MasterOfCeremonies $done {
{static} +PlayGame(game: Game)
+StartNewGame(string, IManager<Player>, [*] Die): Game
}
class GameManager $done
class Game $done {
/+Name: string
+PerformTurn(player: Player)
+GetHistory(): [*] Turn
+GetWhoPlaysNow(): Player
+PrepareNextPlayer(current: Player)
}
class Turn $done {
+/When: DateTime
-Ctor()
{static} +CreateWithDefaultTime(...)
{static} +CreateWithSpecifiedTime(...)
}
}
}
Turn .left. (Die, Face) : [*] /+DiceNFaces
Face "[1]" -up- "[1]" Die
Turn -down-> "/+Player" Player
MasterOfCeremonies --> IManager : "T <-- <DiceGroup>"
MasterOfCeremonies --> IManager : "T <-- <Player>"
MasterOfCeremonies --> IManager : "T <-- <Game>"
GameManager ..|> IManager : "T <-- <Game>"
GameManager --> "[*] -games" Game
Game -down-> "[*] /+Dice" Die
Game -down-> "[*] /+Turns" Turn
Game -right-> IManager : "T <-- <Player>"
@enduml
Players
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
package Model <<Frame>> #bada55 {
interface IManager<T> $done {
+Add(toAdd: T): T
+GetAll(): [*] T
+GetOneByName(name: string): T
+GetOneByID(ID: Guid): T
+Update(before: T, after: T): T
+Delete(toDelete: T)
}
package Players #bcf {
class PlayerManager $done
class Player $done {
/+Name: string
}
}
}
PlayerManager ..|> IManager : "T <-- <Player>"
PlayerManager --> "[*] -players" Player
@enduml
Dice
Dans DiceGroupManager, Update()
permet de modifier le nom d'un groupe de dés. Cette méthode renvoie une ArgumentException
si on essaye de modifier un groupe de dés.
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
package Model <<Frame>> #bada55 {
interface IManager<T> $done {
+Add(toAdd: T): T
+GetAll(): [*] T
+GetOneByName(name: string): T
+GetOneByID(ID: Guid): T
+Update(before: T, after: T): T
+Delete(toDelete: T)
}
package Dice #fdb {
class DiceGroupManager $inprogress
class DiceGroup $done {
/+Name: string
}
abstract class Die $done {
{static} ~rdm: Random
GetRandomFace(): Face
}
abstract class HomogeneousDie<T> $done {
GetRandomFace(): Face<T>
}
class NumberDie $done
class ImageDie $done
class ColorDie $done
package Faces #9ff {
abstract class Face $done
}
}
}
ImageDie --|> HomogeneousDie : "T <-- <Uri>"
ColorDie --|> HomogeneousDie : "T <-- <Color>"
NumberDie --|> HomogeneousDie : "T <-- <int>"
DiceGroupManager ..|> IManager : "T <-- <DiceGroup>"
DiceGroupManager -up-> "[*] -diceGroups" DiceGroup
DiceGroup -up-> "[*] /+Dice" Die
HomogeneousDie --|> Die
Die -left-> "[*] /+Faces" Face
@enduml
Faces
Face<T>
hérite de Face
: Face
contient /+StringValue
, et pas de généricité. C'est grâce à cette classe qu'on peut définir Die
sans faire appel à la généricité.
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
package Model <<Frame>> #bada55 {
package Dice #fdb {
package Faces #9ff {
abstract class Face<T> $done {
/+Value: T
/+StringValue: string
}
class NumberFace $done
class ImageFace $done
class ColorFace $done
}
}
}
Face --|> Face
ImageFace --|> Face : "T <-- <Uri>"
ColorFace --|> Face : "T <-- <Color>"
NumberFace --|> Face : "T <-- <int>"
@enduml
Data
Global Diagram
Le package Data contien ILoader
une interface qui aide a charger un objet de MasterOfCeremonies
.
Les deux class Stub
et DiceAppDbContext
implemente Iloader
et ovveride la methode Load()
, qu'elle a un type de retour MasterOfCeremonies
.
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
class System.Data.Entity.DbContext
package Data <<Database>> #ddd {
class Stub $done
interface ILoader $done
package EF #9fb {
package Dice #fdb {
class DieEntity $inprogress
class DieExtensions <<static>> $inprogress
class DiceGroupDbManager $todo
class FaceEntity $inprogress
class FaceExtensions <<static>> $inprogress
}
package Games #daf {
class GameEntity $todo
class GameExtensions <<static>> $todo
class GameDbManager $todo
class TurnEntity $done
class TurnExtensions <<static>> $done
}
package Players #bcf {
class PlayerEntity $done
class PlayerExtensions <<static>> $done
class PlayerDbManager $done
}
class DiceAppDbContext $inprogress
class DiceAppDbContextWithStub $inprogress
}
}
Stub ..|> ILoader
DiceAppDbContextWithStub -right-|> DiceAppDbContext
DiceAppDbContext -up-|> System.Data.Entity.DbContext
DiceAppDbContext .left.|> ILoader
PlayerExtensions ..> PlayerEntity
DieExtensions ..> DieEntity
FaceExtensions ..> FaceEntity
DieEntity --> "[*]" FaceEntity
GameExtensions ..> GameEntity
TurnExtensions ..> TurnEntity
DiceAppDbContext -down-> "[*]" PlayerEntity
DiceAppDbContext -right-> "[*]" DieEntity
DiceAppDbContext -up-> "[*]" GameEntity
DiceAppDbContext --> "[*]" TurnEntity
PlayerDbManager -up-> DiceAppDbContext
DiceGroupDbManager -left-> DiceAppDbContext
GameDbManager -down-> DiceAppDbContext
@enduml
EF (Global)
Dans Data.EF
on a trois sub-package Players
,Dice
et Games
, chaqu'un de ces troi package a trois types de class:
- dbManager: implemente
IManager
pour Faire les methode CRUD sur la DB - context: nous aide a passé des entite vere les model et vice versa.
- entity: c'est la presentation des modesle pour EF, EF ce base sur les Entity pour creer les Tables de la BD
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
package Data <<Database>> #ddd {
package EF #9fb {
package Dice #fdb {
class DieEntity $inprogress
class DieExtensions <<static>> $inprogress
class DiceGroupDbManager $todo
class FaceEntity $inprogress
class FaceExtensions <<static>> $inprogress
}
package Games #daf {
class GameEntity $todo
class GameExtensions <<static>> $todo
class GameDbManager $todo
class TurnEntity $done
class TurnExtensions <<static>> $done
}
package Players #bcf {
class PlayerEntity $done
class PlayerExtensions <<static>> $done
class PlayerDbManager $done
}
class DiceAppDbContext $inprogress
class DiceAppDbContextWithStub $inprogress
}
}
DiceAppDbContextWithStub -down-|> DiceAppDbContext
PlayerExtensions ..> PlayerEntity
DieExtensions ..> DieEntity
FaceExtensions ..> FaceEntity
DieEntity --> "[*]" FaceEntity
GameExtensions ..> GameEntity
TurnExtensions ..> TurnEntity
DiceAppDbContext -down-> "[*]" PlayerEntity
DiceAppDbContext -right-> "[*]" DieEntity
DiceAppDbContext -up-> "[*]" GameEntity
DiceAppDbContext -up-> "[*]" TurnEntity
PlayerDbManager -up-> DiceAppDbContext
DiceGroupDbManager -left-> DiceAppDbContext
GameDbManager -down-> DiceAppDbContext
@enduml
Players
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
class DiceApp.Model.Player $done
interface DiceApp.Model.IManager<T> $done {
+Add(toAdd: T): T
+GetAll(): [*] T
+GetOneByName(name: string): T
+GetOneByID(ID: Guid): T
+Update(before: T, after: T): T
+Delete(toDelete: T)
}
package Data <<Database>> #ddd {
package EF #9fb {
package Players #bcf {
class PlayerEntity $done {
/+ID: Guid
/+Name: string
}
class PlayerDbManager $done {
+Ctor(db: DiceAppDbContext)
+IsPresentByName(name: string): bool
+IsPresentByID(ID: Guid): bool
}
class PlayerExtensions <<static>> $done {
{static} +ToModel(...)
{static} +ToModels(...)
{static} +ToEntity(...)
{static} +ToEntities(...)
}
}
class DiceAppDbContext $inprogress
}
}
DiceAppDbContext --> "[*] /+Players" PlayerEntity
PlayerDbManager -left-> "-db" DiceAppDbContext
PlayerDbManager ..|> DiceApp.Model.IManager : "T <-- <PlayerEntity>"
PlayerExtensions .left.> PlayerEntity
PlayerExtensions ..> DiceApp.Model.Player
@enduml
DiceAppDbContext
@startuml
skinparam classAttributeIconSize 0
!$todo = "#fff"
!$inprogress = "#ff9"
!$done = "#6f6"
class System.Data.Entity.DbContext
package Data <<Database>> #ddd {
package EF #9fb {
package Dice #fdb {
class DieEntity $inprogress
class DiceGroupDbManager $todo
class FaceEntity $inprogress
}
package Games #daf {
class GameEntity $todo
class GameDbManager $todo
class TurnEntity $done
}
package Players #bcf {
class PlayerEntity $done
class PlayerDbManager $done
}
class DiceAppDbContext $inprogress {
#OnConfiguring(...)
}
class DiceAppDbContextWithStub $inprogress {
#OnModelCreating(...)
}
}
}
DiceAppDbContextWithStub --|> DiceAppDbContext
DiceAppDbContext --|> System.Data.Entity.DbContext
DiceAppDbContext --> "[*] /+Players" PlayerEntity
DiceAppDbContext --> "[*] /+Dice" DieEntity
DiceAppDbContext --> "[*] /+Faces" FaceEntity
DiceAppDbContext -up-> "[*] /+Games" GameEntity
DiceAppDbContext -up-> "[*] /+Turns" TurnEntity
DieEntity --> "[*] /+Faces" FaceEntity
PlayerDbManager --> "-db" DiceAppDbContext
DiceGroupDbManager --> "-db" DiceAppDbContext
GameDbManager -down-> "-db" DiceAppDbContext
@enduml