Index
Documentation Générale Qualité
Documentation Classes Metier
Documentation Liste Qualité Code Review
Documentation Liste Qualité Guideline Development
Documentation Bugs Defaults
Documentation Tests Unitaires
Documentation i18n
Documentation SQL Indexation
Documentation Timeframe

CLASS METIER : Couche d'abstraction entre le modèle de persistance de données, les contrôleurs, services ou autres class métiers

Date

Par

Quoi

Version

Etat git

31/08/2023

MB

Création

0.0.1

Dans Master

07/09/2023

MB

Ajout de “Etapes du portage vers les classes métier”

0.0.2

Dans Master

08/09/2023

MB

Ajout de “Les class métiers, ce qu’il faut savoir”

0.0.3

Dans Master

21/09/2023

MB

Ajout section “To Do”

0.0.4

Dans Master

27/09/2023

MD

Rédaction de la section concernant les filtres et getAll

0.0.5

Dans Master

21/10/2023

MB

Attention aux datas sources fournies à des fonctions typées, il faut les vérifier à l'implémentation et les corriger si besoin en amont.

0.0.6

Les class métiers, ce qu’il faut savoir        2

Définition Classe metier        2

Relation entre classe métiers et SGBD        2

Données        2

Où créer les méthodes métiers ?        3

Quand créer une nouvelle méthode ?        3

La classe métier type        4

Objet Métier        4

Convention de nommage        4

Les classes métiers        4

Les méthodes        4

Conventions et bonnes pratiques pour les méthodes        5

Retour de valeurs, gestion des erreurs        5

Validation des paramètres        5

Où créer les objets métiers ?        5

Quand créer un nouvel objet métier ?        6

Convention de nommage        6

Les objets métiers        6

Les attributs        6

Les méthodes        6

Généralités        6

Ordre des paramètres pour les getAll        6

Quand faire une fonction spécifique pour un filtre spécifique ?        7

Les getters et setters        7

Les méthodes publiques        7

Les méthodes privées        7

Etapes du portage vers les classes métier        9


Les class métiers, ce qu’il faut savoir

Définition Classe metier

Le but d'une classes métier est de factoriser le code en fournissant une couche d'abstraction entre le modèle de persistance de données

(base de données, xml, json, fichiers) et les contrôleurs, services ou autres classes métiers.

La maintenance et les évolutions sont plus simples dans du code centralisé, pensé en termes de besoins métiers et qui retourne des objets.

Relation entre classe métiers et SGBD

La classe métier n'a pas et ne DOIT PAS reproduire le schéma SGBD. C'est le rôle du manager. Il répond à un besoin, par conséquent, une méthode métier peut être amenée à

interagir sur plusieurs tables, faire appel elle-même à d'autres classes métiers.

Les méthodes - bien que spécialisées - doivent être aussi courtes que possible, leur nom doit exprimer parfaitement ce qu'elle fait (voir règles de nommage plus bas) et être pensées pour pouvoir s'adapter à différents besoins afin d'être réutilisées et interagir entre elles de manière logique.

La frontière entre trop spécialisée ou pas est mince, la nomenclature des classes aide à définir ce scope le plus souvent. Si on ne peut pas la nommer pour exprimer ce qu'elle fait dans les règles de nommage, il faut réfléchir.

Données

Les class métiers travaillent et retournent de préférence des OBJETS, pas des tuples de tables ou de tableaux, sauf bien sûr

lorsque la vocation de la méthode est de retourner ce type de données en particulier. Si une méthode doit retourner des données multiples, on préférera retourner

un nouveau type d'objet plutôt qu'un tableau.

Créer des objets métiers abstraits : Exemple src/classMetier/ClassMetierLoadTemplate/EntitiesFilters.php qui permet de créer un objet qui contient les données que l’on veut, pas forcément d’une table mais de toute origine (tables, calculs etc…).

Où créer les méthodes métiers ?

Généralement une méthode trouve naturellement sa place dans une classe métier. Exemple : une méthode qui retourne une ou des factures ou des lignes factures va être classée dans ClassMetierManagerFacture.

On se basera en premier sur le type d'objet retourné. Exemple : EmailsTemplates, EmailsTemplatesSocietes dans ClassMetierManagerEmailsTemplates, getSocieteByConsultant dans

ClassMetierManagementSocietes.

Il peut cependant être judicieux de déroger à cette règle dans certains cas. Exemple : Bien que retournant un objet Langue, getAllLanguesByIDemails_templates_societes qui retourne les langues disponibles pour un modèle de mail d'une société prend sa place dans ClassMetierManagementTemplatesEmail

plutôt que dans ClassMetierManagementLangues.

Quand créer une nouvelle méthode ?

Une nouvelle méthode doit répondre à un besoin.

Est-ce que la fonctionnalité doit être disponible de manière indépendante ou pas ? Exemple : Tu crèves un pneu, que fait le garagiste :

on a pas une seule méthode qui fait tout ça car ça n’a pas de sens. Et on appelle pas toutes ces méthodes une à une dans le controlleur, c’est la méthode reparePneu qui s’en occupe.

Une méthode existe-t-elle déjà ?

Peut-on arriver au résultat attendu en utilisant simplement des méthodes de class métiers déjà existantes (combinées ou pas) ?

Répond-elle à un besoin unique ou fréquent ?

Puis-je la nommer facilement avec la convention de nommage ?

La classe métier type

Exemple : …

Si vous sortez de ce schéma c’est soit que vous avez un nouveau cas exotique et il faut en parler ou que vous êtes sur une pente glissante.

Objet Métier

Parfois, il est nécessaire de créer un objet métier pour répondre à un besoin spécifique. C'est notamment le cas pour les objets qui ne sont pas directement liés à une table de la base de données.

Ou qui sont liés à plusieurs tables de la base de données (jointure).

Le constructeur de l'objet métier doit utiliser l'hydratation.

Convention de nommage

Afin d'unifier et de faciliter leurs utilisations, les classes et les méthodes doivent respecter plusieurs règles de nommages et d'ordre des paramètres.

Le développeur doit pouvoir comprendre ce que fait la méthode juste avec son nom et ainsi déterminer rapidement si une méthode remplit déjà la tâche qu'il cherche à mettre en œuvre.

De même, le développeur doit pouvoir imaginer une nouvelle méthode en imaginant son nom.

Les classes métiers

Les classes métiers sont nommées ClassMetier-action-sujet, exemple : ClassMetierLoadTemplate, ClassMetierManagementLangues, ClassMetierManagementTemplatesEmail.

Elles doivent être dans un sous répertoire, sous src\classMetier, au même nom que la classe

Les méthodes

- les méthodes publiques et protected utilisent le format : action-quoi-(By)-(comment)-(precision) : getContent, getAllContentsByIDSocietes, persistContent, deleteAllContentByIDSocietes

- Camel CASE

- les prefixes actions (évolutif) sont : get | getAll | persist | delete |deleteAll | search

- le séparateur entre l'objet et le comment et les précisions est "By"

- 'quoi' indique le type d'objet retourné, ou à défaut le type de données

- 'comment' indique ce qui est utilisé pour effectuer l'action

- 'precision' indique une éventuelle précision de spécialisation

- les méthodes privates sont précédées d'un _, exemple _getFirstIDfacturesIDconsultantByIDsocietes()

Responsabilité des méthodes

Conventions et bonnes pratiques pour les méthodes

- typer les valeurs : toujours indiquer le type de paramètre et valeur de retour dans la signature. maFunction.

- Attention aux datas sources fournies à des fonctions typées, il faut les vérifier à l'implémentation et les corriger si besoin en amont. Autrement dit, si vous forcez un typage d’un paramètre de la fonction (exemple float), il faut absolument penser à l’implémentation de vérifier que les params passés à la fonction sont biens des floats (et corriger la source de ces valeurs en amont si besoin dans la branche de PREPROD du projet + vérifier que ces changements de typages des sources de donnés ne produisent pas d’effets de bords ailleurs dans du code legacy), sinon cela va déclencher des fatal error en production ce qui n’est pas admis.

- pour les retours de valeur multiple, on passe en fin les paramètres int $offset=0, int $limit=0

- sur les getter, la méthode doit se terminer par un champ 'field' (avec valeur par défaut, '*' généralement) indiquant la liste des champs de l'objet à hydrater.

  2 exceptions à cette règle, soit si le type retourné est un objet composé, soit si tous les champs de l'objet sont systématiquement hydratés.

Retour de valeurs, gestion des erreurs

Les données retournées par un composant sont toujours dans un état valide, les erreurs sont retournées au travers d'exceptions.

Par exemple, une méthode peut retourner un tableau vide, mais pas une valeur null. Une méthode 'persist' retourne l'id de l'objet persisté, pas le succès ou l'échec de

l'action, une erreur de persistance doit être indiquée par la levée d'une exception.

Validation des paramètres

Chaque méthode s'assure que les paramètres qui lui sont fournis sont valides. En cas d'erreur, une exception doit être levée. Pas de retour true|false ou de valeur nulle.

Où créer les objets métiers ?

**Avant de créer un objet métier, il faut s'assurer qu'il n'existe pas déjà !**

L'objet métier se situe dans le même répertoire que la classe métier qui l'utilise le plus.

*Exemple : ObjMetierCraProjetStatus sera dans le répertoire ClassMetierManagementCra*

Quand créer un nouvel objet métier ?

Un nouvel objet métier doit répondre à un besoin.

Un objet métier existe-t-il déjà ?

Peut-on arriver au résultat attendu en utilisant simplement des objets métiers déjà existants (combinés ou pas) ?

Répond-il à un besoin unique ou fréquent ?

Puis-je le nommer facilement avec la convention de nommage ?

Convention de nommage

Les objets métiers

Les objets métiers sont nommés ObjMetier-sujet.

*Exemple : ObjetMetierCraProjetStatus*

Les attributs

Dans le cas où l'attribut correspond à un champ de la base de données, il doit être nommé de la même manière que le champ de la base de données.

Dans le cas où l'attribut ne correspond pas à un champ de la base de données, il doit être nommé de façon explicite, en utilisant le camelCase avec la première lettre en minuscule.

*Exemple : $nbJoursConges qui représente le nombre de jours de congés prit.*

Les méthodes

Généralités

Ordre des paramètres pour les getAll

Toute les méthodes getAll doivent avoir les paramètres suivants et pas un de plus :

Et doivent retourner un tableau des objets qu’il récupère.

Exemple d’une signature d’une fonction qui récupère toutes les langues pour PHP 7 :

/**

 * Retourne la liste de toutes les langues, classées par ordre alphabétique

 * @params int $offset index de départ, 0 par défaut

 * @params int $limit nombre d'enregistrements à retourner, tous par défaut (limit 0 <=> pas de limite)

 * @params string|string[] $ta_fields liste des champs à retourner dans l'objets, tous par défaut

 * @params array $sorts liste des tris et s'ils sont en reverse ou non. Ils doivent être implémentés dans la fonction

 * @params array $filters liste des filtres. Ils doivent être implémentés dans la fonction

 * @returns Langues[]

 */

public function getAllLangues(int $offset = 0, int $limit = 0, $ta_fields = '*', array $sorts = [], array $filters = []) : array {}

Quand faire une fonction spécifique pour un filtre spécifique ?

Il est possible de vouloir implémenter une fonction spécifique pour un filtre donné. Par exemple, une fonction qui récupère toutes les langues actives.

On s’autorise l’implémentation et l’utilisation d’une telle fonction à la place de la fonction getAll dans les cas suivants :

  1. Le filtre est souvent utilisé dans le code
  2. Le filtre est très complexe et s’applique sur plusieurs tables (ou fichiers)

Dans le cas des langues actives on serait dans le cas où le filtre est beaucoup utilisé. Ainsi, on se permettra de créer la fonction avec la signature suivante :

public function getAllLanguesActive(int $offset = 0, int $limit = 0, $ta_fields = ‘*’, array $sorts = []) : array {}

Cette fonction pourra faire sa propre requête pour aller chercher les données ou alors appeler la fonction getAllLangues().

Les getters et setters

Les getters et setters sont nommés getAttribut et setAttribut.

*Exemple : getNbJoursConges et setNbJoursConges*

Les méthodes publiques

Les méthodes publiques sont nommées de la même manière que les méthodes publiques des classes métiers.

Les méthodes privées

Les méthodes privées sont nommées de la même manière que les méthodes privées des classes métiers.

## Exemple d'objet métier

```php

<?php

   

    namespace src\classMetier\ClassMetierCra\ClassMetierManagementCra;

   

    use processid\traits\Hydrate;

    class ObjMetierCraProjetsStatus {

   

        use Hydrate;

       

        private $IDcra_projets;

        private int $status;

        private int $timestamp_validation;

        private string $intitule;

   

        /**

         * @param array $data

         */

        public function __construct(array $data) {

            $this->hydrate($data);

        }

   

        /**

         * @return mixed

         */

        public function getIDcraProjets() {

            return $this->IDcra_projets;

        }

   

        /**

         * @param mixed $IDcra_projets

         */

        public function setIDcraProjets($IDcra_projets): void {

            $this->IDcra_projets = $IDcra_projets;

        }

   

        /**

         * @return int

         */

        public function getStatus(): int {

            return $this->status;

        }

   

        /**

         * @param int $status

         */

        public function setStatus(int $status): void {

            $this->status = $status;

        }

   

        /**

         * @return int

         */

        public function getTimestampValidation(): int {

            return $this->timestamp_validation;

        }

   

        /**

         * @param int $timestamp_validation

         */

        public function setTimestampValidation(int $timestamp_validation): void {

            $this->timestamp_validation = $timestamp_validation;

        }

   

        /**

         * @return string

         */

        public function getIntitule(): string {

            return $this->intitule;

        }

   

        /**

         * @param string $intitule

         */

        public function setIntitule(string $intitule): void {

            $this->intitule = $intitule;

        }

   

    }

```

Etapes du portage vers les classes métier

Développer méthode par méthode :