Sortes d'objets
Aux fins de notre discussion, séparons nos objets en trois types différents:
Ce sont les objets qui font le travail. Ils transfèrent de l'argent d'un compte courant à un autre, exécutent les commandes et toutes les autres actions que nous attendons des logiciels d'entreprise.
Les objets logiques de domaine ne nécessitent normalement pas d'accesseurs (getters et setters). Au lieu de cela, vous créez l'objet en lui passant des dépendances via un constructeur, puis vous manipulez l'objet à l'aide de méthodes (dites, ne demandez pas).
Les objets de transfert de données sont à l'état pur; ils ne contiennent aucune logique métier. Ils auront toujours des accesseurs. Ils peuvent ou non avoir des setters, selon que vous les écrivez de manière immuable ou non . Vous définirez vos champs dans le constructeur et leurs valeurs ne changeront pas pendant la durée de vie de l'objet, ou vos accesseurs seront en lecture / écriture. En pratique, ces objets sont généralement modifiables, de sorte qu'un utilisateur peut les modifier.
Les objets du modèle de vue contiennent une représentation de données affichable / modifiable. Ils peuvent contenir une logique métier, généralement limitée à la validation des données. Un exemple d'un objet View Model peut être un InvoiceViewModel, contenant un objet Customer, un objet En-tête de facture et des éléments de ligne de facture. Les objets View Model contiennent toujours des accesseurs.
Ainsi, le seul type d'objet qui sera "pur" dans le sens où il ne contient pas d'accesseurs de champ sera l'objet Logique de domaine. La sérialisation d'un tel objet enregistre son "état de calcul" actuel, de sorte qu'il peut être récupéré plus tard pour terminer le traitement. Les modèles de vue et les DTO peuvent être librement sérialisés, mais dans la pratique, leurs données sont normalement enregistrées dans une base de données.
Sérialisation, dépendances et couplage
S'il est vrai que la sérialisation crée des dépendances, dans le sens où vous devez désérialiser vers un objet compatible, il ne s'ensuit pas nécessairement que vous devez changer votre configuration de sérialisation. De bons mécanismes de sérialisation sont d'usage général; ils ne se soucient pas si vous changez le nom d'une propriété ou d'un membre, tant qu'il peut toujours mapper des valeurs aux membres. En pratique, cela signifie uniquement que vous devez re-sérialiser l'instance d'objet pour rendre la représentation de sérialisation (xml, json, peu importe) compatible avec votre nouvel objet; aucune modification de configuration du sérialiseur ne devrait être nécessaire.
Il est vrai que les objets ne doivent pas se préoccuper de la façon dont ils sont sérialisés. Vous avez déjà décrit une manière de dissocier ces préoccupations des classes de domaine: la réflexion. Mais le sérialiseur doit se préoccuper de la façon dont il sérialise et désérialise les objets; c'est, après tout, sa fonction. La façon dont vous gardez vos objets découplés de votre processus de sérialisation est de faire de la sérialisation une fonction polyvalente , capable de fonctionner sur tous les types d'objets.
Une des choses qui rend les gens confus, c'est que le découplage doit se produire dans les deux sens. Ce ne est pas; il ne doit fonctionner que dans une seule direction. En pratique, vous ne pouvez jamais découpler complètement; il y a toujours un couplage. Le but du couplage lâche est de faciliter la maintenance du code, et non de supprimer toutes les dépendances.