Notre sérialisation permet de sauvegarder nos données dans des fichiers *XML* ainsi que de charger dans des collections les données contenues dans ceux-ci.
Cette méthode est appelée lorsque l'utilisateur démarre l'application *Linaris* (MAUI). Celle-ci appelle ensuite les différentes fonctions de chargement codées en *C#* présentes dans la classe *LinqXmlSerialization*. Grâce à la bibliothèque **LINQ_XML**, la sérialisation peut récupérer les données présentes dans les différents fichiers pour les classes **Artist**, **CustomTitle** et **Playlist** et les mettre dans les différentes *ObservableCollection*. Pour les classes **InfoTitle** et **Album**, les données sont récupérées dans les collections des stubs correspondant et les mettre dans les différentes *ObservableCollection*. Les données sont ensuite utilisables par les vues via le **manager**.
### NextTitle()
```plantuml
@startuml
autonumber
actor Utilisateur as user
participant Front as vues
participant Manager as man
participant Playlist as play
group NextTitle
user -> vues : Clique sur le bouton suivant
vues -> man : Appelle la fonction NextTitle
alt currentPlaylist == null
vues <--man:neretournerien
else currentPlaylist != null
man -> play : Demande le titre suivant
alt loop == true
man <--play:retourneletitreactuel
else loop == false and shuffle == true
man <--play:retourneuntitrealéatoiredelaplaylist(indexentre0etlatailledelaplaylist)
else loop == false and shuffle == false
man <--play:retourneletitresuivant(index+1)
end
vues <--man:retourneletitre
user <--vues:joueletitre
end
end
@enduml
```
#### Explications
Lorsque l'utilisateur clique sur le bouton **suivant**, la fonction **NextTitle** de la classe C# *Manager* est appelée. Si la variable *currentPlaylist* est initialisée,
la fonction **NextTitle** de la classe *Playlist* est appelée. Si le booléen *loop* est vrai, la fonction retourne le titre actuel. Si le booléen *loop* est faux et le booléen *shuffle* est vrai,
la fonction retourne un titre aléatoire en générant un nombre aléatoire compris entre 0 et la taille de la playlist (nombre de titres) grâce à la fonction **RandomGenerator** de la playlist.
À l'inverse, si le booléen *shuffle* est faux, la fonction retourne le titre suivant en incrémentant de 1 l'index du son actuel.
---
#### Description de l'architecture
Notre programme se compose de deux parties distinctes : les **vues** et le **modèle**.
Pour les **vues**, cela correspond aux visuels de l'application. Pour le modèle, cela correspond à la logique de l'application, son fonctionnement.
Ces deux parties sont liées par le **DataBinding** liant les données et le modèle avec les vues.
<br/>
Pour permettre cela, nous avons mis en oeuvre le patron de conception de **"façade"** grâce à la classe *Manager*. En effet, cette classe est un *point d'entrée* vers le modèle, où le fonctionnement est caché par des méthodes et propriétés comme c'est le cas pour les listes d'objets. Les vues ne savent pas comment ces listes sont créées, elles ne font que l'utiliser. Cette classe **gère le modèle** mais est aussi l'interlocuteur des vues. C'est un **lien** entre ces deux parties. Cela nous permettait de bien **séparer les vues et le modèle**, mais aussi de **réduire** et **clarifier** le code présent dans le code-behind des vues.
<br/>
De plus, nous avons intégré le patron de conception de **"stratégie"** grâce à l'interface *IDataManager* et l'*injection de dépendance par le contructeur* du Manager. En effet, cela nous permet de *changer de méthode* de sérialisation très facilement. Nous pouvons donc utiliser les stubs pour tester le programme et repasser sur la sérialisation XML pour utiliser l'application en un simple changement. Cela permet une **adaptabilité** de code non négligeable. Il suffit de changer le paramètre donné au constructeur du Manager.
En outre, pour que cela fonctionne, l'interface *IDataManager* est indispensable, afin de s'assurer que toutes les méthodes de sérialisation aient bien **toutes les méthodes** nécessaires au bon fonctionnement de l'application. Grâce à cela, nous n'avons pas à nous demander quelle est la méthode de sérialisation pusique l'appel de la méthode de l'interface appellera la méthode de la technique de sérialisation demandée. Nous obtenons un résultat différent selon la méthode **sans changer le code**. Par exemple, dans la classe *App*, nous pouvons simplement appeler la méthode de sérialisation du manager, nous n'avons pas à changer ce code à chaque changement de méthode de sérialisation. Cela nous fait **gagner en temps** et en **adaptabilité de code**.
Grâce à ces patrons de conception, nous pouvons passer des stubs à la sérialisation XML bien plus facilement et **sans changer le code** des vues.
<br/>
Afin de lier nos différents projets, nous avons ajouté des **dépendances**. En effet, pour que l'*application console*, les *vues* et les *tests unitaires* fonctionnent, nous avons ajouté la dépendance vers le *modèle*.
Par ailleurs, nous avons aussi ajouté la dépendance vers **XUnit** pour le projet des *tests unitaires* et la dépendance vers **ToolKit** pour les vues afin de pouvoir utiliser *MediaElement* pour la lecture de médias.