Soit quatre classes A, B, C, D. On souhaite émuler en Java le fait que D hérite de A, B, C.
Question :
Proposez une solution en UML pour cela. Quel design pattern utiliseriez-vous ?
L’ingénieur de notre petite entreprise a développé un logiciel de contrôle suivant le schéma UML ci-dessous. L’idée est la suivante : on a une classe Streamer qui gère un flux de données. Celles-ci sont traitées via une classe ProcessingUnit qui peut exécuter ses calculs soit sur GPU (CUDA) soit sur CPU. Les données ainsi traitées peuvent être affichées par le centre de contrôle via la méthode displayProcessing().
Plus précisément, lors de sa construction, le ControlCenter exécute une thread timedProcess() qui se réveille toutes les 15ms afin de demander au ProcessingUnit qu’il contient s’il y a eu une update des données, auquel cas ces données sont traitées par la méthode getProcessingUpdate() et affichées via la méthode displayProcessing(). Ce processus n’est pas optimal dans la mesure où les updates apparaissent plutôt toutes les 2 ou 3 secondes, mais le logiciel fonctionne malgré tout correctement.
Question :
Récemment embauché dans l’entreprise, on vous demande de mettre à jour ce schéma UML pour qu’il soit SOLID et efficace. En exploitant les design patterns, quel nouveau schéma UML proposez-vous?
Un tenseur est la représentation informatique d’une table multidimensionnelle. C’est donc une généralisation d’un vecteur (table de dimension 1) et d’une matrice (table de dimension 2). Par exemple, les tableaux numpy de Python sont des tenseurs.
Ci-dessous, Tens est un tenseur. Si ses dimensions correspondent à des variables x,y,z (dans cet ordre) alors Tens[0,2,1] = Tens[x=0,y=2,z=1] = 2.
x=0 | x=1 | ||||||
---|---|---|---|---|---|---|---|
Tens = | y=0 | y=1 | y=2 | y=0 | y=1 | y=2 | |
3 | 1 | 7 | 4 | 6 | 5 | z=0 | |
8 | 7 | 2 | 3 | 5 | 8 | z=1 |
On souhaite ici développer en Java une classe générique Tenseur<T> équivalente aux tableaux numpy et contenant des éléments de type T. Outre un ou plusieurs constructeurs, les seules méthodes publiques de cette classe sont :
int[] shape() : retourne les dimensions du tenseur, comme en numpy
Exemple :
Dans l’exemple 1, Tens.shape() retournerait [2,3,2], autrement dit, le nombre de valeurs possibles de x,y,z.
void reshape(int[]) : modifie les dimensions du tenseur, comme en numpy
Exemple :
Si l’on applique Tens.reshape([2,6]) au tenseur de l’exemple 1, on obtiendrait le tenseur ci-dessous. Autrement dit, on reporte les valeurs de Tens de la gauche vers la droite et du haut vers le bas.
x=0 x=1 3 1 z=0 Tens_bis = 7 4 z=1 6 5 z=2 8 7 z=3 2 3 z=4 5 8 z=5
T get(int[] pos) : renvoie la valeur du tenseur à la position passée en argument
Exemple :
Dans l’exemple 1, Tens.get([0,2,1]) retournerait la valeur 2.
void set(int[] pos, T val) : affecte la valeur val à l’élément de position pos du tenseur
Tenseur<T> add(Tenseur<T> x) : calcule et retourne le tenseur obtenu en additionnant à this le tenseur x
Exemple :
Si l’on appelle Tens.add(T2), avec T2 défini par :
x=0 x=1 T2 = y=0 y=1 y=2 y=0 y=1 y=2 1 1 1 1 1 1 z=0 1 1 1 1 1 1 z=1 on obtient le tenseur suivant (chaque case de Tens est incrémentée de 1) :
x=0 x=1 T3 = y=0 y=1 y=2 y=0 y=1 y=2 4 2 8 5 7 6 z=0 9 8 3 4 6 9 z=1
Tenseur<T> mult(Tenseur<T> x) : calcule et retourne le tenseur obtenu en multipliant this avec le tenseur x
L’idée des tableaux multidimensionnels (tenseurs) de numpy est de stocker en interne tous les éléments dans un vecteur (un MyArray<T>) et d’utiliser les informations de shape pour accéder aux éléments.
Dans cet exercice, on souhaite étendre ce stockage en proposant 2 méthodes de stockage :
des vecteurs classiques de type MyArray<T> stockant la totalité des éléments;
des vecteurs creux MySparseArray<T>, qui ne stockent que les éléments différents d’une certaine valeur.
Les éléments de ces deux types de vecteurs sont accessibles uniquement via des index (position depuis le début du vecteur) qui sont des entiers. Par exemple, array[5] correspond au 6ème élément du vecteur (comme dans un tableau usuel).
Les deux méthodes add(x) et mult(x) de la classe Tenseur<T> produisent de nouveaux tenseurs. Si le stockage interne du tenseur x est identique à celui de this, alors on souhaite que le tenseur qu’elles retournent ait le même type de stockage interne (par exemple si this et x utilisent des MySparseArray<T>, les tenseurs résultats utiliseront également des MySparseArray<T>), sinon on impose que ce soit un MyArray<T>.
Attention : on ne veut pas exposer le type de stockage à l’extérieur de la classe Tenseur, autrement dit la classe de tenseur que vous devez proposer est Tenseur<T>.
Question :
Écrivez un diagramme UML permettant de modéliser les tenseurs décrits ci-dessus ainsi que les classes de stockage. Évidemment, vous respecterez les principes SOLID et vous écrirez bien les attributs de vos classes ainsi que leurs méthodes (en précisant leurs paramètres et types de retour).