Je suis curieux de savoir quels sont les inconvénients de l'utilisation du modèle ActiveRecord pour l'accès aux données / les objets métier. La seule à laquelle je peux penser du haut de ma tête est qu'elle viole le principe de responsabilité unique, mais le modèle de RA est assez commun pour que cette raison seule ne semble pas "assez bonne" pour justifier de ne pas l'utiliser (bien sûr, mon La vue peut être biaisée car souvent aucun du code avec lequel je travaille ne suit les principes SOLID).
Personnellement, je ne suis pas un fan d'ActiveRecord (à l'exception de l'écriture d'une application Ruby on Rails, où AR semble "naturel"), car on a l'impression que la classe en fait trop, et l'accès aux données ne devrait pas être réservé à la classe elle-même gérer. Je préfère utiliser des référentiels qui renvoient des objets métier. La plupart du code avec lequel je travaille a tendance à utiliser une variante d'ActiveRecord, sous la forme (je ne sais pas pourquoi la méthode est booléenne):
public class Foo
{
// properties...
public Foo(int fooID)
{
this.fooID = fooID;
}
public bool Load()
{
// DB stuff here...
// map DataReader to properties...
bool returnCode = false;
if (dr.HasRows)
returnCode = true;
return returnCode;
}
}
ou parfois la manière la plus "traditionnelle" d'avoir une public static Foo FindFooByID(int fooID)
méthode pour les chercheurs et quelque chose dans le sens de la public void Save()
sauvegarde / mise à jour.
J'obtiens qu'ActiveRecord est généralement beaucoup plus simple à implémenter et à utiliser, mais cela semble un peu trop simple pour les applications complexes et vous pourriez avoir une architecture plus robuste en encapsulant votre logique d'accès aux données dans un référentiel (sans parler d'avoir plus facile à échanger) stratégies d'accès aux données, par exemple, vous utilisez peut-être des processus stockés + des ensembles de données et souhaitez passer à LINQ ou quelque chose du genre)
Quels sont donc les autres inconvénients de ce modèle qui doivent être pris en compte pour décider si ActiveRecord est le meilleur candidat pour le travail?
la source
Le plus grand inconvénient de l'enregistrement actif est que votre domaine est généralement étroitement lié à un mécanisme de persistance particulier. Si ce mécanisme nécessite un changement global, peut-être d'une persistance basée sur des fichiers à une persistance basée sur une base de données, ou entre des infrastructures d'accès aux données, CHAQUE classe qui implémente ce modèle peut changer. Selon le langage, le cadre et la conception, même quelque chose d'aussi simple que de changer l'emplacement de la base de données ou à qui "appartient", il peut nécessiter de parcourir chaque objet pour mettre à jour les méthodes d'accès aux données (ce qui est rare dans la plupart des langues qui offrent un accès facile pour configurer des fichiers avec des chaînes de connexion).
Cela vous oblige également généralement à vous répéter. La plupart des mécanismes de persistance ont beaucoup de code commun, pour se connecter à une base de données et démarrer une transaction. DRY (Don't Repeat Yourself) vous dirait en tant que codeur de centraliser une telle logique.
Cela rend également les opérations atomiques délicates. Si un groupe d'objets doit être enregistré de manière tout ou rien (comme une facture et ses lignes de facture et / ou entrées client et / ou GL), l'un ou l'autre objet doit connaître tous ces autres objets et contrôler leur persistance ( qui étend la portée de l'objet de contrôle; les grands enregistrements interconnectés peuvent facilement devenir des "objets divins" qui savent tout de leurs dépendances), ou le contrôle de la transaction entière doit être géré de l'extérieur du domaine (et dans ce cas, pourquoi utilisez-vous AR?)
C'est également "faux" d'un point de vue orienté objet. Dans le monde réel, une facture ne sait pas comment se déposer, alors pourquoi un objet de code facture sait-il comment se sauvegarder dans la base de données? Bien sûr, une adhésion trop religieuse aux «objets ne devrait modéliser que ce que leurs homologues du monde réel peuvent faire» conduirait à des modèles de domaine anémique (une facture ne sait pas non plus comment calculer son propre total, mais divise le calcul de ce total en un autre objet est généralement considéré comme une mauvaise idée).
la source
L'inconvénient de base est qu'il rend votre modèle de domaine complexe car il contient non seulement la logique métier mais également des informations de persistance.
La solution consiste donc à utiliser l' implémentation Data Mapper d'ORM. Cela sépare la couche de persistance et nous sommes désormais plus centrés sur la logique métier de l'entité. La doctrine est Data Mapper ORM.
Mais cette approche présente également une certaine complexité. Pour les requêtes, vous dépendez maintenant trop de Data Mapper, ce qui rend l'environnement orienté requêtes. Pour le simplifier, une autre couche est introduite entre le modèle de domaine et le mappeur de données est appelé référentiel .
Le référentiel résume la couche de persistance. Cela donne l'impression d'une programmation orientée objet dans le sens, c'est une collection de tous les objets de même type (comme toutes les entités stockées dans la table de base de données) et vous pouvez effectuer des opérations sur eux comme opération de collecte, ajouter , supprimer . contient etc.
Par exemple, pour l'entité utilisateur , il y aura UserRepository qui représente la collection du même type d'objets utilisateur (celui stocké dans la table des utilisateurs) sur lequel vous pouvez effectuer l'opération. Pour interroger la table des utilisateurs, il utilise le mappeur de données utilisateur, mais il a été extrait du modèle de domaine Utilisateur .
Le modèle de référentiel est le type de couche d'accès aux données , un autre est les différences d' objet d'accès aux données uniquement Le référentiel a une fonction racine agrégée
la source