Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Thomas Lebrun

Tout sur WPF, LINQ, C# et .NET en général !

Actualités

[.NET] Article d'introduction au développement en couches

Lorsque l'on commence à développer des applications, on se rend vite compte qu'il est important de bien développer si l'on veut être un minimum structuré, avoir un code clair qui pourra être relû, etc.....

On entend ainsi parlé de développements en couches, d'applicatons N-Tiers, de design patterns, etc...

Tout cela, c'est fort intéressant mais cela pose quand même un problème: pour un développeur débutant, c'est un enfer de s'y retrouver !

Afin d'y voir plus clair, j'ai écrit un premier article destiné aux débutants:

Introduction au développement en couches

Comme son nom l'indique, cet article a pour but de fournir les premières briques nécessaires à la compréhension et à la réalisation du développement d'une application multi-couches (DAL, BLL, GUI, etc...)

Attention, cet article n'est pas exhaustif: en effet, il s'agit d'un sujet tellement vaste qu'un article de 15 pages ne peut en faire le tour. Néanmoins, il s'agit d'une bonne introduction au sujet qui devrait, je l'espère, faire plaisir aux débutants.

A titre d'information, sachez que je prévois (reste à voir si j'aurai le temps par la suite Smile) d'écrire d'autres articles sur le sujet: il s'agit en effet d'un sujet que j'apprécie beaucoup.

 

N'hésitez pas à me laisser vos commentaires Smile

 

A+

 

del.icio.us tags:

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: mardi 26 juin 2007 09:06 par Thomas LEBRUN
Classé sous : ,

Commentaires

Alexandre Marlot a dit :

Félicitation pour cette excellent article sur le développement par couche ! C'est vrai que c'est un sujet passionnant (qui me passionne moi aussi ;)).

L'article est très claire et très bien illustré par des exemples. Je vais le recommander à beaucoup de monde ;)

Je dois dire que j'essaye au maximum d'utiliser cette approche mais avec une toute petite différence aux niveaux de la gestion des exceptions. En effet, je découpe aussi les exception par couche (DALException, BLLException).

Une dernière question concernant : Le mapping d'objet relationnel, pour générer la DAL vous utilisez des outils spécifiques (CodeSmith, MyGeneration, codeFluent ...) ou un NHibernate par exemple ?

Bonne fin de journée.

Alex

PS : Vivement la suite des articles ;)

# juin 26, 2007 09:38

Thomas LEBRUN a dit :

Merci pour vos encouragements :)

En ce qui concerne le MOR, je dois admettre que je ne suis pas un grand utilisateur de ce genre d'outils (pour le moment, cela changera peut-être par la suite).

Pour le moment, j'ai un peu joué avec CodeSmith et MyGeneration (qui d'ailleurs est passé en OpenSource: http://sourceforge.net/projects/mygeneration) mais il va falloir que je me penche plus sur le sujet un de ces jours, car cela va dans la continuité des articles que j'aimerais écrire.

Sinon, il y a aussi LINQ To SQL que j'ai regardé et que j'aime bien.

Reste à voir ce que donnera LINQ To Entities :)

# juin 26, 2007 09:54

Alexandre Marlot a dit :

Rebonjour ;)

Je suis pressé de lire la suite de vos articles :) Ca s'annonce prometteur ... J'ai eu l'occasion de tester très rapidement le logiciel CodeFluent la semaine dernière et il avait l'air sympa. Cependant, le prix de la licence est assez conséquent (2500 euros) contre 400$ pour CodeSmith et 0 pour mygeneration.

Avez-vous dejà réalisé des tests sur ces deux outils ?

J'ai eu l'occasion d'assister à de nombreuses sessions sur Linq to SQL, c'est vraiment et ca s'annonce très prometteur cependant les versions RTM ne sortirons qu'en fin 2007 :( Je ne peux donc pas l'utiliser en production :( J'attends LINQ to Entities avec impatience mais encore une fois il ne sortira qu'en 2008 :( Donc d'ici la, j'essaye de trouver une autre solution :)

Codez-vous toutes vos DAL à la main ?

A très bientot

Alex

# juin 26, 2007 17:25

Thomas LEBRUN a dit :

>> Avez-vous dejà réalisé des tests sur ces deux outils ?

Non, je n'en ai jamais eu l'occasion...

>> Codez-vous toutes vos DAL à la main ?

Oui, la plupart du temps car je ne travaille des bases de données de petites tables donc je peux me permettre de tout faire à la main.

# juin 26, 2007 19:40

Miiitch a dit :

Super article! Je vais le recommander a Azra, pour qu'il donne son avis. Surtout qu'en ce moment, les couches.... il connait :p

# juin 26, 2007 21:24

richardc a dit :

Une question : tu la close quand ta connexion ?

Ta classe Sql n'implémente ni finaliseur, ni IDisposable. J'ai pas téléchargé le code mais ca m'inquiéte ;-)

# juin 26, 2007 22:19

Thomas LEBRUN a dit :

@Richard: Faut toujours que y'en ai un qui rale alors qui a justement pas téléchargé le code :)

Pour info, la classe SqlFactory.cs possède la méthode suivante:

public void CloseConnection()

       {

           if (this.m_SqlCnx != null)

           {

               if (this.m_SqlCnx.State != System.Data.ConnectionState.Closed)

               {

                   this.m_SqlCnx.Close();

               }

           }

       }

C'est juste que je n'ai pas écrit explicitement dans l'article qu'il fallait appeller cette méthode, mais tout y est :)

# juin 26, 2007 22:47

romagny13 a dit :

Bizarrement moi plus le temps passe et moins j'essaie d'utiliser une couche métier(apres une pèriode n-tiers) mais plutot une classe d'accès générique aux données grace à DbProviderFactory + des classes plus "typées" interagissant avec (méthodes pour lire et mettre à jour) et j'essaie de mettre en place un cache qui remplace la couche métier

(car celle ci me parait surtout interessante pour la consultation(+filtre et trie), mais est plus un inconvénient dès que l'on doit faire une mise à jour)

au niveau du cache dans quelle mesure l'utiliser ? est ce que le cache peut remplacer la couche metier ?

sinon c'est vrai que l'article est excellent ce serait génial si d'autres suivaient pour approfondir les sujets (tel le mapping o/r, le cache,le lazy-loading,etc.)

merci :)

# juin 26, 2007 23:00

cyril a dit :

J'ai pas encore eu le temps de lire l'article mais pareil que Richard tu ferme où la connexion ? OK la méthode est implémenté mais jamais appellé ;-)Heureusement tu passes par un using, quand .net va appeller la méthode Dispose il va fermer la connexion.

using (DbConnection cnx = SqlFactory.Instance.GetSqlConnection())

{

   clients = GetClientsFromDB(cnx);

}

Mais que se passe t'il dans un contexte multi-threadé (ASP.net) ? Tu n'as qu'une seule connexion instancié à la fois, stockée au niveau du singleton SqlFactory. Imagine maintenant que tu as deux GetClients simultanée les 2 vont récuperer le même objet SqlConnection, la premiere requête va être traité mais la deuxieme va claquer une exception car la connection est déjà utilisé (à moins qu'il la mette en queue et claque une exception car tu auras fait un dispose sur la connection)

D'après ce que j'ai vu du code, tu ne gères pas le multi threading ...

Je me demande aussi les avantages des singletons ? pourquoi pas tout simplement un helper ? une classe avec seulement des méthodes statics ?

Mais peut etre que tout ca est expliqué dans l'article que je lirais dès que j'ai un peu de temps ;-)

# juin 27, 2007 00:59

Matthieu MEZIL a dit :

Salut Thomas,

Très bon article.

Il y a juste un point où je ne suis pas d'accord :

"Généralement, on part du principe qu’une table dans la base de données représente un objet"

Justement je pense que la conception OO et la conception de la BD ne se font pas dans la même optique. Par conséquent, bien souvent, il est préférable que les classes ne soient pas une copie des tables.

Au delà de l'aspect optimisation, prenons un exemple tout simple qui montre que les classes et les tables peuvent être différentes : une facture qui référence un client. En base, on aura la clé du client dans la table facture. Dans les classes on aura souvent l'instance du client dans la facture et on aura également souvent une liste de factures dans la classe Client.

Pour revenir sur le MOR, jusqu'à maintenant j'utilisais le mien (je m'en suis développé un) mais j'ai été moi aussi conquis par LINQ To SQL et j’attends impatiemment LINQ To Entities.

Autre chose, avec le Singleton, je mets systématiquement un constructeur private afin d’être quasiment certain qu’il n’y ait qu’une seule instance de la classe de créer. Je dis quasiment car il est toujours possible d’instancier un objet dont le constructeur est private par Reflexion mais bon…

Perso, j’aurais plutôt utilisé un DataSet avec des Adapter pour les requêtes mais bon c’est un choix.

# juin 27, 2007 08:52

Thomas LEBRUN a dit :

@Cyril: Comme je l'ai dit juste avant, dans ma réponse a Richard, la méthode CloseConnection est implémentée mais pas appellée, c'est vrai. En même temps, je n'ai pas écrit dans l'article comment lancer Visual Studio, comment créer une classe, etc...

Effectivement, on peut penser que c'est une erreur de ma part de ne pas avoir montrer comment fermer la connextion mais:

1) J'utilise un using donc le boulot est fait automatiquement (mais c'est vrai que ce n'est pas forcément un point connu par les débutants)

2) Un article, c'est bien mais il faut un minimum de réflexion de la part du lecteur aussi....

Pour ce qui est du multi-threading: effectivement, je ne le gère pas. Mais le problème ne se pose pas (dans le cas de mon article) car, si tu l'avais lu au lieu de faire la remarque, tu aurais su que j'utilise une application Windows ;)

Dans le cas d'une appli Web, il est fort possible que certaines parties doivent être modifiées (même si, dans l'ensemble, le principe reste le même): ne faisant que très peu de développement Web, je préfère ne pas trop m'avancer sur le sujet :)

Et pour répondre à ta question: "pourquoi pas tout simplement un helper ?", voici ma réponse: effectivement, pourquoi pas :)

C'est un choix, rien ne dit que c'est le mieux ni le plus mauvais. Mais je me suis dit que, quitte à parler d'architecture, autant essayer de commencer à donner quelques pistes de bonnes pratiques (attention, ici, on ne se focalise pas sur les avantages/inconvénients des singletons: si le lecteur est curieux, il se doit tout de même de faire un peu de recherche).

Je le répète mais cet article n'est qu'une INTRODUCTION. Il n'est pas parfait mais ce n'est pas son role. Son role est de donner des pistes sur "Comment bien faire". Après, si les lecteurs sont curieux, c'est à eux de chercher un peu par eux même.

@Mathieu: "Justement je pense que la conception OO et la conception de la BD ne se font pas dans la même optique. Par conséquent, bien souvent, il est préférable que les classes ne soient pas une copie des tables."

C'est pourquoi, dans ma phrase, j'ai écrit "Généralement". Cela sous-entend que c'est souvent le cas mais pas toujours :)

Et c'est vrai que bcp de monde semble attendre LINQ To Entities avec impatience: espérons que le réésultat sera à la hauteur de notre attente !

A+

# juin 27, 2007 09:51

Danuz a dit :

Bravo Thomas !

Bel article et en français sur l'affaire ! ;)

Bonne continuation !

A + :-)

# juin 27, 2007 10:50

Miiitch a dit :

Sur certains projets j'ai rajouter une couche qui permet de gerer un scope de connection à la TransactionScope, ca permet d'enchainer des opérations à la base avec une connexion ambiante sans avoir a passer d'objet SqlConnection à chaque fois et surtout se demander si l'on doit le créer.

Ca ressemble à ca:

using (CnxScope cs = new CnxScope())

{

 SqlCommand sc;

...

sc.Connection = cs.Connection;

}

Autre avantage ca se combine tres bien avec un TransactionScope

# juin 27, 2007 14:53

phil a dit :

J'ai bien aimé l'article, dommage que tant de gens cherchent la petite bête.

Du coup on en oublie l'effort necessaire à la rédaction de ce genre d'article et l'apport qu'il peut apporter à la communauté.

Bravo en tout cas !!

# juin 27, 2007 15:08

seb816 a dit :

Article très instructif pour un débutant comme moi.

J'espère qu'il y en aura d'autres qui suivront. ;)

Merci en tout cas.

# juillet 29, 2007 12:58

Cilaos a dit :

Bonjour à tous et merci beaucoup thomas pour ce tutoriel, qui est très clair (plutôt rare en ce qui concerne le développement en couches).

@Thomas & @Cyril : je ne connais pas bien "using()" mais dans :

using (DbConnection cnx = SqlFactory.Instance.GetSqlConnection())

{

  clients = GetClientsFromDB(cnx);

}

N'est-ce pas cnx (variable locale) qui est fermée automatiquement par le using, et non la DbConnection du SqlFactory (qui, il me semble, reste ouverte pour tout autre appel)?

Si c'était le cas, je n'arrive pas à voir de problème pour un contexte multithread ASP.NET.

Si un d'entre vous peut m'éclairer sur le sujet, merci beaucoup, ça m'aiderait vachement car j'essaie d'appliquer le tutoriel à mon besoin (en ASP.NET).

Bonne journée.

# avril 9, 2008 14:10

Thomas LEBRUN a dit :

En effet, c'est bien cnx qui sera disposé automatiquement dans ce cas là.

# avril 9, 2008 15:08
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- [WPF] Et hop: un nouvel article sur c2i.fr (DependencyPropertyDescriptor & co) par Richard Clark le il y a 2 heures et 34 minutes

- Découvrir Windows Presentation Foundation (WPF) en webcasts par Bernard Fedotoff le il y a 4 heures et 39 minutes

- [WPF] Webcast pour garantir une interface réactive par Elise's blog le il y a 5 heures et 4 minutes

- Dell Inspiron Mini 9 - Enfin en vente !!! par The diary of EBArtSoft le il y a 19 heures et 26 minutes

- Solution Template et Project Template dans Visual Studio par Atteint de JavaScriptite Aiguë [Cyril Durand] le il y a 22 heures et 8 minutes

- PocketIE et Assignation du SRC d'un Element IMG par Jerome Laban le il y a 23 heures et 0 minutes

- Conversion de fichiers RAW en fichier JPEG avec WPF par Perspective le il y a 23 heures et 36 minutes

- Mise à Jour du Moteur de Recherche des Arrêts de Bus de Montréal par Jerome Laban le 09-07-2008, 17:46

- [WPF] XPSReader v0.2 par Blog Technique d'Audrey PETIT le 09-07-2008, 16:45

- Entity Framework : providers Oracle, MySQL et PostgreSQL par Matthieu MEZIL le 09-07-2008, 10:10