jeudi 8 mai 2008

Objects and POO in .Net


Classes - objets
liste de clients héritant d'un SortedList


 
Objectif : Construire une liste de client fondée sur un SortedList, si vous avez travaillé le même exemple avec ArrayList comparez les codes construits.

 

Rappel du schéma interne d'un SortedList :  
( un SortedList = 2 tables  Keys et Values liées entre elles implantant un IDictionnary )




n est le nombre d'éléments présent dans le SortedList ( n = this.Count ).

Le couple ( une cellule de Keys , la cellule associée dans Values ) peut aussi être considéré comme un DictionaryEntry  = (Key ,Value), le SortedList peut alors être considéré aussi comme une collection d'objets de type DictionaryEntry :


Exercice, listeClient d'objets de type Client, fondée sur un SortedList :



Spécifications des méthodes à implanter :

Classe Client :

Un objet de type Client est identifié grâce à des champs publiques représentant son nom, son prénom et un numéro unique d'identification qui est attribué au client (l'adresse du client est facultative). Les deux surcharges du constructeur renseigneront les champs nom, prenom, idClient et adresse.


Classe listeClient :

Maintient à jour la liste de tous les clients à l'aide de méthodes.


Méthodes de la classe listeClient :
1°) 
void afficherListeClients() : affiche à la console la liste complète de tous les clients.
2°) 
void ajouterClient(Client person) : ajoute un client à la liste dans le cas où son identifiant n'est pas déjà existant dans la liste.
3°) 
void modifAdresseClient(string nomCli, string newAdr) : à partir d'un nom de client "string nomCli" cette méthode modifie l'adresse actuelle de ce client dans la liste.
4°) 
void supprimerClient(string nomCli)enlève de la liste, l'objet client à partir de son nom "string nomCli" s'il existe dans la liste.
5°) 
string requeteClientId(int idCli)renvoie sous forme d'une string toutes les informations connues sur un client de la liste(nom, prenom, identifiant, adresse) à partir de son numéro d'identification de client "int idCli".
6°) 
string requeteClientNom(string nomCli) : renvoie sous forme d'une string toutes les informations connues sur un client de la liste(nom, prenom, identifiant, adresse) à partir de son nom de client "string nomCli".
7°) Deux surcharges de l'indexeur de la classe listeClient, permettant de retrouver un objet Client de la liste l'un directe ( this[int id] ) l'autre associative ( this[string nom] ).

Classes Client et listeClient

 

using System;
using System.Collections;

    class Client
    {//-- enregistrement du type client
        public string nom, prenom, adresse;
        public int idClient; 

        //-- constructeurs :
       
public Client(string nom, string prenom, int id)
        {

       
}
        public Client(string nom, string prenom, string adresse, int id)
            : this(nom, prenom, id)    
        {
        }
    } 

    class listeClient : SortedList    {
        private const string mark = "***"

        //-- méthodes métier :
        public void afficherListeClients()
        {//-- liste des clients enregistrés:
        } 

        public string requeteClientNom(string nomCli)
        {//-- requête de recherche de client par nom dans la liste
        } 

        public void modifAdresseClient(string nomCli, string newAdr)
        {//-- modification si le client est présent
        }

        public void ajouterClient(Client person)
        {//-- ajout uniquement si numéro non déjà présent
        }

        public void supprimerClient(string nomCli)
        {//-- supprime uniquement si le client est présent
        }

        public string requeteClientId(int idCli)
        {//-- requête de recherche de client par identif client dans la liste
        }

        //-- indexeurs :
        public Client this[string nom]
        {//-- indexeur de requête Client par nom :Client("***","***",-1) si pas trouvé
            get

            {
            }
        }

        public Client this[int id]
        {//-- indexeur de requête Client par identif :Client("***","***",-2) 
         //   si pas trouvé.

            get
            {
            }
        }
    }

Chargez le programme à compléter avec la classe de test. (cliquez sur le lien)

Méthode Main, à utiliser pour tester les méthodes de la classe listeClient :

(identique à celle de la listeClient fondée sur ArrayList)

static void Main(string[] args)
{

            listeClient cci = new listeClient();
            cci.ajouterClient(new Client("renoir", "rené", 20));
            cci.ajouterClient(new Client("Lizt", "Franzt", "12 rote strasse 1245 Köln",8));
           
cci.ajouterClient(new Client("Thomson", "major", " 1st flowers street 00258 Maidstone",47));
           
cci.ajouterClient(new Client("Puccini", "Vittorio", 75));
            cci.ajouterClient(new Client("Strauss", "Johan", "62  Kirsh Platz 80065 Wien",109));
            cci.afficherListeClients();
            Console.WriteLine("Requête puccini : "+cci.requeteClientNom("Puccini"));
            Console.WriteLine("Requête idClient=1 : " + cci.requeteClientId(1));
            Console.WriteLine("Requête idClient=8 : " + cci.requeteClientId(8)); 
           
cci.ajouterClient(new Client("Wayne", "John", 75));
            cci.ajouterClient(new Client("Wayne", "John","Fort Alamo new Mexico",23));
           
cci.afficherListeClients();
            Console.ReadLine();
     
}

 

--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

mercredi 7 mai 2008

Web deployment of .Net project

That's strong
 

The power of Web Deployment for Winforms

When I've to deploy a Windows Form application, usually 99% of the times I create a setup package by using Visual Studio .NET and its Setup Project: here you can create a single .msi package or multiple packages by using cabinets files (.cab) (useful if you want to deploy your application via multiple media).

With .NET 2.0 you have the possibility to use the ClickOnce technology to deploy your application. ClickOnce basically allows you to deploy Windows-based applications to a desktop by placing the application files on a Web or file server accessible to the client and providing the user with an URL. When the user clicks the link, the application files are downloaded to the user's machine and executed.

The program are executed in a secure sandbox provided by .NET code access security (CAS). When a new version of the application is deployed to the server, it can be automatically detected by connected clients, and the update can be downloaded and applied in a variety of ways based on optional deployment settings.

The .NET Framework 1.1 also includes a possibility to deploy applications in a way similar to this, a way that is not so known and used but that it's really powerful (I've choosed to use it for my last project): the Web Deployment.

But what is it? It's essentially a zero-touch deployment model that allows you to install a .NET application simply by going via browser to the proper URL where there is the application's executable file. What is wonderful is that the web server not needs to have the .NET Framework installed (it could be also a non Microsoft web server) but it's the local system's copy of the .NET Framework that handles the installation.

When you go to the proper url, the assemblies are downloaded and maintained in a download cache (unique for each user) and the installation and execution of the application uses a zone-based security model.

You can check the security zone settings simply by using the .NET Framework Configuration tool, as you can see in the figure below (I'm sorry for the italian language of my system ). Obviously, you can customize the security settings of these zones as you want, but it's not recommended.

If you're developing Windows Forms applications with .NET 1.1 and your deployment scenario is an Intranet network, I recommed this way to to: by using it, you don't require to have a distribution method to all your users. You save time and you're sure that all receives the correct version.



--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

lundi 5 mai 2008

The reason for the challenge

Introduction

The Artical provides base for fresh C# and java developers

Features of C# absent in Java

  • C# includes more primitive types and the functionality to catch arithmetic exceptions.
  • Includes a large number of notational conveniences over Java, many of which, such as operator overloading and user-defined casts, are already familiar to the large community of C++ programmers.
  • Event handling is a "first class citizen"—it is part of the language itself.
  • Allows the definition of "structs", which are similar to classes but may be allocated on the stack (unlike instances of classes in C# and Java).
  • C# implements properties as part of the language syntax.
  • C# allows switch statements to operate on strings.
  • C# allows Anonymous methods providing closure functionality.
  • C# allows iterator that employs co routines via a functional-style yield keyword.
  • C# has support for output parameters, aiding in the return of multiple values, a featured shared by C++ and SQL.
  • C# has the ability to alias namespaces.
  • C# has "Explicit Member Implementation" which allows a class to specifically implement methods of an interface, separate to its own class methods. This allows it also to implement two different interfaces which happen to have a method of the same name. The methods of an interface do not need to be "public"; they can be made to be accessible only via that interface.
  • C# provides integration with COM.
  • Following the example of C and C++, C# allows call by reference for primitive and reference types

Features of Java absent in C#

  • Java's strictfp keyword guarantees the result of floating point operations remain the same across platforms.
  • Java supports checked exceptions for better enforcement of error trapping and handling.

Philosophical differences between the languages

  • There are no unsigned primitive numeric types in Java. While it is universally agreed that mixing signed and unsigned variables in code is bad, Java's lack of support for unsigned numeric types makes it somewhat unsuited for low-level programming.
  • C# does not include checked exceptions. Some would argue that checked exceptions are very helpful for good programming practice. Others, including Anders Hejlsberg, chief C# language architect, argue that they were to some extent an experiment in Java and that they haven't been shown to be worthwhile [1] [2].
  • C#'s namespaces are more similar to those in C++. Unlike Java, the namespace does not specify the location of the source file. (Actually, it's not strictly necessary for a Java source file location to mirror its package directory structure.)
  • C# includes delegates, whereas Java does not. Some argue that delegates complicate the method invocation model, because they are handled through reflection, which is generally slow. On the other hand, they can simplify the code by removing the need to declare new (possibly anonymous) classes to hook to events.
  • Java requires that a source file name must match the only public class inside it, while C# allows multiple public classes in the same file.
  • C# allows the use of pointers, which some language designers consider to be unsafe, but certain language features try to ensure this functionality is not misused accidentally. Pointers also greatly complicate technologies such as Java's RMI (Remote Method Invocation), where program objects resident on one computer can be referenced within a program running on an entirely separate computer. Some have speculated that the lack of memory pointers in Java (substituted by the more abstract notion of object references) was a nod towards the coming of grid computing, where a single application may be distributed across many physical pieces of hardware.
  • C# supports the goto keyword. This can occasionally be useful, but the use of a more structured method of control flow is usually recommended.
  • C# has true multi-dimensional arrays, as well as the array-of-arrays that is available to Java (which C# calls jagged arrays). Multi-dimensional arrays are always rectangular (in the 2D case, or analogous for more dimensions), whereas an array-of-arrays may store rows (again in the 2D case) of various lengths. Rectangular arrays may speed access if memory is a bottleneck (there is only one memory reference instead of two; this benefit is very dependent on cache behavior) while jagged arrays save memory if it's not full but cost (at the penalty of one pointer per row) if it is. Rectangular arrays also obviate the need to allocate memory for each row explicitly.
  • Java does not include operator overloading, because abuse of operator overloading can lead to code that is harder to understand and debug. C# allows operator overloading, which, when used carefully, can make code terser and more readable. Java's lack of overloading makes it somewhat unsuited for certain mathematical programs. Conversely, .NET's numeric types do not share a common interface or superclass with add/subtract/etc. methods, restricting the flexibility of numerical libraries.
  • Methods in C# are non-virtual by default. In Java however, methods are virtual by default. Virtual methods guarantee that the most overridden method of an object will be called which is determined by the runtime. You always have to keep that in mind when calling or writing any virtual method! If the method is declared as non-virtual, the method to invoke will be determined by the compiler. This is a major difference of philosophy between the designers of the Java and .NET platforms.
  • Java 1.5's generics use type-erasure. Information about the generic types is lost when Java source is compiled to bytecode. .NET 2.0's generics are preserved after compilation due to generics support starting in version 2.0 of the .NET Common Language Runtime, or CLR for short. Java's approach allows Java 1.5 binaries to be run in the 1.4 JRE, at the cost of additional runtime typechecks.
  • C# is defined by ECMA and ISO standards, whereas Java is proprietary, though largely controlled through an open community process.
  • The C# API is completely controlled by Microsoft, whereas the Java API is managed through an open community process.
  • The .NET run-time allows both managed and unmanaged code, enabling certain classes of bugs that do not exist in Java's pure managed code environment but also allows interfacing with existing code.


--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

jeudi 10 avril 2008

The challenger resume

Find it here:
https://mail.google.com/mail/?ui=2&ik=4b3fdc6c1e&realattid=f_5r3z8w6z0&attid=0.1&disp=attd&view=att&th=11933e122915aa27

--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

Challenge the challenge

Never give up and you 'll succeed
 


--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

lundi 31 mars 2008

.Net comparé à J2EE

L'architecture .NET comparée à J2EE
Une chose est sûre, avec l'avènement de .NET et le combat annoncé entre Sun et Microsoft il ressort d'ores et déjà un grand gagnant incontestable et incontesté : L'architecture n-tiers à base d'objets. De nos jours, l'important n'est pas de maîtriser Java, VB ou C# mais de comprendre en quoi ces langages nous sont utiles pour implémenter des architectures solides, évolutives et maintenables. C'est pourquoi, la philosophie de ce site est avant tout d'insister sur l'architecture que nous pourrions qualifier de "logique" dans le but d'illustrer les différentes solutions du marché. Bien entendu, .NET et J2EE se ressemblent sur de nombreux aspects mais diffèrent aussi dans leur implémentation de telle ou telle couche de l'architecture. C'est dans cet esprit que seront orientés la majeure partie des articles de DotNetGuru. Les questions posées seront les suivantes : en quoi la manière d'écrire un composant .NET est-elle si différente de la manière d'implémenter un composant Enterprise Java Bean ? Existe t-il les mêmes services de distribution, persistance ou transaction de part et d'autre ? Y a t-il, dans .NET, à la manière de Framework tels que Apache Struts un environnement MVC (Modèle Vue Contrôleur) similaire ? Comment .NET gère t-il la persistance des objets (la manière dont sont stockés les objets en base) ? Toutes ces questions seront au cœur de nos préoccupations avec à chaque fois le souci de l'objectivité.Ne disposant pas des sources de .NET, toute analyse de la conception interne du Framework sera forcément aléatoire, malgré tout, nous tâcherons d'apporter des réponses aux questions qui vous semblent les plus pertinentes. L'effervescence provoquée par .NET ne doit pas nous faire oublier que toute technologie ne peut émerger que si elle répond à une réelle attente. Avant d'aborder la suite, il est nécessaire de définir l'architecture logique qui servira de référence à l'implémentation des différentes couches par .NET et J2EE.Une architecture n-tiers comprend généralement une couche de présentation, une couche de services et d'objets métier et une couche d'accès aux données.Certains ont l'habitude de qualifier cette architecture de 3 tiers, 4 tiers ou plus ... Le but de cet article n'est pas de débattre sur le nombre de niveaux (encore que ce ne soit pas inintéressant), mais plutôt de se baser sur un modèle de référence qui nous servira de guide d'architecture. La figure suivante illustre le principe :
Nous allons commencer par comparer chaque couche de l'architecture pour étudier la manière dont elles sont implémentées dans .NET, mais avant cela, faisons un point sur leur contenu :
· La couche de présentation contient les différents types de clients, léger (Web, ASP, JSP) ou lourd (Swing, WinForm)
· La couche de service contient les traitements (contrôleurs de Use Case UML) représentant les règles métier (créer un compte, rechercher un client, calculer un amortissement, ...)
· La couche d'objets métier est représentée par les objets du domaine, c'est à dire l'ensemble des entités persistantes de l'application (Facture, Bon de Commande, Client, ...)
· La couche d'accès aux données contient les usines d'objets métier, c'est à dire les classes chargées de créer des objets métier de manière totalement transparente, indépendamment de leur mode de stockage (SGBDR, Objet, Fichiers, Legacy, ...)
Cette séparation par couche de responsabilité sert découpler au maximum une couche de l'autre afin d'éviter l'impact d'évolutions futures de l'application. Imaginez que vous ayez à changer votre base de données relationnelle pour une base sous la forme de fichiers XML à plat, seule la couche d'accès aux données sera impactée, la couche de service et la couche de présentation ne seront pas concernées car elles ont été découplées des autres. Microsoft fait un grand pas en avant avec .NET, en effet, c'est la première fois que son discours marketing et technique est orienté vers la "séparation des rôles et des responsabilités" et des "frameworks d'entreprise multi-couches", ... Aujourd'hui, plus personne n'a intérêt à ignorer les bienfaits des architectures n-tiers..
Les classes du FrameworkLe diagramme suivant nous illustre la BCL (Bases Class Library) : les classes du Framework. Contrairement à Java qui dispose de plusieurs SDK téléchargeables séparément (J2SE et J2EE), le Framework .NET comprend l'ensemble des classes ci-dessous.

L'environnement d'exécution : le Runtime et la CLR (Common Langage Runtime)
La CLR représente l'équivalent de la JVM dans le monde Java. Son fonctionnement est très proche de cette dernière avec MSIL (Intermediate Language) comme code intermédiaire (byte-code). .NET propose un ensemble de types définis à l'échelle du Framework (le Common Type System) dont la représentation est strictement la même dans tous les langages. Cela permet de faire hériter deux classes développées dans deux langages différents. Un ramasse miettes opérant sur le même principe que celui de Java s'occupe de la libération des ressources mémoire avec là encore quelques spécificités que nous ne détaillerons pas dans cet article.
Aperçu général des technologies utiliséesLe deux figures suivantes vous illustrent les technologies utilisées de part et d'autre.
La couche de présentation
Les clients lourds ou richesLa couche de présentation est la face visible de notre application. Les clients utilisant une interfaces graphique à base de formulaires riches et de contrôles graphiques complexes sont dit "lourd", en rapport avec la nécessité de déployer un applicatif sur le poste client. Par opposition, les navigateurs HTML sont considérés comme clients "légers" car ils sont pré-installés sur la plupart des plate-formes avec le système d'exploitation. Dans cette catégorie nous pouvons regrouper les applications Client/Serveurs traditionnelles en Visual Basic, Delphi, PowerBuilder, NSDK ... Bref, tout ce qui nécessite un applicatif client à installer.J2EESans entrer dans le détail, J2EE propose plusieurs APIs liées au client lourd :
· Swing et les JFC mais aussi l'AWT (Abstract Windowing Toolkit) moins riche et plus bas niveau
· Les Frameworks graphiques propriétaires sur-couche de l'AWT ou quelques fois de Swing (SWT d'eclipse, Oracle WT, JViews d'Ilog)
La caractéristique essentielle de Swing est d'être intégré dans le J2SE (le Framework Java) et de s'exécuter sur n'importe quelle plate-forme. La portabilité d'AWT et de Swing provient de la conception interne des classes existantes. Toutes les plate-formes possèdent des systèmes d'affichage vidéo différents : XWindow Motif pour Unix, Win32/GDI pour Windows, Apple/MAC. Sun a donc mis en place la notion de Composant Peer simplifiant le portage vers une plate-forme cible. Cette partie est donc native (code C/C++ ) et utilise des bibliothèques liées à chaque plate-forme.Quant à la conception du modèle objet Swing, elle est basée sur le concept de conteneur/composant et utilise intensivement le design pattern MVC.
.NET (WinForms)Microsoft propose une API similaire à AWT/Swing : les WinForms (Windows Forms). Les WinForms sont une surcouche de GDI+ (Graphical Device Interface) dont la responsabilité est de créer nativement (code non managé) des contrôles graphiques du type fenêtres, boutons, ... D'ailleurs GDI+ est écrit en C++ et améliore considérablement le modèle (non) objet de GDI/Win32 pour cibler l'architecture .NET et le namespace System.Drawing qui l'intègre. Dans le monde Java, Java 2D est l'API se rapprochant le mieux de GDI+ à ceci près que la majeure partie du code de Java 2D est écrit en Java.A l'heure actuelle, l'architecture des WinForms cible essentiellement Windows et le portage des WinForms vers d'autres systèmes s'avère délicat. Pour preuve, les équipes du projet Mono (http://www.go-mono.com) regrettent l'utilisation de l'ordre PInvoke difficilement portable (utilise des appels natifs) entre les couches WinForms GDI+ et Win32 concernant certains traitements spécifiques. Microsoft ne s'est pas encore clairement affirmé pour le portage du Framework sur d'autres plate-formes et cela ne fait sans doute pas partie de sa priorité à l'heure actuelle, préférant d'abord stabiliser .NET. C'est un choix stratégique dont nous ne débattrons pas ici. Les WinForms sont donc le pendant des Swing dans le monde Java et constituent la partie la plus délicate à porter du fait de leur forte intégration avec Windows.Quant à la conception du modèle objet WinForms, elle est basée sur le concept de conteneur/composant et comparé à Swing, celles-ci utilisent moins le design pattern MVC.
Les clients légers ou Web Les clients légers représentent les applications utilisant un navigateur Web comme interface graphique.J2EE (JSP) Java utilise une API standardisée intégrée dans les spécifications J2EE : Java Servlet API 2.3 et Java Server Pages 2.2. Cela implique que tout éditeur peut implémenter un moteur de pages JSP et de servlet compatible J2EE rendant une page JSP totalement portable sous divers produits. Aussi, souvent, le développement des pages JSP requiert l'utilisation de Framework externes dans le but de simplifier le modèle. Dans certains cas, le Framework Apache Struts peut apporter une plus grande souplesse dans l'architecture combinée à Velocity (moteur de Templates) ou encore Turbine et il en existe d'autres ! (Cocoon, XTP, ...). Vous trouverez donc énormément d'API Java (gratuites) dont le but consiste à étendre les fonctionnalités de base des JSP et séparer la présentation des traitements (règle fondamentale). Souvent, le manque d'outil permettant l'intégration de ces APIs entre elles freine leur utilisation et rendent complexe la tâche du développeur..NET (ASP.NET et WebForms) Dans ce domaine, Microsoft a innové avec plusieurs aspects : les ASP.NET représentent l'équivalent des JSP avec un modèle de développement totalement intégré basé sur les WebForms. Les WebForms permettent de développer une interface graphique Web de la même manière qu'une interface graphique VB, cela dans le but de séparer les traitements de la présentation. Ainsi, le formulaire représente la page Web et les traitements sont contenus dans une seconde page appelée Code Behind. Cette page peut être codée dans n'importe quel langage du Framework.NET et contient plusieurs méthodes, dont l'implémentation des évènements liés à cette page. La page HTML finale qui sera générée au client fusionne la présentation et le Code Behind en ciblant différents navigateurs. D'ailleurs, vous n'avez pas ou très peu la maîtrise du code généré qui est laissé à la charge du Framework.Pour résumer, Microsoft adopte une stratégie d'intégration des outils et permet de simplifier le modèle de développement en proposant les WebForms au dessus des ASP.NET avec Visual Studio comme chef d'orchestre. Bien entendu, il est possible d'utiliser uniquement les ASP.NET sans les WebForms tout comme en Java il est possible d'utiliser les JSP sans Struts ou Velocity.
La couche de service
La couche de service est la partie de notre architecture contenant les traitements applicatifs. Vous avez plusieurs alternatives au développement de services dans cette couche. Soit vous prenez l'entière responsabilité de l'implémentation des composants sans l'utilisation des services du Framework (vos besoins sont simples), soit vous faites appel au Framework pour :
La gestion des transactions automatiques
Le cache d'objets (Pooling)
La montée en charge et le multi-threading
Les composants asynchrones, ...
La responsabilité du conteneur est de vous fournir tous ces services en vous proposant un canevas dans lequel vous implémenterez vos composants.J2EE (EJB Session)Le choix de l'implémentation de cette couche réside dans deux approches : Utiliser les EJB ou ne pas les utiliser. Les composants concernés par cette couche sont les EJB Session. Sun spécifie un certain nombre d'éléments dans J2EE allant de la gestion des transactions en passant par la sécurité à la synchronisation des tâches. Ensuite, chaque éditeur propose une implémentation J2EE (serveur d'application) en rajoutant leurs spécificités propres :
Montée en charge, Clustering, Fail Over
Cache optimisé, Moteur d'exécution, outils ...
La distribution
Encore une fois, Java se distingue par l'ouverture de ces APIs avec comme maître mot : la portabilité du serveur. Bien entendu, nous pourrions nous poser la question de la pertinence de cette portabilité mais nous vous laissons libre d'en débattre, la réponse à cette question dépend de multiples facteurs (besoins, critères, ...)..NET (ServicedComponent)Tout comme J2EE, .NET propose le même ensemble de services sous l'appellation de ServicedComponent. Le conteneur utilisé dans le Framework est COM+. D'ailleurs, cela n'est pas sans poser de problème, COM+ fonctionne dans un environnement non managé avec une gestion de type différente de celle de .NET (Common Type System). Tout appel à une méthode d'un ServicedComponent utilisant des services spécifiques (Transactions, sécurité, ...) se traduit par une redirection vers les couches basses COM+ entraînant la création d'un Proxy (Wrapper). Ce dernier joue le rôle d'interface entre le nouveau monde et le vieux monde. Cet aspect qui pourrait sembler être un inconvénient n'en est pas vraiment un. En effet, le code d'un client utilisant un ServicedComponent n'est en aucun cas lié aux interfaces COM+ tout comme le composant lui même qui utilise l'API .NET : ServicedComponent. Tout cela se passe dans les tuyauteries internes du Framework comme décrit dans le schéma suivant. A plus long terme, lorsque Microsoft aura entièrement porté COM+ en COM+.NET 2020 ;-) seules ces couches seront impactées, pas le composant, encore moins le client. Dans tous les cas, c'est à espérer ....
Quant aux différences entre les services, nous n'entrerons pas dans le détail mais sachez que Microsoft propose .NET/COM+ et J2EE les EJB. La distribution est assurée par Remoting pour .NET et RMI sur IIOP pour Java. Les transactions sont gérées en Java à l'aide des API JTA/JTS et l'ensemble des composants s'exécutent dans un seul et même environnement managé, ce qui n'est pas le cas de .NET comme nous l'avons vu précédemment avec COM+.
La couche d'objets métiers (ou domaine)
Les objets métiers sont représentés par l'ensemble des objets persistants du domaine de l'application. Une facture, un bon de command e ou tout autre objet nécessitant d'être stocké en base. Cette couche assure l'indépendance totale entre le client et le type de stockage utilisé (SGBDR, SGBDO, fichiers XML, ...). Le client doit posséder uniquement une vue sur un objet avec l'ensemble de ces attributs et non un éventuel curseur (ResultSet et RecordSet) pointant vers une ligne d'une quelconque base. Cette couche est en étroite collaboration avec la couche de persistance qui assure la création des objets métier de manière totalement transparente.
J2EE (EJB Entity) Ce type d'objet est représenté par les EJB Entity dans la spécification J2EE. Dans ce cas, vos entités métiers sont couplées aux interfaces du Framework EJB et cela peut être gênant si la spécification EJB évolue dans le futur, d'autant plus que ces objets sont destinés à vivre très longtemps contrairement aux objets de services qui dépendent de l'évolution des règles métiers. Une autre approche consiste à développer des objets métiers simples n'héritant d'aucunes interfaces ou classes du Framework en utilisant des outils de persistance fonctionnant par introspection. C'est à dire que le mapping entre vos objets et vos tables est réalisé via des fichiers de configuration externes à votre application. C'est le cas de la spécification JDO qui cible ce genre de besoin avec des produits comme Castor, JUDO, KODO etc.... Ainsi, vous ne couplez pas vos objets du domaine à votre Framework de persistance.
.NETLes objets métier persistants dans .NET sont à l'heure actuelle des objets C# ou VB simples sans aucune caractéristique particulière.
La couche d'accès aux données ou de Persistance
Cette couche est responsable de la création, destruction et chargement des objets métier de manière totalement transparente. La différence entre une application 2-tiers et 3-tiers se fait à ce niveau. Son rôle est de masquer entièrement l'opération de création et de manipulation de tables (SGBDR) ou autre le types de stockages spécifiques (Fichiers à plats, ...). En règle général, vous avez deux alternatives : Implémenter cette couche vous même par l'intermédiaire de classes jouant le rôle d'usines à objets métier (pattern Factory), ou laisser le soin à un Framework tiers de réaliser cette tâche (produits du marché). Tout dépend de la nature de vos besoins et de la complexité des données manipulées pour mettre en oeuvre le mapping objet/relationnel.Cette partie, souvent délaissée dans la mise en place d'un projet est le tendon d'Achille d'une architecture. La conception de la couche de persistance doit se faire avec soin et en tenant compte de multiples facteurs tels que la montée en charge, la complexité de mise en oeuvre mais aussi l'impact d'évolutions futures de la base. Voyons ce que proposent J2EE et .NET dans ce domaine.
J2EE (JDBC) Dans le monde Java, l'API JDBC (Java Database Connectivity) est en charge de la communication entre un client et un SGBDR. Contrairement à .NET qui propose des API oledb ciblant aussi bien des bases relationnelles qu'un annuaire distribué (Exchange), JDBC s'adresse uniquement aux bases de données SQL.
Si vous prenez le choix de gérer vous-même la persistance des données, il vous suffira d'implémenter des classes utilisant JDBC. Dans le cas où vos besoins sont plus complexes, il faudra faire l'acquisition d'un produit (gratuit ou payant) réalisant cette tâche à votre place. Il en existe un certain nombre s'interfaçant avec les spécifications EJB (EJB Entity). Le but étant de fournir un composant standard qui utilise les services des outils de mapping objet/relationnel de manière totalement transparente. Il existe deux types d'EJB : BMP (Bean Managed Persistance) et CMP (Container Managed Persistance). Dans les deux cas, l'API utilisée pour communiquer avec les bases de données relationnelles est JDBC. Cette API est spécifiée par Sun, intégrée à J2EE et dispose de plusieurs implémentations à travers les multiples drivers JDBC disponibles sur le marché (Oracle, SQL Server, DB2, ...). JDBC permet aussi de convertir le résultat de requêtes SQL en XML (JDBC 3.0)..NET (ADO.NET) Microsoft propose ADO.NET pour l'accès aux données. ADO.NET fonctionne de manière similaire à JDBC avec quelques variantes.Historiquement, ADO souffre d'un passé quelque peu lourd à porter. C'est pourquoi, vous trouverez deux types de provider :
Managed (utilisant les services de la CLR)
Unmanaged (pour supporter les anciennes versions)
Le schéma suivant nous illustre l'ensemble des API mises en oeuvre dans d'ADO.NET, comparée à JDBC nous pouvons remarquer une complexité plus importante dû au support historique d'oledb et à la prise en charge de divers types de serveurs (Exchange, ...). Nous pouvons espérer à terme que Microsoft proposera tout comme JDBC un même socle commun managé.
Nous n'entrerons pas dans le détail des classes d'ADO.NET mais la grande nouveauté se situe dans l'intégration d'XML à tous les niveaux. Le schéma suivant nous illustre les différentes étapes comprenant l'accès aux tables jusqu'à l'affichage dans un WinForm par l'intermédiaire d'un DataView en passant par un DataSet.
Le DataSet jour un rôle capital dans ADO.NET. En effet, il permet de renvoyer par valeur un ensemble d'enregistrements associés à la structure des tables contenant les relations d'association. Lorsque nous évoquions précédemment la couche de persistance, nous avons parlé de l'importance de dissocier un client de la base de données. C'est pourquoi, le DataSet doit être, tout comme le ResultSet, manipulé dans le but de renvoyer des objets métier. ObjectSpace, en préparation dans les labs de Microsoft adopte cette démarche.ConclusionLes deux environnements disposent de mécanismes très similaires pour gérer chaque couche de l'application. L'important est de savoir utiliser ces services de manière à découpler au maximum les couches entre elles. Finalement, Microsoft ou J2EE, les questions relevant de l'architecture demeurent les plus importantes, ensuite ce n'est qu'une question de critères (portabilité serveur, multi-plateformes, scalabilité, ...).