J'ai lu beaucoup de livres sur la conception de logiciels, et plus encore et plus, je me demande si ce que j'ai appris que la séparation des préoccupations entre l'objet métier et la sérialisation me rend plus productif. P>
Je suis influencé par design dirigé sur le domaine, alors quand je concevons mes cours d'affaires, je ne pense pas à la persistance. Les seuls objets qui sont couplés à ma technologie de base de données / technologie de service Web / la mise en cache sont encapsulés derrière un référentiel avec une interface de domaine agréable. P>
Pour illustrer, pour une base de données d'applications traditionnelle <-> Service Web <-> RIA, je concevons mon compte de classe affaires et mes employés. Ensuite, si je souhaite obtenir des comptes à partir d'une source de données, je crée un iacCountrePository et implémentez des méthodes pour interroger ou ajouter des comptes à ma source de données. P>
Ajouter une capacité de mise en cache à mon application, ce n'est qu'une question de création d'une classe de proxy qui implémente iaccountrepository et enveloppe le référentiel réel, puis l'injection dans mon conteneur IOC. P>
Pour mettre en place un référentiel de base de données, j'utilise un orj qui crée des classes à partir de mon schéma de base de données, puis j'utilise Créer un traducteur pour transformer les cours de base de données vers / depuis les classes de Business, de cette façon, mes classes d'affaires sont découplées de mon schéma de base de données. < / p>
Je crée également des classes de contrat de données dédiées pour mes services Web, puis le service Web utilise des traducteurs pour transformer une agrégation d'objets métier vers sa représentation de données du point de vue du service Web. P>
Lorsque je crée mon application RIA, je concevez à nouveau son propre modèle de domaine, mais cette fois, l'implémentation du référentiel utilise un service Web au lieu de la base de données (et des traducteurs). P>
Pour les développeurs WPF, je crée alors ma viewModel et ma vue. P>
Je programmais comme ça. P>
Mais, quand mon patron vient et dit: Pouvez-vous ajouter un champ à ce formulaire à ... bla bla bla bla em> je dois: p>
Je pense de plus en plus de penser à coupler mon objet métier avec la technologie d'accès à la base de données et la technologie de service Web ou la technologie de sérialisation. P>
De cette façon, je n'ai plus besoin de maintenir mes traducteurs.
Par exemple, pourquoi ne pas utiliser d'attributs / annotations de ces technologies sur les objets métier? Oui, il apporte des contrefaits, oui, j'aurai besoin d'un get / placé sur mes champs, même si je veux que ma propriété soit réadonnée, oui mon module d'entreprise aura des dépendances externes.
Mais je pense que cela entraînera moins de code et un système plus maintenu. P>
La mise en œuvre de mes référentiels sera triviale et ne s'appuiera pas sur des traducteurs. P>
Bien que je vois des avantages de coder de cette façon, je me sens toujours coupable de coder comme ça. Je me sens vraiment coupable de l'ajout de 5 attributs / annotations associés à ma technologie de technologie d'accès à la technologie / technologie de service Web / technologie de sérialisation sur mes objets métier et je pense que ce n'est pas correct. P>
Pourquoi ma séparation des préoccupations de la base de données / des objets d'affaires / service Web me fait écrire plus de code? P>
Avez-vous des alternatives? P>
9 Réponses :
Votre productivité personnelle n'est pas le point. P>
Le point de séparation des préoccupations consiste à augmenter la valeur Je suis désolé si cela vous fait écrire plus de code, mais votre temps est typiquement une infime fraction du coût de la vie d'utilisation, de maintenir et d'adapter ce que vous écrivez. P>
La séparation des préoccupations est essentiellement pour maintenir le coût total de la propriété totale de la vie. Il a peu à voir avec votre productivité personnelle. P>
Si votre patron vous demande un changement omniprésent ... Eh bien ... c'est omniprésent. Je suis désolé que ce soit omniprésent. P>
edit 1 fort> p>
La valeur "Est-ce la pureté / la beauté du code? Pour moi, la valeur est en simplicité et à la lisibilité." Ce n'est ni. C'est la valeur créée en appliquant le code aux problèmes du monde réel. P>
Si le code est difficile à maintenir, à adapter ou à utiliser, cela la dévalente. Si le code est facile à entretenir, d'adapter ou d'utiliser, il y a moins de barrières pour obtenir une valeur totale du code. P>
Votre temps Développer le code est un petit coût minuscule comparé à la valeur de l'utilisation. De plus, votre temps de développement est un coût réduit que de maintenir ou de s'adapter. P>
Le changement omniprésent est une conséquence inévitable de logiciels de construction. Rien - aucune pratique - peut empêcher votre patron de changer de changement qui enfreint votre architecture. P>
Si vous avez une couche, presque tout changement rompt cette couche. P>
Si vous avez 3 niveaux, 7 couches ou n + 1 couches, il est toujours possible pour votre patron de demander un changement qui casse plus d'une couche. p>
L'idée est que la plupart des changements sont isolés. Rien ne peut assurer que tous les changements sont isolés. P>
Intéressant, si un peu condescendant. Je penserais que la productivité personnelle d'un programmeur serait bien corréler avec la valeur de l'application. Sinon, pourquoi continuerions-nous à créer de nouvelles et meilleures langues de programmation? Pourquoi n'avons-nous pas juste collé avec Cobol? Le changement demandé par un patron va bien, mais si beaucoup de changements sont demandés régulièrement, peut-être un design plus agile et découplé est en ordre.
Nous ne nous en tenons pas avec COBOL, car la maintenance, l'adaptation et les coûts d'exploitation sont si élevés. De nouveaux outils de développement produisent généralement du code de "qualité" supérieure où la qualité signifie maintenir, adaptable et utilisable. Les coûts de développement sont une infime fraction de coût de cycle de vie.
Est une base de code maintenable si elle vous oblige à 1.Update ma base de données 2.Update ma base de données Traducteur de base de données 3.Update My Business Object Traducteur (serveur) 5.Aubliez mon service Web Translator (client) 6.UPDate Mon objet commercial (client) 7.Update My View 8.Pour WPF Adepts, Mettez à jour ma viewModel
S.Lott, je suis d'accord avec vous, mais le problème est, comme Robert compris, que vous suivez «les meilleures pratiques», mon code ne semble pas maintenir.
Qu'est-ce que cette valeur i> ?? Est-ce la pureté / la beauté du code? Pour moi, la valeur est en simplicité et à la lisibilité. Voir «Votre opinion la plus controversée»: Les meilleures pratiques devraient être «utiliser votre cerveau».
Il me lit comme ils ont mis en œuvre chaque couche d'abstraction qu'ils ont surveillé comme "pratique courante". Peut-être pour une bonne raison, si cette application est aussi complexe, fortement distribuée et active, comme l'aurait besoin. Mais alors la réponse serait évidente - la portée de confusion des couches serait intimidante. Les meilleures pratiques diffèrent notamment à l'échelle de l'application. Espérons que quelqu'un est autour qui peut relier l'histoire (et les raisons) il a accrété tous ces niveaux.
@Hasen, mon code est simple et lisible, mais certains changements comme celui que mon patron a dit onduler à travers toutes mes couches et devient un cauchemar d'entretien.
Il existe un compromis entre 8 changements simples dans une base de code hautement lisible et un changement difficile dans une base de code complexe, obtus, difficile à lire. Cela me semble que vous êtes dans l'ancienne position et non ce dernier. Cela ressemble également à ces changements peut être fabriqué en une demi-heure (y compris des tests d'unités pour vous assurer de ne rien briser). Est-ce vrai?
@Robert, ce n'est pas seulement l'heure (une demi-heure à ajouter un champ de formulaire est encore trop), mais la quantité de changement de contexte qui va dans votre cerveau. Si vous devez mettre à jour 8 couches pour chaque champ de formulaire, ce n'est pas amusant du tout. De mon expérience, c'est trop de stress (et je n'avais que 3 couches).
Une application maintenable est une application qui a un faible coût de maintenance. Si des changements courants prennent beaucoup de temps, ce n'est pas une application maintenable. P>
La question clé à poser est la manière dont les demandes de fonctionnalités courantes sont, contre des changements technologiques. p>
Si vous modifiez votre ensemble de technologies préférées tous les 3 mois environ, vous n'aurez jamais le temps de mettre en œuvre de nouvelles fonctionnalités. Votre architecture est donc optimale ... P>
J'ai aussi la même expérience, beaucoup de choses que j'ai apprises à l'école sur l'abstraction et la séparation de "substances" rend mon code en fait de plus en plus compliqué.
Je viens réaliser que, quand tu as de haut La cohésion (vos classes sont très petites et très au point), vous les em> ont un couplage élevé. En simplifiant chaque classe individuelle plus loin et en outre, chaque composant sera de plus en plus inutile en soi; Pour obtenir des fonctionnalités simples, vous devez gérer des interactions complexes entre ces objets simples "cohésives". P> Ensuite, des tâches simples seront compliquées !! Pensez à lire un fichier en Java, je ne me souviens pas comment le faire (je devais le faire plusieurs fois), et je ne veux plus jamais le refaire. P> en python Il est mort simple: p> Je ne dis pas que la séparation des préoccupations et des abstractions sont mauvaises, faites-les simplement. P> imo, c'est toujours mieux avec quelque chose qui "fonctionne simplement" même si c'est spaghetti, étant donné que vous faire em> refacteur. p> p>
Vous écrivez définitivement trop de code. L'ajout d'un seul champ ne doit pas être un processus de 8 étapes. P>
Pourquoi ne pas utiliser NHibernate? Vous pouvez avoir votre vrai modèle de domaine et le "traducteur de base de données" (maintenant) un simple exercice avec fluenteNibernate. P> li>
Il existe des framedeces très robustes pour la combinaison des étapes 4-6 de manière relativement transparente. WCF (l'horreur!) Pour un. P> Li> ol>
Oh, je ne connaissais pas fluentnhiberante, il ne semble pas polluer mon bo et la cartographie semble très facile à faire! Je vais jeter un coup d'oeil: D
+1 pour "écrire trop de code", -1 pour "Utiliser NHibernate". Donc, c'est un peu opté.
Je ne sais pas pourquoi vous feriez -1 pour utiliser NHibernate. C'est le meilleur orj à créer une application avec DDD. Peut-être que vous n'avez tout simplement pas assez de capacité à construire une application de cette façon.
Il s'agit de l'investissement initial. Le temps qu'il faut pour construire quelque chose de correctement sera toujours plus grand que le temps nécessaire pour construire quelque chose qui fonctionne simplement em>. Un emplacement à emporter important de DDD est que vous pouvez abstraire beaucoup de plomberie et la mettre dans un cadre de développement pouvant être réutilisé, de sorte que vous n'avez pas d'investissement initial sur d'autres projets. Vous pouvez abstraire les bases de votre référentiel, une unité de travail, un objet de domaine, etc. En outre, vous pouvez prendre la fonctionnalité réelle de la base de données et les mettre en œuvre en tant que fournisseur, de sorte que vous écrivez une fois et choisi le bon pour le travail la prochaine fois, ou si vous devez modifier le magasin de support pour votre objet de domaine. P>
Une solution qui a correctement traitée ses sépérations de préoccupation a des caractéristiques très productives - telles que cela étant très qualifiées, plus apte à être évolutive, plus réutilisable, plus facile à déboguer, plus facile à modifier et plus facile à prolonger. Être capable de voir comment le domaine traverse le code est une ruée totale et être capable de décrire un concept à un intervenant ou de les parcourir par le concept qu'un artefact de code est en cours d'exécution vaut son poids en or. P>
Avec mes développeurs, j'ai eu beaucoup de temps à vendre les concepts de SOC et DDD, à ce moment-là. Outre la testabilité, la facilité de débogage et une langue unifiée entre les ressources techniques et les parties prenantes, beaucoup de bénifits arrivent soit après le déploiement initial, ou pas du tout. Par exemple, vous n'avez peut-être pas besoin d'échelle (par exemple, d'envelopper une façade autour de vos services et de les mettre sur un autre serveur pour héberger une API reposer via des services Web), mais sachant que vous pouvez em> est un très bon sentiment. p>
Je comprends votre peur de l'effet d'ondulation. Pour être honnête, il y a toujours une ondulation de quelque sorte. Avec un référentiel correctement conçu, vous pouvez isoler la taille de l'ondulation pour être à peine quelques endroits. Comme il apparaît que vous utilisez .NET (basé sur le commentaire WPF), vous voudrez peut-être jeter un coup d'œil à
Lors de la conception d'une application, les niveaux d'abstraction doivent fournir une valeur. Ils ne devraient pas être là simplement parce que c'est une «meilleure pratique». Certaines applications ont un modèle de domaine riche et bénéficient des couches d'abstraction. Cependant, une application très centrée sur les données sans beaucoup de logique peut ne pas avoir besoin de plus de couches. P>
J'ai vu des applications qui définissent plusieurs couches correspondant à chaque objet avec les noms correspondant consciencieusement à la couche d'emploi, employébl, employé. Aucun des objets n'a ajouté aucune valeur et passe simplement des valeurs entre les couches de l'interface utilisateur à la base de données. C'était inutile. P>
Je trouve lorsque vous travaillez avec des applications avec un modèle de domaine plus riche, les modifications peuvent affecter plusieurs couches, mais sont rarement aussi simples que de transmettre une valeur de l'interface utilisateur via plusieurs couches à la base de données. Il existe au milieu de la logique commerciale qui serait beaucoup plus difficile à mettre en œuvre sans les niveaux d'abstraction. P>
À la fin de la journée, il est très important de choisir une architecture correspondant aux besoins de votre application en termes de complexité et de maintenabilité. P>
Quels outils utilisez-vous? Je n'ai jamais entendu parler d'un degré aussi élevé de non-sens non automatisé. Je ne crois presque pas que votre question soit réelle. Et que faites-vous avec un "objet métier" sur le client? P>
Vous parlez de couplage de vos couches d'accès aux données, d'entreprise et de service Web. C'est exactement où pas em> coupler! P>
Vos entités commerciales doivent correspondre aux entités réelles utilisées par votre entreprise. S'ils arrivent à mapper un à un avec votre base de données, c'est une coïncidence. Les services aux entreprises offerts par un service Web ne doivent pas être aussi finement grains que les méthodes de votre entreprise, de plus, à nouveau, il ne devrait pas y avoir de cartographie directe. P>
C'est définitivement le cas que de plus en plus de cela devrait être automatisé, avec une génération de code appropriée, mais cela ne sera jamais libre. Vous allez payer une chose ou vous allez payer une autre. Dans un environnement où tout se passe directement dans la base de données, tout au long de votre casser une table en deux ou trois, vous devez tout à coup de changer. Et je ne veux pas dire juste ajouter une colonne. P>
Faites attention à ce que vous demandez! P>
Je suis d'accord avec vous, je ne veux pas coupler ma couche d'accès aux données, d'entreprise et de service Web, car je sais que le service Web devrait être grain grossier, alors que l'objet Business ne devrait pas, et la conception de la base de données est également un problème très très complexe par lui-même. Le seul problème que je vois lorsque j'essaie de découpler, c'est qu'une petite modification posée par mon patron a presque toujours l'ondulation de plusieurs objets dans plusieurs couches. Et par exemple, je pense que l'ajout d'attributs / annotations sur mes propriétés peut vraiment me réserver pour écrire beaucoup de code, bien que ces attributs soient couplés à certaines technologies externes.
... certaines technologies externes, et pas vraiment liées aux entreprises. Comme je l'ai dit que je déteste faire cela, mais pour mes projets la plupart du temps, la base de données et le contrat de données, on dirait que mes objets métier et beaucoup de code sont écrits pour traduire un objet d'une couche à une autre ... Prenez l'exemple , le premier chapitre de weblogs.asp.net/scottgu/archive/2009/03/10/... , vous verrez qu'une très bonne application (le dîner NERD) est faite même si des objets d'affaires (comme un dîner) sont couplés à Linq à SQL.
Ces objets auraient mieux d'avoir été créés avec le cadre d'entité, qui découle les entités de la conception de la base de données. Notez comment EF utilise un modèle déclaratif: un modèle des entités conceptuelles et un modèle de mappage entre les entités et la base de données logique. De cela, il génère du code. C'est l'avenir. Voir aussi l'usine de service ( CODEPLEX.COM /FFACTORY ) À titre d'exemple d'un modèle de conduite de service génération du code pour le service. Astuce: J'ai combiné les deux modèles dans le passé.
Oui, mais si ces objets d'entreprise sont créés avec l'entité Framework ou Linq à SQL ou autre, ils sont couplés à une technologie de la base de données. Par exemple, vous devez créer un setter et un getter pour chaque propriété que vous souhaitez enregistrer sur la base de données, vous devez ajouter des attributs, vous devez peut-être hériter d'une classe et c'est ce que je ne veux pas faire. Ce que j'ai toujours fait, c'est la création de mes classes de base de données avec NHibernate / Linq dans le cadre SQL / entité, puis j'ai créé manuellement un traducteur entre ces classes générées et mon BOS .Quand appelle Microsoft "Entité" ne devrait pas être un BO à mon esprit.
@Slashene: C'est "ADO.NET Entity Framework". Il devrait fonctionner avec n'importe quel fournisseur ADO.NET, y compris Oracle et DB2. Il découle du schéma DB. Vous n'avez pas à jouer des attributs et des classes - vous créez un modèle et génère les classes.
Le point de séparer ces choses est p>
Sauf si vous avez 8 développeurs (pour correspondre à votre tarte à huit pièces) et écrivez-vous du code de test de l'unité pour correspondre au code de production, votre arrangement est surchargé. P>
Considérez également l'utilisation de couches d'abstraction pouvant être implémentées avec un simple passage à travers mais remplacé si nécessaire. P>
Les vues de la base de données sont un bon exemple - j'ai généralement la couche d'application uniquement référence aux tables de base de données via des vues (clairement indiquées par le suffixe _v) plutôt que des noms de table directement. Celles-ci font généralement référence à une seule table et ne sont que 2 lignes de DDL chacune. Ceci est rapide à créer et à entretenir - mais peut également être élargi pour fournir une traduction entre l'application, l'orm et la base de données. p>
Un autre exemple est les propriétés de Python - où votre code peut directement référencer des variables de classe ou d'instance plutôt que de toujours passer par des ensembles et des getters. Ensuite, plus tard, si vous devez traduire entre cette variable à l'intérieur de la classe et le code qui l'accède, vous pouvez définir une fonction de propriété qui est appelée à livrer la variable. Cela se produit de manière transparente au programme d'appel. p>
Ainsi, dans les deux cas, vous obtenez la valeur de la couche d'abstraction, mais également ajouter du code et du travail lorsque vous avez besoin de la flexibilité. P>