Skip to content

johriviere/LuccaTest

Repository files navigation

Consigne du projet

Vous souhaitez créer un petit programme permettant de convertir automatiquement des montants dans une devise souhaitée.

Cas d'utilisation

Le projet gère les cas d'utilisation suivants :

  1. Cas standard

    • L'utilisateur utilise le programme avec un fichier d'entrée cohérent.
      De plus la conversion demandée est possible (existence d'au moins un chemin possible de proche en proche entre la devise source et la devise cible).
  2. Cas anormaux

    • L'utilisateur utilise le programme sans argument.
    • L'utilisateur utilise un fichier d'entrée non cohérent (cohérence du format ou cohérence logique).
    • L'utilisateur utilise un fichier d'entrée cohérent, cependant, la conversion ne peut pas être effectuée car il n'y a pas de chemin possible entre la devise source et la devise cible.

Théorie des graphes

Contexte

Une partie de la consigne est :

Si plusieurs chemins de conversion vous permettent d'atteindre la devise cible, vous devez utiliser le chemin le plus court.

La résolution de cette problématique est assimilable à une recherche du plus court chemin pour aller d'une devise source à une devise cible dans un graphe (liste de taux de change).

Généralités sur les graphes

Les propriétés du graphe représentant ce problème sont :

  • Graphe simple (pas de self-loop, pas de multi-edge)
    • non orienté (undirected)
    • sans notion de poids (unweighted)

Représentation d'un graphe

Un graphe peut être représenté de différentes façons.

La manière de représenter un graphe aura une influence sur 2 choses :

  • Complexité spatiale
    Il s'agit de la quantité de mémoire utilisée pour représenter les données du graphe.
  • Complexité temporelle
    Il s'agit de la performance des algorithmes qui vont pouvoir s'appliquer sur le graphe.
    Par exemple :
    • trouver si deux sommets sont connectés
    • trouver tous les sommets adjacents à un sommet donné

Dans ce projet, j'ai choisi de représenter les données en Edge list.

Algorithme du plus court chemin

Plusieurs algorithmes existent pour trouver le plus court chemin entre 2 sommets dans un graphe :

  • Dijkstra
  • Bellman-Ford
  • Floyd-Warshall

Dans ce projet j'ai choisi d'implémenter l'algorithme de Dijkstra.

Décisions d'architecture

Utilisation d'une architecture hexagonale (port/adapter)

Ressources

Description rapide

Trois grandes zones :

  • Application (Driver side)
  • Domain
  • Infrastructure (Driven side)

Le code et les concepts métier sont isolés dans la zone Domain. La zone Domain ne dépend de rien. Il ne doit exister aucun concept technique dans dans la zone Domain.
La zone Domain contient des ports :

  • ports primaires : ports à brancher sur la zone Application
  • ports secondaires : ports à brancher sur la zone Infrastructure Le branchement aux ports se fait via des Adapter.

L'avantage est d'isoler dans le Domain toute la valeur métier du programme.

Fonctionnalité de validation du fichier d'entrée de la responsabilité de la zone Application

Pour moi, la responsabilité de validation du fichier d'entrée est à faire par la zone Domain.
C'est similaire par exemple au travail qui est fait par les validateurs dans un site web MVC.

Fonctionnalité de recherche du plus court chemin de la responsabilité de la zone Infrastructure

Une partie du problème posé dans la consigne est assimilable à une recherche du plus court chemin pour aller d'un point A (devise source) à un point B (devise cible) dans un graphe (liste de taux de change).
Pour moi, toute la logique de recherche est purement technique et ne doit donc pas se trouver dans la zone Domain.
C'est juste une fonctionnalite technique dont le Domain a besoin. Cela semble logique de le placer dans la zone Infrastructure.
On peut imaginer implémenter des algorithmes alternatifs pour trouver le plus court chemin :

  • Algorithme de Bellman-Ford
  • Algorithme de Floyd-Warshall

Tests

Tests unitaires

Les projets de tests utilisent le framework de tests unitaires MSTest.
Le framework de simulacre est Moq.

Inversion Of Control (IoC)

Dans ce projet, j'ai utilise l'IoC. J'utilise notamment ce principe pour rendre indépendante la zone Domain de l'architecture hexagonale.
L'IoC est l'un des 5 principes SOLID.

Pour faire l'injection de dépendance, j'ai utilisé le container IoC Unity.

J'ai choisi d'injecter les dépendances par constructeur.