Y a-t-il de bonnes raisons de ne pas utiliser un ORM? [fermé]
Pendant mon apprentissage, j'ai utilisé NHibernate pour des projets plus petits que j'ai principalement codés et conçus par moi-même. Maintenant, avant de commencer un projet plus important, la discussion a surgi comment concevoir l'accès aux données et si oui ou non utiliser une couche ORM. Comme je suis encore dans mon apprentissage et que je me considère toujours comme un débutant en programmation d'entreprise, je n'ai pas vraiment essayé de pousser à mon avis, qui est que l'utilisation d'un mappeur relationnel d'objet à la base de données peut faciliter le développement beaucoup. Les autres codeurs dans l'équipe de développement sont beaucoup plus expérimentés que moi, donc je pense que je vais juste faire ce qu'ils disent. :-)
Cependant, je ne comprends pas complètement deux des principales raisons de ne pas utiliser NHibernate ou un projet similaire:
- on peut simplement créer ses propres objets d'accès aux données avec des requêtes SQL et copier ces requêtes depuis Microsoft SQL Server Management Studio.
- le débogage D'un ORM peut être difficile.
Donc, bien sûr, je pourrais juste construire ma couche d'accès aux données avec beaucoup de SELECT
s etc, mais ici je manque l'avantage des jointures automatiques, des classes de proxy de chargement paresseux et un effort de maintenance inférieur si une table obtient une nouvelle colonne ou une colonne est renommée. (Mise à jour de nombreux SELECT
, INSERT
et UPDATE
requêtes vs. mise à jour de la configuration de mappage et éventuellement refactoring des classes métier et des Dto.)
En outre, en utilisant NHibernate, vous pouvez rencontrer des problèmes imprévus si vous ne connaissez pas très bien le framework. Qui pourrait être, par exemple, faire confiance à la Table.hbm.xml où vous définissez la longueur d'une chaîne à valider automatiquement. Cependant, je peux aussi imaginer des bugs similaires dans une couche D'accès aux données basée sur une requête SqlConnection "simple".
Enfin, ces arguments mentionnés ci-dessus sont-ils vraiment une bonne raison de ne pas utiliser un ORM pour une application d'entreprise basée sur une base de données non triviale? Y a-t-il probablement d'autres arguments qu'ILS/je pourrais avoir manqués?
(je devrais probablement ajouter que je pense que c'est comme le premier" gros". Net/C# basé application qui nécessitera un travail d'équipe. Les bonnes pratiques, qui sont considérées comme assez normales sur le débordement de pile, telles que les tests unitaires ou l'intégration continue, n'existent pas jusqu'à présent.)
10 réponses
Il y a eu une explosion de croissance avec les ORM ces dernières années et vos collègues plus expérimentés peuvent encore penser à la mentalité "chaque appel de base de données devrait être via une procédure stockée".
Pourquoi un ORM rendrait-il les choses plus difficiles à déboguer? Vous obtiendrez le même résultat, qu'il provienne d'un proc stocké ou de L'ORM.
Je suppose que le seul inconvénient réel auquel je peux penser avec un ORM est que le modèle de sécurité est un peu moins flexible.
Modifier: Je viens de relire votre question et il semble qu'ils copient et collent les requêtes dans sql en ligne. Cela rend le modèle de sécurité identique à un ORM, donc il n'y aurait absolument aucun avantage sur cette approche par rapport à un ORM. S'ils utilisent des requêtes non paramétrées, ce serait en fait un risque de sécurité.
La réponse courte est oui, il y a vraiment de bonnes raisons. En fait, il y a des cas où vous ne pouvez pas utiliser un ORM.
Par exemple, je travaille pour une grande institution financière d'entreprise et nous devons suivre beaucoup de directives de sécurité. Pour respecter les règles et règlements qui nous sont imposés, la seule façon de passer des audits est de garder l'accès aux données dans les procédures stockées. Maintenant, certains peuvent dire que c'est tout simplement stupide, mais honnêtement ce n'est pas le cas. outil / développeur peut insérer, sélectionner, Mettre à jour ou supprimer tout ce qu'il ou elle veut. Les procédures stockées offrent beaucoup plus de sécurité, en particulier dans les environnements traitant des données client. Je pense que c'est la plus grande raison de considérer. Sécurité.
Le sweet spot de l'Orm
Les ORM sont utiles pour automatiser les 95%+ de requêtes lorsqu'elles sont applicables. Leur force particulière est l'endroit où vous avez une application avec une architecture de modèle d'objet forte et une base de données qui joue bien avec ce modèle d'objet. Si vous faites une nouvelle construction et que vous avez de solides compétences en modélisation dans votre équipe, vous obtiendrez probablement de bons résultats avec un ORM.
Vous pourriez bien avoir une poignée de requêtes qui sont mieux faites à la main. Dans ce cas, n'ayez pas peur d'écrire quelques procédures stockées pour gérer cela. Même si vous avez l'intention de porter votre application sur plusieurs plates-formes de SGBD, le code dépendant de la base de données sera minoritaire. Gardant à l'esprit que vous devrez tester votre application sur n'importe quelle plate-forme sur laquelle vous avez l'intention de la soutenir, un peu d'effort de portage supplémentaire pour certaines procédures stockées ne fera pas beaucoup de différence pour votre TCO. Pour une première approximation, 98% portable est 100% portable, et beaucoup mieux que des solutions alambiquées ou mal performantes pour contourner les limites d'un ORM.
J'ai vu l'ancienne approche fonctionner bien sur un très grand projet J2EE (100 ans de personnel).
Où un ORM peut ne pas être le meilleur ajustement
Dans d'autres cas, il peut y avoir des approches qui conviennent mieux à l'application qu'un ORM. Les Modèles de Fowler d'architecture D'Application D'entreprise ont une section sur les modèles d'accès aux données qui bon travail de catalogage diverses approches à ce sujet. Quelques exemples que j'ai vus de situations où un ORM peut ne pas être applicable sont:
Sur une application avec une base de code héritée substantielle de procédures stockées, vous pouvez utiliser une couche d'accès aux données orientée fonctionnellement (à ne pas confondre avec les langages fonctionnels) pour envelopper les sprocs titulaires. Cela réutilise la couche d'accès aux données et la conception de base de données existantes (et donc testées et déboguées), qui représentent souvent un effort de développement et de test assez important, et permet d'économiser sur la migration des données vers un nouveau modèle de base de données. C'est souvent un bon moyen d'envelopper les couches Java autour des bases de code PL/SQL héritées, ou de re-cibler les applications VB, Powerbuilder ou Delphi avec des interfaces web.
Une variation est l'endroit où vous héritez d'un modèle de données qui n'est pas nécessairement bien adapté au mappage O-R. Si (par exemple) vous écrivez une interface qui remplit ou extrait des données interface vous pouvez être mieux de travailler directement avec la base de données.
Applications financières ou autres types de systèmes pour lesquels l'intégrité des données entre systèmes est importante, en particulier si vous utilisez des transactions distribuées Complexes avec validation en deux phases. Vous devrez peut-être microgérer vos transactions mieux qu'un ORM est capable de supporter.
Applications hautes performances où vous voulez vraiment régler votre accès à la base de données. Dans ce cas, il peut être préférable de travailler à un niveau inférieur.
Situations où vous utilisez un mécanisme d'accès aux données titulaire comme ADO.Net c'est "assez bon" et jouer bien avec la plate-forme est d'un plus grand avantage que L'ORM apporte.
Parfois, les données ne sont que des données - il peut arriver (par exemple) que votre application fonctionne avec des 'transactions' plutôt que des 'objets' et qu'il s'agisse d'une vue sensée du domaine. Un exemple de ceci pourrait être un paquet financier où vous avez des transactions avec des champs d'analyse configurables. Bien que l'application elle - même puisse être construite sur une plate-forme O-O, elle n'est pas liée à un seul modèle de domaine d'activité et peut ne pas connaître beaucoup plus que les codes GL, les comptes, les types de documents et une demi-douzaine de champs d'analyse. Dans ce cas, l'application n'est pas au courant d'un modèle de domaine métier en tant que tel et un modèle objet (au-delà de la structure du grand livre elle-même) n'est pas pertinent pour l'application.
Tout d'abord, l'utilisation d'un ORM ne rendra pas votre code plus facile à tester, et ne fournira pas nécessairement d'avantages dans un scenerio D'Intégration Continue.
Dans mon expérience, alors que l'utilisation D'un ORM peut augmenter la vitesse de développement, les plus gros problèmes que vous devez résoudre sont:
- tester votre code
- maintenir votre code
Les solutions à celles-ci sont:
- Faites tester votre code (en utilisant les principesSOLID )
- écrire tests automatisés pour autant de code que possible
- exécutez les tests automatisés aussi souvent que possible
En ce qui concerne votre question, les deux objections que vous énumérez ressemblent plus à de l'ignorance qu'à toute autre chose.
Ne pas être capable d'écrire des requêtes SELECT à la main (ce qui, je suppose, explique pourquoi le copier-coller est nécessaire) semble indiquer qu'il y a un besoin urgent de formation SQL.
Il y a deux raisons pour lesquelles je n'utiliserais pas un ORM:
- il est strictement interdit par la Politique de l'entreprise (auquel cas j'irais travailler ailleurs)
- le projet est extrêmement gourmand en données et l'utilisation de solutions spécifiques au fournisseur (comme BulkInsert) a plus de sens.
Les rebuffades habituelles sur les ORM (NHibernate en particulier) sont:
-
Vitesse
Il n'y a aucune raison pour que l'utilisation d'un ORM soit plus lente que l'accès aux données codées à la main. En fait, en raison de la mise en cache et des optimisations intégrées, cela peut être plus rapide. Un bon ORM produira un ensemble reproductible de requêtes pour lesquelles vous pouvez optimiser votre schéma. Un bon ORM permettra également une récupération efficace des données associées en utilisant diverses stratégies de récupération.
-
Complexité
En ce qui concerne la complexité, l'utilisation D'un ORM signifie moins de code, ce qui signifie généralement moins de complexité. De nombreuses personnes utilisant un accès aux données écrit à la main (ou généré par code) se retrouvent à écrire leur propre framework sur des bibliothèques d'accès aux données "de bas niveau" (comme l'écriture méthodes d'aide pour ADO.Net). ceux-ci équivalent à plus de complexité, et, pire encore, ils sont rarement bien documentés, ou bien testés.
Si vous regardez spécifiquement NHibernate, alors des outils comme Fluent NHibernate et Linq à NHibernate adoucissent également la courbe d'apprentissage.
La chose qui me préoccupe de tout le débat ORM est que les mêmes personnes qui prétendent que l'utilisation D'un ORM sera trop difficile / lente / quelles que soient les mêmes personnes qui sont plus qu'heureuses d'utiliser Linq en Sql ou Typés. Alors que le Linq à Sql est un grand pas dans la bonne direction, il est encore des années-lumière derrière certains des ORM open source sont. Cependant, les frameworks pour les jeux de données typés et pour Linq to Sql sont encore extrêmement complexes, et les utiliser pour aller trop loin de la (Table=Class) + (Basic CRUD) est bêtement difficile.
Mon conseil est que si, à la fin de la journée, vous ne pouvez pas obtenir un ORM, alors assurez-vous que votre accès aux données est séparée du reste du code, et que vous vous suivez le Conseil de la bande des quatre de codage à une interface. En outre, obtenez un cadre D'Injection de dépendance pour faire le câblage.
(Comment est-ce pour une diatribe?)
Il existe un large éventail de problèmes courants pour lesquels les outils ORM comme Hibernate sont un god-send, et quelques-uns où c'est un obstacle. Je ne connais pas assez votre projet pour savoir de qui il s'agit.
L'un des points forts D'Hibernate est que vous ne pouvez dire les choses que 3 fois: chaque propriété est mentionnée dans la classe, la.hbm.fichier xml, et la base de données. Avec les requêtes SQL, vos propriétés se trouvent dans la classe, la base de données, les instructions select, les instructions insert, les instructions update, les instructions delete, et tout le code de marshalling et unmarshalling supportant vos requêtes SQL! Cela peut devenir désordonné rapidement. D'autre part, vous savez comment cela fonctionne. Vous pouvez le déboguer. Tout va bien là dans votre propre couche de persistance, pas enterré dans les entrailles d'un outil de 3ème partie.
Hibernate pourrait être un enfant d'affiche pour la Loi de Spolsky des Abstractions qui fuient. Obtenez un peu hors des sentiers battus, et vous devez connaître le fonctionnement interne profond de l'outil. Il peut être très ennuyeux quand vous sachez que vous auriez pu corriger le SQL en quelques minutes, mais vous passez des heures à essayer de cajoler votre outil dang en générant un SQL raisonnable. Le débogage est parfois un cauchemar, mais il est difficile de convaincre les gens qui n'y sont pas allés.
EDIT: vous voudrez peut-être regarder dans iBatis.NET s'ils ne vont pas être retournés à propos de NHibernate et qu'ils veulent contrôler leurs requêtes SQL.
EDIT 2: Voici le grand drapeau rouge, cependant: "les bonnes pratiques, qui sont considérées comme jolies les débordements normaux sur la pile, tels que les tests unitaires ou l'intégration continue, n'existent pas jusqu'à présent."Alors, ces développeurs "expérimentés", que sont-ils expérimentés dans le développement? La sécurité de leur emploi? Il semble que vous pourriez être parmi les gens qui ne sont pas particulièrement intéressés par le domaine, alors ne les laissez pas tuer votre intérêt. Vous devez être l'équilibre. Mettre en place un combat.
J'ai travaillé sur un projet où ne pas utiliser un ORM a été très réussi. C'était un projet qui
- devait être horizontalement scalealbe dès le début
- A dû être développé rapidement
- avait un modèle de domaine relativement simple
Le temps qu'il aurait fallu pour que NHibernate fonctionne dans une structure partitionnée horizontalement aurait été beaucoup plus long que le temps qu'il a fallu pour développer un datamapper super simple qui était conscient de notre partitionnement régime...
Donc, dans 90% des projets sur lesquels j'ai travaillé, un ORM a été d'une aide inestimable. Mais il y a des circonstances très spécifiques où je peux voir ne pas utiliser un ORM comme étant le meilleur.
Permettez-moi d'abord de dire que les ORM peuvent faciliter votre développement s'ils sont correctement intégrés, mais il y a une poignée de problèmes où L'ORM peut réellement vous empêcher d'atteindre vos exigences et objectifs énoncés.
J'ai constaté que lors de la conception de systèmes qui ont de lourdes exigences de performance, je suis souvent mis au défi de trouver des moyens de rendre le système plus performant. Plusieurs fois, je me retrouve avec une solution qui a un profil de performance d'écriture lourd (ce qui signifie que nous écrivons données beaucoup plus que nous lisons des données). Dans ces cas, je veux profiter des facilités que la plate-forme de base de données m'offre afin d'atteindre nos objectifs de performance (C'est OLTP, pas OLAP). Donc, si J'utilise SQL Server et que je sais que j'ai beaucoup de données à écrire, pourquoi ne pas utiliser un insert en vrac... Eh bien, comme vous l'avez peut-être déjà découvert, la plupart des ORM (Je ne sais pas si même un seul le fait) n'ont pas la capacité de profiter des avantages spécifiques à la plate-forme comme le vrac insérer.
Vous devez savoir que vous pouvez mélanger les techniques ORM et non-ORM. Je viens de trouver qu'il ya une poignée de cas de bord où ORM ne peuvent pas soutenir vos besoins et vous devez travailler autour d'eux pour ces cas.
Pour une application d'entreprise basée sur une base de données non triviale, il n'y a vraiment aucune justification ne pas utiliser un ORM.
Caractéristiques de côté:
- en n'utilisant pas un ORM, vous résolvez un problème qui a déjà résolu à plusieurs reprises par de grandes communautés ou entreprises avec des ressources.
- en utilisant un ORM, le noyau de votre couche d'accès aux données bénéficie des efforts de débogage de cette communauté ou entreprise.
Pour mettre un peu de perspective dans l'argument, considérez les avantages de l'utilisation ADO.NET vs. écrire le code pour analyser le flux de données tabulaire soi-même.
J'ai vu l'ignorance de la façon d'utiliser un ORM justifier le dédain d'un développeur pour les ORM par exemple: chargement impatient (quelque chose que j'ai remarqué que vous n'avez pas mentionné). Imaginez que vous voulez récupérer un client et toutes leurs commandes, et pour ceux tous les éléments de détail de la commande. Si vous comptez uniquement sur le chargement paresseux, vous vous éloignerez de votre expérience ORM avec l'opinion: "les ORM sont lents." Si vous apprenez à utiliser le chargement impatient, vous ferez en 2 minutes avec 5 lignes de code, ce que vos collègues prendront une demi-journée à mettre en œuvre: une requête à la base de données et lier les résultats à une hiérarchie d'objets. Un autre exemple serait la douleur d'écrire manuellement des requêtes SQL pour implémenter la pagination.
L'exception possible à l'utilisation D'un ORM serait si cette application était un framework ORM conçu pour appliquer des abstractions de logique métier spécialisées, et conçu pour être réutilisé sur de multiples projets. Même si tel était le cas, cependant, vous obtiendriez une adoption plus rapide en améliorant un ORM existant avec ces abstractions.
Ne laissez pas l'expérience des membres de votre équipe senior vous entraîner dans la direction opposée à l'évolution de l'informatique. Je me développe professionnellement depuis 23 ans, et l'une des constantes est le mépris pour le nouveau par la vieille école. Les ORM sont à SQL comme le langage C était à assembly, et vous pouvez parier que les équivalents à C++ et C# sont sur leur chemin. Une ligne de code de la nouvelle école équivaut à 20 lignes de la vieille école.
Lorsque vous devez mettre à jour 50000000 enregistrements. Définissez un drapeau ou autre.
Essayez de le faire en utilisant un ORM Sans appeler une procédure stockée ou des commandes SQL natives..
Update 1: Essayez également de récupérer un enregistrement avec seulement quelques-uns de ses champs. (Lorsque vous avez une table très "large"). Ou un résultat scalaire. ORMs sucent à cela aussi.
UPDATE 2 : il semble que EF 5.0 Beta promet des mises à jour par lots, mais c'est une nouvelle très chaude (2012, janvier)
Je pense que peut-être que lorsque vous travaillez sur des systèmes plus gros, vous pouvez utiliser un outil de générateur de code comme CodeSmith au lieu d'un ORM... J'ai récemment trouvé ceci: Cooperator Framework {[2] } qui génère des procédures stockées SQL Server et génère également vos entités commerciales, mappeurs, passerelles, lazyload et tout ce genre de choses en C#...regarde out...it a été écrit par une équipe ici en Argentine...
Je pense qu'il est au milieu entre le codage de toute la couche d'accès aux données et l'utilisation d'un ORM...