Conception objet simple et dépendances

muqaddarmuqaddar Administrateur
Je me pose souvent des questions sur la conception objets des modèles de mes applications, et j'ai souvent des doutes.
Pas sur le MVC, mais sur les modèles eux-mêmes.

Imaginons une classe Entreprise et une classe Employé. (c'est très original, merci  :P)
Chacune de ses classes sauvegarde ses propres données par défaut.

Méthode 1:
La classe Entreprise gère directement les employés, elle a donc une ivar NSMutableArray *_employees.
C'est elle qui sauvegarde ses données et qui lance aussi la sauvegarde des employés présents dans l'array, en appelant la classe Employee. Après tout, c'est logique qu'elle gère ses dépendances, c-a-d les modèles associés. En cas de suppression, elle aura aussi pour rôle de supprimer les enfants (les employés).

Méthode 2:
On crée une classe modèle supplémentaire, appelons la Reference.
Cette classe a une ivar sur le modèle Entreprise et une autre ivar NSMutableArray *_employees.

A cette classe on demande de créer tous les objets dépendants.
Losque l'on sauvegarde, on fait par exemple [Reference save], ce qui va appeler la sauvegarde de Entreprise PUIS des employees dépendants présents dans l'array.

Cette solution me paraà®t plus flexible pour gérer les dépendances, MAIS n'est-ce-pas illogique que l'array Employees ne soit plus attaché à  Entreprise directement mais à  la référence (qui s'occupe de lier les 2 via ses méthodes de CRUD) ?

Ce qu'il faut voir aussi, c'est avoir le plus de flexibilité pour la sauvegarde et la destruction des employees. Surtout lorsque l'on crée un nouvel objet Entreprise, qui n'a pas encore d'id, et à  qui on commence par remplir l'array des employees (donc qui ne sont pas encore attachés en base, mais qui le seront lors de la sauvegarde de Entreprise).

J'ai déjà  essayé les 2 solutions (les 2 marchent) mais quelle est la règle de l'art ?

J'étais parti du principe que chaque classe Entreprise ou Employee ne devait sauvegarder QUE ses données et pas appeler des sauvegardes sur les enfants, que c'était le rôle de la classe Reference supplémentaire de faire la sauvegarde de Entreprise puis en cas de succès, des employees saisis dans l'array. Est-ce une erreur ? Quelle est la règle absolue ?

Réponses

  • AliGatorAliGator Membre, Modérateur
    12:18 modifié #2
    La règle est la méthode 1.

    Utiliser la méthode 2 nécessite une connaissance externe du modèle, c'est à  dire que Reference doit connaà®tre tout le modèle, et surtout toutes les relations entre les objets. Cela va à  l'encontre du principe d'encapsulation.

    Allons plus loin dans ton exemple. Ta classe Entreprise contient non pas des employés, mais des Agences. Chaque Agence contient des Services. Chaque Service contient des Employés.
    Ou encore part d'un autre exemple, une classe Voiture, qui contient un Moteur, 4 Roues, un TableauDeBord. le Moteur lui est composé de Pistons, de Bougies, etc. Le TableauDeBord un ModuleGPS, un Tachymètre, un CompteTours, une JaugeEssence.

    Avec ta méthode 2, la Référence a besoin de connaà®tre tous les liens entre tous les objets, de connaà®tre ton modèle dans sa totalité. Si tu changes une sous-partie du modèle, par exemple le TableauDeBord contient finalement un sous module InfoConduite qui lui contient le Tachymètre, le COmpteTours et le ModuleGPS, et un autre module InfoMoteur avec JaugeEssence, NiveauHuile, etc. du coup tu vas être obligé de tout changer dans ta classe Reference, pour lui faire connaà®tre toutes les nouvelles relations entre les parties.

    La méthode 1 a le mérite de respecter le principe d'encapsulation. Chaque module ne connaà®t que ses composants, et n'a pas besoin de savoir la composition desdits composants, en gros il connait ses éléments enfants, mais n'a pas besoin de connaà®tre la composition interne de ses petits enfants.
  • muqaddarmuqaddar Administrateur
    12:18 modifié #3
    OK. Tu m'as convaincu vis-à -vis de la logique et de la maintenance.
    Oui, c'est vrai que Reference avait besoin de connaà®tre tous les modèles.

    Venant de Ruby on Rails, j'avais l'habitude que mes classes modèles (qui correspondent donc chacune à  une table) ne fassent que de l'initialisation de champs, leur sauvegarde et éventuellement quelques méthodes de classe utilitaires. Mais, en y pensant, Rails a une "boà®te noire" qui gère les dépendances... depuis les modèles directement.

    Je vais donc ajouter des properties à  ma classe Entreprise (NSMutableArray d'agences, de salariés, un objet patron...etc) et bien entendu un constructeur en plus qui initialize ces dépendances, car pour l'instant, je n'avais que des constructeurs qui initializent les champs du modèle lui-même, et pas les enfants (puisqu'ils étaient gérés par Reference).

    Merci à  toi.
Connectez-vous ou Inscrivez-vous pour répondre.