Affichage des articles dont le libellé est Génie logiciel. Afficher tous les articles
Affichage des articles dont le libellé est Génie logiciel. Afficher tous les articles

jeudi 26 juin 2025

Concevoir un système d’annotations pour l’automatisation

À la suite de l'article concernant Automatisation d'interface utilisateur, j'ai reçu différents commentaires relatifs au choix qui avait ét fait. J'ai décidé d'écrire un autre article présentant différentes conceptions, avec leurs avantages et inconvénieunts respectifs

Annotation et convention over configuration

L'approche qui avait été adoptée était basée sur une annotation par responsabilité, avec le moins de choix possible. Un maximum d'automatisation avait été mis en place.


@Order(value = 9)
@HideField(value = SectionEnum.TABLE)
@Mandatory
private Integer groundElementOwnerId;

Les annotations indiquent 

  • que le champs serait affiché à la neuvième position.
  • que le champ serait caché dans la section table de la page.
  • que le champ est obligatoire

@Order(value = 7)
@TableStruture
private Map<String,String> properties;

Ici il y avait détection de la map et un tableau était affiché.




Différentes conventions avaient été mises en place.

Concernant les select, lorsque le nom de l'attribut contenait "id" et comportait plus de deux caractères, une tentative était faite pour rechercher un service au nom du dto et de trouver une méthode s'appelant findAll. Le résultat était mis dans le modèle et pouvait être utilisé dans thymeleaf.

Lorsqu'un traitement spécifique était nécessaire pour un champ, ce dernier pouvait être masqué via l'annotation et une gestion personnalisée était alors implémentée dans un template thymeleaf.

Cette première approche avait été simple en mettre place, car il y avait peu de cas spécifique à gérer. Le développeur pouvait aisément ajouter de nouveau dto.

La gestion de la construction de la structure dynamique était assez simple malgré les quelques annotations à gérer. Peu d'attribut était disponible dans chaune des annotations.


Annotation générique

Avec cette approche, une seule annotation est définie avec l'ensemble des attributs possibles. C'est possiblement la plus simple, même si le développeur doit fournir davantage d'informations. Le principal défaut est qu'il est possible que le développeur assigne des valeurs inexistantes  pour le type spécifié. Deplus, l'annotation a plusieurs responsabilités.

@FormField(type = FormFieldType.PHONE, order = 9, pattern = "999 999-9999")
private String phone;
    
@FormField(type = FormFieldType.SELECT, optionsProvider = "getCities", order = 5 )
private String city;
    
@FormField(type = FormFieldType.CHECKBOX, options = {"sportCheck:Sport", "musiqueCheck:Musique", "lectureCheck:Lecture"}, order = 15 )
private List<String> interest;

Une seule annotation facilite la construction de la structure dynamique. Seuls les attributs existants pour un type donnée sont pris en compte.


Annotation par responsabilité

Les responsabilités sont définies via différentes annotations. Le dto devient plus verbeux, et la gestion plus complexe pour construire la structure dynamique. C'est une version avancé que la première approche.

@FormField(type = FieldType.SELECT)
@SelectConfig(valueField = "id", labelField = "name")
private List<Ville> villes;

@FormField(type = FieldType.INPUT, placeholder = "+1 (555) 123-4567")
@FormStyle(cssClass="form-control")
@FormValidation(required=true, readonly=true, pattern="'mask' : '999 999-9999'")
@Order(8)
private String phone;

Annotation générique avec avec type spécifique

Chaque type dispose de sa propre annotation avec ses propres attributs. Ainsi, le développeur ne peut pas se tromper sur les propriétés applicables.

@HiddenInput(order=1)
private Long idEditeur;

@TextInput(minLength = 2, maxLength = 20, order=2)
private String name;

@TextInput(readonly=true, order=3)
private String age;

@SelectInput(optionsProvider = "getCities", required = true, order=4)
private String city

Approche assez simple à comprendre, cependant l'attribut order bien qu'utile pour la position d'affichage n'étant pas un attribut HTML, il vient briser le concept de séparation des responsabilités. Il pourrait être mis dans une autre annotation. Parfois un juste milieu est la meilleur solution.


Une librairie a été créé: https://github.com/marccollin/formatic


Quel approche au niveau des annotations préférez-vous?



jeudi 31 décembre 2020

Architecture hexagonale

Introduction

Dans une application conventionnel, il ne sera pas rare d'avoir une couche de contrôleur,  de service et de dao. Pour chacune de nos entités, une classe existera sous chacune de ces couches. Il est possible de se retrouver rapidement avec des centaines de classes. Ce type d'architecture utilise un modèle d'objet anémique, c'est-à-dire qu'il ne contient pas de logique métier.

Il n'est pas rare de voir un appel à la couche de persistance directement de la première couche.

Les entités, les domains object n'ont pas de règle métier. Elle est alors mise dans les classes de service, utilitaire. Ces classes chargent des entités, modifient leurs états et persistent le tout. Les services commencent à utiliser d'autres services et il n'est pas rare de se retrouver avec des classes de plusieurs milliers de lignes. Pour une petite application, de type CRUD, ça peut être plus rapide à développer, mais imaginer maintenant une application avec 200K, 300K... lignes de code.

C'est une architecture souvent basée sur le design de la base de données. Une modification au sein de celle-ci et des modifications à chaque couche est nécessaire.

Plus l'application prendra de l'expansion, plus il deviendra difficile de la modifier sans causer de multiples anomalies.

Une bonne architecture doit pouvoir s'adapter à de nouvelles exigences sans tout chambouler.

Une architecture hexagonale pourrait être une approche à songer pour débuter sans trop devoir tout changer si on désirait passer à des microservices par la suite.

Architecture hexagonale

Le but de ce type d'architecture est d'avoir un noyau relié à la logique métier. Tout le reste est externalisé tel que la sauvegarde de donnée ou bien la réception de donnée. Cette conception est priorisée en DDD: domain-driven design.  

 


Avantages

  • Indépendance de la couche métier aux autres couches, technologie
  • Test plus facile à effectuer

 Désavantage

  • Plus de code nécessaire
  • Structure plus complexe

 

Couche

Cette architecte implique de diviser l'application en trois couches:

  1. Application
  2. Domaine
  3. Infrastructure

Application

Cette couche est le point d’interaction de l’application. Il peut s'agir de contrôleur rest, de service de messages. C'est la porte d'entrée pour exécuter le domaine métier.  Cette portion est parfois appelée espace utilisateur.

Domaine

C'est l'implémentation de la couche métier, c'est le noyau central de l'application. Il se trouve aussi les interfaces de communication avec les deux autres couches. Il est possible de rencontrer cette couche sous l’appellation règle d'affaires.

Infrastructure

Cette couche possède l'implémentation pour sauvegarder dans une base de données, fichier, web service externe. C'est le point de sortie du domaine métier. Un synonyme pour cette couche est espace serveur.

Principe

Le domaine n'a pas connaissance de l'application et de l'infrastructure. C'est là qu'entrent en jeu les adapteurs et les ports. Les ports sont des interfaces que les adapteurs implémenteront. Chaque couche peut être testée individuellement, de plus l'utilisation d'interface ajoute un niveau d'indépendance au niveau de l'implémentation. Pour un test, les données pourraient être sauvegardées dans un fichier alors qu'en production la sauvegarde se ferait dans une base de données.

Contexte, limite d'un domaine

Contrairement à une application monolithique, l'architecture hexagonale nécessite de découper selon le contexte (bounded context). On se retrouve avec plusieurs petits modèles au lieu d'un modèle unique. 

Un contexte peut être vu comme les limites d'un sous-domaine dans une application auquel une certaine logique métier peut être appliqué.

Si on prend une application telle qu'amazon: il en existe plusieurs inventaire, prix, produit, commentaire.

 
L'interface graphique accède une multitude de microservice délimité par leur domaine. Si les instances du service de commentaire sont en arrêt, un client pourra tout de même acheter un livre.
 

Objet valeur (Value Object)

C'est un objet immuable qui décrit un aspect du domaine mais qui n'a pas d'identité. De la logique métier est fortement conseillé d'y être présent. Un âge ou bien une adresse pourrait être présenté de la sorte. Il faut considérer que deux VO sont égales si l'ensemble de ses champs sont identiques.

public final class Age{
     private final int value;
 
     public Age(int value){
        if(age < 0 || age > 120){
            throw new InvalidAgeException()
        }
        this.value=value;
     }

     public Age change(int value){
         return new Age(value);
     }
}            

Il serait tout à fait possible de ne pas utiliser un objet dédié, mais il faudrait externaliser la logique métier.  D'ailleurs c'est souvent cette façon de faire qu'il est possible de voir, on se retrouve avec des validations à maint endroit et le risque d'erreur de tout genre s'accroît.

Agrégat

C'est un groupe d'objet métier: objet de valeur, entité qu'on manipule comme si ça serait qu'une seule entité métier. Pour une facture, il y a différents éléments qui peuvent la composer: émetteur, destinataire, date, liste des produits ou service, coût, taxe. Toute modification devrait se faire au sein de notre agrégat afin de garantir sa cohérence. Si la facture est déjà payée, il ne devrait pas être possible d'ajouter d'élément dedans. Si un agrégat a besoin des informations d'un autre agrégat, son identifiant peut-être utilisé. Dans une transaction, il devrait avoir qu'une sauvegarde pour un agrégat.

Il faut prendre en considération que pour une situation donnée, un objet pourrait être un objet de valeur et dans un autre cas une entité ou même un agrégat.

Est-ce qu'on se soucie des valeurs de l'objet ou bien de l'identification d'une instance? Ce questionnement peut nous aider à choisir entre une value objet ou bien un agrégat. Pour spécifier l'identité d'un agrégat, une bonne pratique est d'utiliser une VO. 

Au lieu de faire

public class Invoice{
    int id;
}
 
Passer par un VO dans l'agrégat 

public class Invoice{
    InvoiceId id;
}

public class InvoiceId{
    int id; 
    InvoiceId(int id){
        if(id < 1){
            throw new ArgumentException("Id must have a minimum value of 1");
        } 
        this.id=id; 
    }
}
 
Dans le cas de notre InvoiceId, le id pourrait être la date du jour: 20201229 suivit d'un chiffre  qui s'incrémente et se réinitialise chaque jour. 

Il est plus aisé de changer le type de donnée par la suite, il y a moins d'endroits à effectuer les changements. Il est possible d'ajouter de la logique pour en autre effectuer des validations. Il est plus difficile de passer une mauvaise valeur que si on utilisait le type primitif.

Mise en pratique

Notre exemple consistera à une application de facturation, il pourrait avoir un contexte de facturation, client, paiement.... nous développerons celui de facturation. Plus précisément le scénario d'aller chercher une Invoice selon son Id. Notre application sera monolithique mais sous-divisée. Chacun des modules devrait utiliser une architecture hexagonale.

Notre objet Invoice va représenter toutce qui doit être facturé à un customer. LineInvoice représenterait chaque item produit ou service acheté. Invoice est un bon candidat pour un agrégat, mais LineInvoice?

public class Invoice {

    private final InvoiceId id;
    private final InvoiceStatus status;
    private final Long customerId;
    private final LocalDate paidDate;
    private final LocalDate dueDate;
    private final Flux<InvoiceItem> invoiceItems;
    
    private Invoice(InvoiceId id, InvoiceStatus status, Long customerId,
            LocalDate paidDate, LocalDate dueDate,
            Flux<InvoiceItem> invoiceItems) {
        this.id = id;
        this.status = status;
        this.customerId = customerId;
        this.paidDate = paidDate;
        this.dueDate = dueDate;
        this.invoiceItems = invoiceItems;
    }
    
    public static Invoice withoutId(InvoiceStatus status, Long customerId,
            LocalDate paidDate, LocalDate dueDate,
            Flux<InvoiceItem> invoiceItems) {
        return new Invoice(null, status, customerId, paidDate, dueDate, invoiceItems);
    }
    
    public BigDecimal calculateTotalPrice() {
        if (invoiceItems == null) {
            return BigDecimal.ZERO;
        }

        return invoiceItems.map(ii -> ii.calculateTotalPrice()).reduce(BigDecimal.ZERO, BigDecimal::add).block();
        
    }
}

LineInvoice pourrait être aussi un bon candidat pour un agrégat,  d'autres entités auraient besoin d'un identifiant. Il pourrait être possible d'appliquer une taxe, un rabais ou un frais d'envois spécifiques.

 public class InvoiceItem {
    private String description;
    private int quantity;
    private BigDecimal unitPrice;
    
    public InvoiceItem(String description, int quantity, BigDecimal unitPrice){
        if(quantity < 1){
            //quantity must be over 0
        }
        
        if(unitPrice.compareTo(BigDecimal.ZERO)!=1){
            //unit price must be over 0
        }
        this.description=description;
        this.quantity=quantity;
        this.unitPrice=unitPrice;
    }
    
    public BigDecimal calculateTotalPrice(){
      return unitPrice.multiply(BigDecimal.valueOf(quantity));
    }
    
}

 L'adapteur web

@RestController
@RequestMapping("/invoices")
public class GetInvoiceController {

    LoadInvoiceQuery loadInvoiceQuery;
    
    GetInvoiceController(LoadInvoiceQuery loadInvoiceQuery){
        this.loadInvoiceQuery=loadInvoiceQuery;
    }
    
    @GetMapping("/{id}")
    public Mono<Invoice> getInvoicesById(@PathVariable Long id){
        return loadInvoiceQuery.getInvoice(new InvoiceId(id));
    }
}

Le port pour la partie web    

public interface LoadInvoiceQuery {
    Mono<Invoice> getInvoice(InvoiceId invoiceId);
}

Le service au niveau du domaine

@Service
public class GetInvoiceService implements LoadInvoiceQuery{

    private final LoadInvoicePort loadInvoicePort;

    public GetInvoiceService(final LoadInvoicePort loadInvoicePort) {
        this.loadInvoicePort = loadInvoicePort;
    }
    
    @Override
    public Mono<Invoice> getInvoice(InvoiceId invoiceId){
        return loadInvoicePort.loadInvoice(invoiceId);
    }

}

L'adapteur de persistence

@Component
public class InvoicePersistenceAdapter implements LoadInvoicePort {

    @Autowired
    InvoiceMapper invoiceMapper;

    SpringPostgresInvoiceRepository invoiceRepository;
    SpringPostgresInvoiceLineRepository invoiceLineRepository;
    
    public InvoicePersistenceAdapter(SpringPostgresInvoiceRepository invoiceRepository,
            SpringPostgresInvoiceLineRepository invoiceLineRepository) {
        this.invoiceRepository = invoiceRepository;
        this.invoiceLineRepository=invoiceLineRepository;
    }


    @Override
    public Mono<Invoice> loadInvoice(InvoiceId invoiceId) {

        Mono<InvoiceEntity> invoiceEntity = invoiceRepository.findById(invoiceId.getValue());
        Flux<InvoiceLineEntity> invoiceLineEntity = invoiceLineRepository.findByInvoiceId(invoiceId.getValue());
        return invoiceMapper.mapToDomainEntity(invoiceEntity, invoiceLineEntity);
    }

}

Pour la persistence, il est possible d'utiliser une base de données ou un schéma par contexte ou bien dans utiliser un global à l'application. Seul un contexte a été développé, cependant même en optant pour une seule base de données pour l'ensemble des contextes, si on a besoin d'une information d'un autre contexte, en utilisant le id tel que customerId dans notre exemple,  pour aller effectuer la requête. Ce qui est une bonne approche pour bien séparer les domaines.

Si vous avez besoin d'augmenter les performances, vous pouvez utiliser un load balancer ou un reverse proxy pour démarrer de multiple instance de votre application avant d'opter pour des microservice. 

 Les packages sont organisés par couche. Certains préfèrent une organisation par fonctionnalité.

Responsabilité de l'adapteur pour la bd

  • Prendre les données en entrée
  • Les convertir dans le format de la bd
  • Les envoyer à la bd
  • Retourner les donner de sortie de la bd

Si vous désirez utiliser un ORM,  il faut faire le pont entre la structure objet et ceux utilisés pour le domaine, car tel que déjà dit, la couche du domaine ne devrait pas être imprégnée d'un framework. Cependant, j'ai pu constater à quelques reprises que ce n'était pas toujours respecté. 

Dans une architecture hexagonale, on se retrouve avec un petit domaine, je trouve alors l'emploi d'un ORM moins intéressant. Si vous optez pour cette solution, MapStruct peut grandement simplifier la conversion en vos objets métier.

Dans notre exemple, nous avons utilisé r2dbc, afin que l'application soit de type reactive. Contrairement au ORM, les relations ne sont pas géré, il faut le faire manuellement.

Autrement, Spring Data JDBC peut être une autre solution.

À partir d'un Id, nous avons été chercher un objet de type InvoiceEntity, il a été ensuite convertir en Invoice pour la couche domaine, nous aurions pu le convertir dans un autre format selon les besoins au niveau du web. Certains pourraient trouver que le passage entre ces couches est inutile dans ce cas. Un appel direct à partir du web vers la bd pourrait être effectué. Je suis d'accord, à moins de gros problème de performance, je continuerais d'utiliser cette approche, une fois que des raccourcies sont mis en place, ils deviennent rapidement la norme et on se trouve avec une architecture loin des attentes initiales.


Communication / synchronisation

Vous voudriez développer un autre module tel que le Customer. Comment les différents modules pourraient communiquer entre eux?

Dépendant si le type de communication: synchrone, asynchrone, vous pouvez optez pour des requêtes HTTP, service d'agent de message (RabbitMQ, JMS...)

Conclusion

Vous êtes une startup, vous voyez en grand. Vous regardez ce qu'utilise Netflix et vous voulez faire pareil. Vous n'avez aucun produit, aucune ligne de code de fait, mais vous pensez que la seule solution pour gérer votre hypothétique centaine de millions de requêtes est les microservices.

Il ne faut pas négliger la complexité niveau infrastructure: une base de données par microservice, la gestion des multiples instances des microservices, la communication entre eux et leur surveillance. Ces particularités amènent à avoir une équipe devops très efficace.

L'utilisation d'une architecture hexagonale pourrait grandement simplifier la mise en place de votre application avant qu'un passage au microservice soit réellement nécessaire. Le but de l'article était de vous montrer une façon différente de faire une architecture logiciel, libre à vous de l'adapter selon vos besoins.


 
 

lundi 8 octobre 2012

L'assurance qualitée avec Sonar

Sonar est un outil pour gérer la qualité du code source pour différents langages tels que Java, PHP, vb. Il utilise plusieurs logiciels tels que pmd, findbug, covertura... pour y parvenir.

Ce logiciel permet de détecter la duplication de code, de déceler le manque de documentation, les anomalies potentielles, règle de programmation, ce que couvrent les tests unitaires et la complexité du code.
Sonar peut s'intégrer à différents outils d'intégration continue tel que Hudson.

Il intègre sa propre base de données, H2 mais il est recommandé d'utiliser une autre base de données ne serait que pour avoir de meilleure performance.

Pour la présentation du produit, H2 sera utilisé. De plus aucun serveur d'intégration continue n'est utilisé.
Télécharger sonar et décompressé l'archive.

La particularité de ce système est qu'il est très visuel. Il peut aider à mieux identifier où doit être mis du temps afin d'accroître la qualité du projet.

Démarrage

Dans le répertoire bin de sonar, sélectionner le répertoire correspondant à votre environnement.

Cliquer sur le fichier sonar.bat si vous utilisez Windows, sinon sur sonar.sh.

Le système est alors accessible via un navigateur web: http://localhost:9000

Projets

Pour chacun des projets que vous désirez importer, si vous utiliser maven lancez la commande
mvn sonar:sonar

La liste des projets importés sera alors affichée dans l'écran de démarrage de Sonar.

Treemap

La treemap est une vue 2D. La taille de chaque carrée est une mesure quantitative selon différents critères des catégories: complexité, design, documentation, duplication, test d'intégration, gestion, revue...

La couleur représentante une mesure qualitative.


Dashboard

C'est la vue par défaut d'un projet. Les différentes mesures quantitatives présentées plutôt y sont affichées.

Hotspot

La vue hotspot présente les éléments à corriger d'un projet.

  • classes ayant le plus de violations
  • règles avec le plus de violations
  • classes ayant une forte complexité
  • classes ayant le plus de code dupliqué
  • classes le moins documentées


Time machine

La vue time machine permet de voir l'évolution du projet. Il est possible de comparer différentes versions du projet. Cette vue est particulièrement importante afin de savoir si le projet s'améliore ou part à la dérive.



Component

La vue component donne des informations similaires au dashboard, cependant elles sont données par  module.


Violations drilldowns

La vue Violations drilldowns indique les violations du projet en plus d'indiquer leur importance. Il est possible de modifier le degré d'importance des violations. Le nombre d'anomalies par type, le nombre de classes par importance, ainsi que le nombre d'anomalies par classe sont affichés.



Cloud

La vue cloud spécifie l'importance à accorder à une classe. La taille du nom de la classe varie en fonction de son importance.

Le cloud Quick wins affiche les classes qui augmenteront la qualité du code tout en demande peu d'effort. La taille du nom de la classe varie en fonction de sa complexité alors que sa couleur indique sa couverture

Le cloud Top risk affiche les classes ayant un risque d'erreur. La taille du nom indique la complexité par méthode alors que sa couleur indique le respect des règles.



Design

La vue design indique les dépendances entre les différents modules d'un projet. Certaines dépendances sont jugées inappropriées.


Des plugins gratuit et payant avec plus de fonctionnalités aussi disponibles. Le plugin Refactoring Assessment est par exemple disponible sous ces modes.




Dans sa version gratuite, des données sont fournies afin de montrer les possibilités de la version payante.  La version payante effectue automatiquement certains traitements.

Autres plugins

La puissance de Sonar est en partie due au nombreux plugins existant. Ils permettent d'étendre les fonctionnalités de l'outil. Voici quelques plugins très intéressants que je vous conseille.


SCM Stats Plugin

Technical Debt Plugin

Quality Index Plugin

SIG Maintainability Model Plugin

Useless Code Plugin

Timeline Plugin



samedi 22 septembre 2012

Design Pattern Tête la première




Ce livre présente les patrons suivants
  • Observateur
  • Décorateur
  • Fabriques
  • Singleton
  • Commande
  • Adaptateur, Façade
  • Patron de méthode
  • Itérateur, composite
  • État
  • Proxy
  • Composés


Au lieu d'aborder une approche théorique comme de nombreux livres, ils ont opté pour une approche pratique.

Il utilise des techniques afin de rendre plus aisé l'apprentissage. Les informations sont expliquées de diverses façons.

Les images sont abondamment utilisées. Il y a des mini-jeux ainsi que des questions afin de faire réfléchir le lecteur sur la matière vue.
Des conseils sont données tout au long du livre. Des dialogues ainsi que des histoires sont employés afin d'emmener le lecteur à se forger une idée sur les points clés.
Les moyens pédagogiques employés rend  la lecture du livre beaucoup plus agréable, sans compté que ça simplifie la compréhension et la mémorisation des patrons.

Les exemples de code utilisent le langage Java, cependant il devrait être compris sans difficulté par ceux utilisant c#.

Cette approche est employée pour chaque patron. Cette stratégie devrait être employée dans plus de bouquins.

À ce jour, c'est le meilleur livre sur les patrons que j'ai pu lire. Si vous devez en lire qu'un seul, pensez à celui-ci.

Certes seuls les patrons les plus populaires sont présentés, mais vous obtiendrez une base solide afin de les utiliser dans vos développements.

dimanche 16 septembre 2012

Netbeans

Netbeans
Chaque nouvelle version de netbeans apporte un nombre grandissant d'amélioration. Il a quelques années, Eclipse a su s'accaparer une grande part du marché des ide en Java.

Depuis, Oracle travaille d'arrache pied pour remonter la pente. Leur effort semble récompensé, les réactions dans les forums et sondage sont très positif. La facilité de créer des interfaces graphiques depuis la  version 5x à peu aider à contribuer à ce renversement.

Une panoplie de module peuvent être installé à la demande: C/C++, java mobile, php, ruby, grail, groovy. De plus le profiler ainsi le créateur de gui installé par défaut permette de faciliter le développement.

Hudson, Ant, Maven, Bugzilla sont bien intégré à l'outil.

Netbeans possède un éditeur graphique qui utilise le groupLayout. Il permet en quelques cliques de créer des interfaces très complexe.



Il y a certe moins de plugin qu'Eclipse, mais les meilleurs existent aussi pour cet ide.

De multiple wizard existe pour créer les fonctionnalités CRUD.

JavaFX est supporté.

La plateforme Netbeans peut être utilisé afin de créer des applications Swing. Il pousse à utiliser divers principe du génie logiciel tel que les modules, les plugins et les services. Il standardise les tâches courantes de création d'application graphiques: gestion des fenêtres, menu, mise à jour, gestion des langues. La gestion des modèles des composants graphiques est générique. Le même modèle peut être utilisé pour un jtree, jtable...

Si vous n'avez jamais utilisé Netbeans, essaye le, votre expérience de développement en sera grandissante. Autrement, faite la mise à jour.

vendredi 15 juin 2012

Specification By Example




Ce livre explique l'importance d'insérer le client dans le processus du développement logiciel. Les bénéfices ainsi que les bonnes pratiques sont définis. Le plus intéressant du livre est de mon point de vue les études de cas. Diverses entreprises donnent leur commentaire, comment elle était avant l'emploi de cette méthode et les résultats de son usage.

Des concepts clés tel que définir les spécifications en groupe, mettre des exemples dans les spécifications, valider fréquemment les spécifications ainsi que plusieurs autres bonnes pratique sont élaborés dans ce livre.

Je crois qu'avoir vécu quelques projets informatiques peut contribuer à mieux apprécier ce livre et ainsi remarquer qu'on est pas les seul à avoir des problèmes similaires et à vouloir les fixer.Oui la documentation est importante, mais une image peur remplacer beaucoup de mot et éviter des erreurs.

Les cas concrets ne font que renforcer que les méthodologies agiles peuvent vraiment être un avantage dans la gestion d'un projet informatique. Les cas sont différents ainsi que la structure et la des équipes ce qui permet de mieux pouvoir se projeter dans un de ces exemples C'est un livre qui donne de précieux conseils.

mardi 2 août 2011

Language Implementation Patterns




Ce livre présente différents patrons utilisés pour l'interprétation, analyse et la traduction de langage de programmation. Le livre utiliser ANTLR afin d'aller à l'essentiel et réduire la complexité. Les différentes étapes de la syntaxe du langage à l'exécutable sont passées en revue.

La première partie est consacrer au parsing le langage différente technique sont présenté tel que "backtracking, memoizin, predicated"... La deuxième partie consiste à analyser ce qui a été lu. La troisième partie est liée à la création d'interpréteur (haut niveau et bytecode). La dernière partie consiste à traduire à un langage à un autre.

Ce livre permettra à celui qui veut créer un langage de mieux décerner le patron qu'il pourra utiliser. Certains patrons sont plus adaptés à certains types de syntaxe. Le lecteur pourra avoir une idée pour implémenter un interpréteur pour un langage dynamique.

La traduction d'un langage à un autre permet grâce à l'exemple d'avoir une meilleure idée de la façon de faire pour un langage plus complexe.

J'ai trouvé que les explications n'étaient pas toujours claires et manquaient d'exemple réellement concret. Néanmoins, il constitue une excellente entrée pour quiconque veut implémenter un langage de programmation.

Peu de livres présentent d'une façon si épurée autant de concept, ce livre fait moins de 400 pages. La concurrence fait souvent plus du double ou triple et est axé trop souvent sur la théorie.

C'est un livre à compléter par un livre plus axé sur la pratique.

jeudi 14 avril 2011

97 Things Every Programmer Should Know




Ce livre est composé de 97 bonnes pratiques que tout développeur devrait connaître. Les astuces sont présentées par des programmeurs expérimentés. Elles sont courtes, mais précises.

 Ce n'est pas pas nécessairement des trucs sur la façon de coder, mais bien des idéologies à mettre en place afin d'arriver à produire du meilleur code, avoir un esprit plus rigoureux qui permettra de résoudre un problème donné de façon plus optimale.

Ce ramassis d'astuces permettra à quiconque du débutant à l'expert de parfaire ses connaissances dans l'art du développement. Au lieu de prendre des conseils à droite et à gauche et qui prendrait plusieurs années, ici on a l'essentiel qui est condensé.

Par exemple, on y dit qu'il est est important de bien maitriser son ide, savoir estimer, améliorer son code en enlevant le superflu. Ce livre présente plusieurs facettes du génie logiciel.
C'est un livre à posséder et à relire.

mardi 2 mars 2010

Les cahiers du programmeur Swing



Ce livre aborde plusieurs aspects du génie logiciel: patron, uml, test, outils de gestion du code. L'approche de l'auteur consiste à montrer par l'exemple est excellente. L'auteur explique différentes étapes pour la création d'un logiciel.

L'application développé est un logiciel d'architecture et représente bien une application réel et non une application bidon. Des annotations sont omniprésentes dans ce livre afin de clarifier certains points.

Par exemple les différences en Swing et SWT. En plus d'apprendre différent concept, l'auteur explique comment utiliser les composants JTree, JTable. L'api swing y est bien présenté. Le patron MVC est employé. Il est plutôt rare d'avoir un exemple aussi complet qui utilise ce patron.

Ce livre permettra aussi de mieux découper un projet. Le livre utilise une approche XP, comme dans un vrai projet. Certaine personne se pose des questions, à partir de ça , une certaine façon de faire est utilisé. Par la suite, il est montré si cette façon était bonne ou mauvaise.

Cet un livre qui montrer les bonnes approches pour développer un système informatique. Ce livre n'a pas d'équivalent. Enfin un livre qui combine la théorie à la pratique.

samedi 23 janvier 2010

Open ModelSphere


Open ModelSphere

Open ModelSphere est un outil de modélisation de données, de processus et UML. Il s'apparente à PowerDesigner. Il supporte divers diagramme UML, processus d'affaire, de notation au niveau de la modèlisation. La génération de code Sql supporte la majeur partie des bases de donné, il est aussi possible de faire de la rétro-ingénierie. Un outil très complèt sous licence libre.


Modèle de donnée

Le mcd, mld et les mdp sont géré par ce programme.

Mcd

Seul la notation entité/relation (merise) est supporté.

Mld

La notation merise, Datarun, information de génération (I/E), information de génération +, Structure de donnée logique, UML.

Mpd

Un scrip SQL peut être créé pour ses bases de données: Db2, DBase, HSQLDB, Informix, Ingre, Interbase, MSAccess, MySQL, Oracle, Parados, Progredss, MS Sql Server, SyBase.
Il est possible de passé d'un Mcd à un Mld et à un Mpd.

Rétro-ingénierie

À l'aide d'une base de donnée, il est possible de généré un modèle de donnée.

Processus d'affaire

Les notations suivantes sont gérés: Datarun, Gane Sarson, Merise, P+, Ward-Mellor, Yourdon-Demarco, Cycle de vie des objets.
Le diagramme ci-dessous utilise la notation Gane Sarson



Open ModelSphere, supporte la décomposition de processus. Il est donc possible de définir un processus à très haut niveau et de le décomposer en plusieurs autres afin d'arrivé à un niveau plus spécialisé. L'inverse peut aussi être fait.

UML

Les diagramme de classe, paquetage, composant, déploiement, cas d'utilisation, séquence, collaboration, état et activité sont géré. La génération de code vers Java et c# sont en béta. Il est même possible de générer un modèle de donnée.

Développement

L'architecture du logiciel permet d'étendre ses fonctionnalités via des plugins. Il est possible de supporter une nouvelle base de donnée. De générer convertir un élement x en y, de valider des éléments... Il est possible d'importer et d'exporter en XML.

Nous avons pu voir quelques fonctionnalités de ce système. Elles sont très nombreuses et pourra satisfaire l'utilisateur le plus exigent. Si vous utilisez Windesign ou PowerDesigner, vous apprécirez à coup sûr ce logiciel. Il est entièrement gratuit, essayez le.

mardi 29 décembre 2009

Le développement de systèmes d'information




Cet ouvrage met l'emphase sur l'étape d'analyse du système. Des méthodes sont présentées afin d'améliorer les processus d'affaire et de développement du système. Les méthodes employés peuvent être vraiment utile, même si je trouve qu'elles sont souvent sous-utilisés.
Elles prennent tous son sens pour modéliser les processus d'affaires afin de mieux les comprendre et les optimiser.

Plusieurs méthodes pouvant être utilisées par les analystes: étude préliminaire, analyse de besoin, modélisation, normalisation des données... Ce livre permet de bien débuter dans l'analyse des systèmes. De mauvais processus occasionnent un système mal adapté au besoin du client. Le livre commence par présenter des façons de bien analyser les processus existants, les améliorer et créer un système. Beaucoup d'exemples complètent les concepts présentés dans le livre. Les méthodes de travail présentées dans ce livre devraient être appréciées par quiconque devant développer un système.

Le genre de méthodes employés est très intéressante pour les systèmes de gestions.

C'est un livre à livre pour ceux qui veulent améliorer leur analyse informatique. Il m'est jamais été donné d'avoir autant d'exemple sur cette notion dans un livre

lundi 26 octobre 2009

Bonne pratique du génie logiciel


Bonne pratique du génie logiciel

La complexité des projets informatiques s'est accrue aux fils des problèmes à résoudre. Cette discipline est assez récente, malgré tout, après d'innombrable projets informatiques réussie certaines pratique très importante ont sortie du lot.

Dans cet article, nous allons répertorier une liste de bonne pratique qui peut s'avérer cruciale dans la bonne réussite d'un projet informatique.

Système de gestion de versions

C'est un logiciel qui permet de gérer des fichiers, de connaître les différentes version d'un fichier, de connaître l'historique d'un fichier. Imaginez qu'un vous avez classe nommé Animal au début d'un projet, avec un tous outils vous pouvez sauvegarder chaque changement que vous faite sur cette classe. Vous pouvez revenir en arrière. Vous pouvez savoir qui a fait des modifications sur cette classe.

Les fichiers sont sauvegardé sur un serveur. Plusieurs personne peuvent travailler sur le même fichier.
Il en existe plusieurs sur le marché dont subversion et cvs.

Équipe

Limité le nombre de personne dans une équipe à 3 à 5 personnes. Créer plusieurs équipes au besoin. Affecté des tâches à chacune des équipes et redistribué à au membres des équipes.

Tableau, "White board"

Lors de rencontre, un tableau peut s'avérer très pratique afin de mieux faire comprendre une idée, d'énumérer ses données. De plus une photo peut être prise afin de pouvoir se remémorer une certaine idée.

Documentation

Il est très aisé après plusieurs moi d'oublier et de ne plus comprendre le fonctionnement d'une fonction, classe. Bien documenter son code contribue à diminuer de tel risque. Il ne faut pas oublier de modifier au besoin les commentaires lorsque des modifications sont apporté au code. Si le commentaire n'est plus valide, il peut mettre en erreur le développeur. Ce n'est pas nécessairement le même développeur qui a créer la classe, fonction qui va faire les mises à jour ou faire la maintenance du code.

Une documentation pour l'utilisateur final est aussi très importante, elle permet de diminuer les appels au support technique.

Échéancier

Un échéancier devrait être établie. Ce qu'il doit apporté en terme de fonctionnalité et de correction devrait aussi être déterminé. À chaque mois, 2 mois... une nouvelle révision du système pourrait sortir.

Spécification

Les spécifications devraient pas être écrite par un développeur qui travaillera sur le projet.

Logiciel de suivi de problème

Un logiciel de suivi de problème devrait être mis en place afin de pouvoir connaître les anomalies relié au système, affecter un problème à une ressource du projet.Bugzilla, Mantis, JIRA sont parmi les plus populaires de ce type d'outils.

Performance

Un temps devrait être alloué pour optimiser le système. Par exemple, à la fin de chaque béta, quelques jours, semaine peuvent être consacré à l'optimisation du système.

Revue de code

Une revue de code devrait être fait sur une base régulière. Voir l'article qui est consacré sur le sujet sur ce site.

Test

Des ressources du projets devrait être alloué pour tester le système, des tests unitaires devraient être créé. À chaque nuit, ses tests peuvent être roulé afin de voir si les changements apportés ont créé une régression.

jeudi 18 juin 2009

Conception de bases de données




Ce livre s'adresse aux gens devant concevoir une base de données. Plusieurs exemples sont expliqués afin de mieux cerner les besoins de l'usager, intégrer les règles de gestion et modéliser les données et processus.

Beaucoup de diagrammes et d'illustrations facilitent la compréhension des concepts et méthodes présentés. Les non-initiés apprécieront que les concepts et commandes du SQL soient aussi bien expliqués en détail. Beaucoup de conseils sont donnés par les auteurs.

Le cycle complet de conception de base de données y est présenté, de l'analyse jusqu'à la maintenance. Beaucoup d'exemples sont présentés.

Ceux ayant déjà de très bonne connaissance en SQL trouveront surement ce livre moins utile, mais pourra servir à se remémorer certains principes oubliés

jeudi 14 mai 2009

Revue de code, Peer Code review


Revue de code, Peer Code review

Les erreurs sont omniprésentes dans divers domaines tel la programmation. Il existe cependant divers méthode afin de réduire les problèmes lié au développement. La revue de code est l'une d'entre elle. Elle est une étape cruciale dans le cycle de développement logiciel.

Méthode

Quelques méthodes de revue de code existe. Chacune présente des avantages et des inconvénients selon le type de développement employé.

Analyse par dessus l'épaule (Over the shoulder review)

Deux personnes sont présentes lors de cette personne. L'auteur du code qui dirige et celui qui analyse. Ce derniers, n'est pas nécessairement un informaticien. L'auteur parcourt le code, l'autre peut lui poser des questions, effectuer des traces le faire réfléchir. L'auteur inscrit les problèmes et les fixes après la rencontre. Cette méthode est très simple à mettre en place. Celui qui analyse, peut trouver de la difficulté à comprendre des algorithmes, portions de code plus complexe. Certaine partie de code peut ne pas être analysé. Cette méthode permet d'effectuer un transfert de connaissance.

Envoi d'email

Cette méthode nécessite l'emploi d'un outils de gestion de code source. Lorsqu'un changement a lieu, un courriel est envoyé aux personnes qui doivent analyser le code. Si un problème est décelé, il l'envoie au développeur. Ce derniers vérifie le problème et le corrige. Grâce à ce genre d'outils, tous les changements effectués sont retracables. Cette méthode permet de faire des analyses de code à distance. Les personnes n'ont pas besoin de se rencontrer. Cependant, étant donné la possibilité d'éloignement, l'analyse du code peut être plus longue, car il peut avoir plusieurs échanges entre les personnes.

Programmation en paire (Pair Programming)

Cette méthode de programmation implique que deux personnes soient devant un ordinateur. Un seul tape sur le clavier, mais les deux sont discussion, s'échange des idées. Des statistiques démontrent que cette approche permet de déceler plus d'erreur tout en effectuant un transfert de connaissance entre les participants. Cependant, elle nécessite que deux participant travaillent en commun ce qui coûte plus chère en terme de ressource, temps.

Liste de contrôle (check-list)

D'après plusieurs professionnels du domaine, dont Jason Cochen c'est une des méthodes les plus efficaces. Cette méthode consiste à créer une liste de point à vérifier dans le code. Voici par exemple, quelques points.
  • Est-ce que les cas où un objet peut être nul est vérifié
  • Est-ce que les limites d'un tableau sont bien vérifiés pour ne pas dépasser sa taille
  • Est-ce que les ressources sont bien libérés
  • Est-ce qu'une gestion est faite lorsque des paramètres invalides sont utilisés dans une méthode
  • Est-ce que les méthodes sont bien documentés
  • Est-ce que les algorithmes complexes sont expliqués et justifiés
  • Est-ce que les objets accessibles par plusieurs threads sont seulement accessible via un verrou (lock)
  • Est-ce que les objets sont dupliqués utilement
Cette liste est incomplète, à mesure que vous faites des vérification, vous allez voir des points à ajouter à cette liste.
Un exercice intéressant à faire est d'utiliser cette liste sur notre code et de faire des statistiques. Ainsi, vous pourriez connaître les erreurs que vous faire le plus fréquemment et être d'avantage attentif à ceux là. Si une autre personne vérifie votre code, vous pourriez lui spécifier ses erreurs plus fréquentes. De façon globale, utilisé en entreprise, les erreurs les plus fréquentes seraient ainsi connu.

Avantage

Coût

La découverte d'un problème peut être faite à toute étape du cycle du développement logiciel. Le coût ne sera par contre par le même, s'il est trouvé en phase de maintenant qu'en phase de conception. Plus que le problème sera trouvé tardivement, plus le coût sera élevé. Il faudra trouvé une solution, la testé, effectuer divers test de régression. Le changement peut avoir divers répercussion sur le système en place. Le support technique est ainsi réduit.

Qualité

Utiliser cette approche permet de déceler plus de problème, d'erreur, d'améliorer la robustesse du code. Au final, la qualité du système est ainsi augmenté. L'équipe de développement en sort grandie car ainsi, elle apprend à utiliser les bonnes techniques. En adoptant toujours ces bonnes pratiques, le cycle de développement entre dans une phase d'optimisation, où chaque développement devient de plus en plus de qualité. L'apprentissage d'erreur, permet habituellement de ne plus les refaire.

Outils

Un outils doit être en mesure d'effectuer le plus de tâche possible d'une revue de code. Gérer les fichiers (réception, transmission de fichier), commentaire et défaut pris par les participant. En gérant les fichiers, l'outil doit être en mesure de voir les différentes versions du fichiers. Ainsi, les changements sont aisément décelable. Les commentaires, défaut... doivent être associé au fichier. De cette façon, une conversation entre les participants est plus simple à suivre.

dimanche 16 mars 2008

Netbeans, GWT, GWT-EXT, Struts 2


Netbeans, GWT, GWT-EXT, Struts 2

Dans cet article, nous allons mettre en place un environnement de travail pour créer des applications utilisant GWT. Nous utiliserons Netbeans comme environnement de développement. Nous employerons GWT-Ext afin d'avoir accès à plus de composant et nous ajouterons Struts 2 pour avoir appeler une action.

GWT

GWT, Google Web Tookit est un framework java open source qui permet d'écrire des applications AJAX. Gmail, Google Maps utilisent ce framework. Ce framework permet de faciliter le développement d'application en oubliant les contraintes des navigateurs internet.

GWT-Ext

GWT-Ext est une librarie de composant graphique, elle fait le pont entre GWT et Ext.

Struts

Struts est un framework web pour développer des applications Java.Il permet d'employer l'architecture MVC.

Préparation

Nous utiliserons la version 6 de netbeans, vous pouvez la télécharger à cette adresse http://download.netbeans.org/netbeans/6.0/final/. Sélectionner la version comprenant le pack Web & Java EE.

Plugin gwt4nb

Il existe un plugin de gwt pour netbeans. Il permet de faciliter le développement de gwt sous cet éditeur. Le plugin se nomme gwt4nb. Téléchargez la version la plus récente du plugin à l'adresse https://gwt4nb.dev.java.net/. Ensuite installer le plugin dans netbeans. Démarrer netbeans, cliquer sur Tools, sélectionner Plugins. Cliquer sur l'onglet Downloaded et ensuite cliquer sur Add Plugins. Il vous reste juste à sélectionner le plugins et cliquer sur Install.

Autres librairies

Voici la liste complète des jars que vous allez avoir besoins pour ce projet.

gwt-servlet
gwt-dev-windows
gwt-user
struts2gwtplugin
gwtext
xwork
freemarkervoyage sncf
ognl
struts2-core
commons-collections
commons-logging
commons-loogin-adapters
commons-looging-api

Création du projet

Dans netbeans, cliquer sur File, New Project.Sélectionner la catégorie Web et le projet Web Application.

Ensuite spécifier un nom pour le projet et sélectionner votre serveur. Nous avons employé Tomcat, mais j'ai testé avec jboss et ça fonctionne aussi très bien.

Ensuite, vous devez sélectionner le framework Google Web Framework. Si ce framework n'est pas disponible, c'est que vous n'avez pas installer le plugin gwt4nb. Spécifier aussi l'emplacement d'installation de gwt. Spécifier un nom pour le module.

Si vous pouvez exécuter directement le projet, par défaut, vous devriez avoir une page ressemblant à celle-ci.

Maintenant ajouter les librairies mentionnées plus tôt dans ce projet.
Maintenant il faut ajouter les librairies de Ext à notre projet. Créer un répertoire js sous Web Pages. Sous le js, créer un répertoire ext. Ajouter à ce répertoire, le répertoire adapter, ressources et ext-all.js.

Dans le fichier de module (Main.gwt.xml), il faut ajouter la ligne suivante
 <inherits name='com.gwtext.GwtExt'/>
Le fichier devrait maintenant ressembler à
<?xml version="1.0" encoding="UTF-8"?>
<module>
 <inherits name="com.google.gwt.user.User"/>
        <inherits name='com.gwtext.GwtExt'/>
 <entry-point class="org.yournamehere.client.MainEntryPoint"/>
 
</module>
Maintenant il faut ajouter les fichiers de Ext dans notre page hôte GWT.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta name='gwt:module' content='org.yournamehere.Main=org.yournamehere.Main'>
        <title>Main</title>

        <link rel="stylesheet" type="text/css" href="js/ext/resources/css/ext-all.css"/>
        <link rel="stylesheet" type="text/css" href="js/ext/resources/css/xtheme-aero.css" />
        
        <script type="text/javascript" src="js/ext/adapter/yui/yui-utilities.js"></script>
        <script type="text/javascript" src="js/ext/adapter/yui/ext-yui-adapter.js"></script>
        <script type="text/javascript" src="js/ext/ext-all.js"></script>

    </head>
    <body>
        <script language="javascript" src="org.yournamehere.Main/org.yournamehere.Main.nocache.js"></script>
    </body>
</html>

Partie struts

Maintenant pour la partie struts, nous allons créer une action qu'on nommera HelloWorldAction. Créer un package org.yournamehere.action. Voici le code de la classe.
package org.yournamehere.action;

public class HelloWorldAction {

    public String execute() {
        return "Hello World";
    }
}

Sous le répertoire, Source Packages, créer le fichier struts.xml. Dans ce fichier, copier ce code
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
 <package name="samplepackage" extends="gwt-default">
  <action name="Hello" class="org.yournamehere.action.HelloWorldAction">
   <interceptor-ref name="gwt"/>
  </action>
 </package>
</struts>
Dans le fichier web.xml sou WEB-INF, il faudra rajouter de l'information sur les filters de struts.
<display-name>Struts 2 - Starter</display-name>
    <filter>
        <filter-name>action2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>action2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
Maintenant il faut faire le pont entre la partie client et notre action. La partie serveur étant notre action. Créer les deux interfaces ci-dessous.

MyService

package org.yournamehere.client;
import com.google.gwt.user.client.rpc.RemoteService;

public interface MyService extends RemoteService{
    public String execute();
}

MyServiceAsync

package org.yournamehere.client;
import com.google.gwt.user.client.rpc.AsyncCallback;


public interface MyServiceAsync {
    public void execute(AsyncCallback callback);
}

Appel de l'action

Nous allons maintenant faire l'appel de l'action dans le fichier MainEntryPoint.java. Ce fichier devrait ressembler à
package org.yournamehere.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;


public class MainEntryPoint implements EntryPoint {
    
    /** Creates a new instance of MainEntryPoint */
    public MainEntryPoint() {
    }

    public void onModuleLoad() {
        final Label label = new Label("Hello, GWT!!!");
        final Button button = new Button("Click me!");
        
        button.addClickListener(new ClickListener(){
            public void onClick(Widget w) {
                label.setVisible(!label.isVisible());
            }
        });
        
        RootPanel.get().add(button);
        RootPanel.get().add(label);
    }
    
}
Après l'ajout du code pour appeler notre action, votre code devrait ressembler à
package org.yournamehere.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.widgets.MessageBox;


public class MainEntryPoint implements EntryPoint {
    
    /** Creates a new instance of MainEntryPoint */
    public MainEntryPoint() {
    }
    
    public void onModuleLoad() {
        final Label label = new Label("Hello, GWT!!!");
        final Button button = new Button("Click me!");
        
        button.addClickListener(new ClickListener(){
            public void onClick(Widget w) {
                label.setVisible(!label.isVisible());
                
                callAction();
                
            }
        });
        
        RootPanel.get().add(button);
        RootPanel.get().add(label);
    }
    
    private void callAction() {
        MyServiceAsync service = (MyServiceAsync) GWT.create(MyService.class);
        AsyncCallback callback = new AsyncCallback() {
            public void onSuccess(Object result) {
                MessageBox.alert(result.toString());
            }

            public void onFailure(Throwable caught) {
                MessageBox.alert(caught.toString());
            }
        };
        ServiceDefTarget endpoint = (ServiceDefTarget) service;
        endpoint.setServiceEntryPoint("Hello.action");
        service.execute(callback);
    }
}
Si vous avez bien suivit l'article, lorsque vous appuyez sur le bouton, vous devriez avoir un message.


Nous avons vu comment appelé une action struts 2 dans GWT. Dans l'exemple montré, le bouton employait GWT, mais le message affiché utiliser GWT-Ext. Vous pouvez utiliser les composants de GWT-Ext au lieu de GWT. Un plugin existe pour spring aussi. GWT est une platteforme qui évolue rapidement, il manque encore de documentation surtout pour l'intégration avec d'autre framework.

dimanche 9 décembre 2007

Technique de référencement


Technique de référencement

Être bien positionné dans les moteurs de recherche permet d'augmenter le trafic de son site, accroître son site d'affaire ou bien d'améliorer l'image de sa marque. Le web s'est développé très rapidement  et les algorithmes de recherche des moteurs se sont complexifiés. Nous allons voir quelques méthodes, techniques qui permettent d'améliorer le référencement de son site.

Structurer ses pages

La structuration de ses pages Internet est cruciale afin de faciliter le travail d'indexation des moteurs de recherches. Plusieurs balises html sont préconisées afin d'obtenir le résultat souhaité.
  • description
  • title
  • hx
  • p
  • div
  • ul
  • alt
  • strong
  • em
Le positionnement d'un mot dans une page a de l'importance, plus il est placé tôt, meilleur que c'est pour le référencement.

Nom des url

Il devrait contenir des mots clés similaires au titre, relié au sujet de la page. Apache permet de réécrire l'adresse de votre url. Au lieu d'avoir une url similaire à http://www.laboiteaprog.com/article.php?numero=43?section=1 , il est possible d'obtenir  http://www.laboiteaprog.com/article-43-1-delphi_optimisation

Cette dernière est beaucoup plus significative et permet de cacher la technologie utilisé, elle situe et précise le contexte de la page.

Nom des images

Le nom de l'image devrait contenir des mots reliés à l'image, de plus il faut bien définir la balise alt, même si personne la lie, les moteurs eux l'utilisent.

Contrainte au référencement

  • Éviter de mettre du flash
  • Éviter les frames
  • Faire attention avec les pages dynamiques, limité le nombre de paramètre à 2

Pertinence et popularité des mots

Ce concept est déterminant pour le bon référencement de votre site. Il faut bien identifier les mots clés de votre domaine. Certain moteur tel que Google propose de connaître la popularité des mots recherchés. De cette façon, il est possible de ce concentrer sur les mots importants.
Il ne faut pas oublier les synonymes qui pourraient vous permettre d'être en peloton de tête.Quelques outils en ligne existent afin d'effectuer cette tâche.
En utilisant le même mot dans différentes sections d'une page, nous forçons le moteur à utiliser nos mots clés.
  • titre de la page
  • hx
  • alt
  • p
  • lien, titre de lien
  • liste
Il faut miser sur quelques mot clé par page et essayer de les combiner. Les moteurs de recherchent analysent le texte de différente façon. Le nombre de fois que le mot revient dans la page. Le nombre de fois qu'il revient par rapport au nombre de mot dans la page. Les différentes déclinaisons (majuscule, minuscule, pluriel...) du mot. Il ne faut pas par contre abuser, par exemple utiliser le même mot dans l'url du lien, le nom du lien et dans la balise du titre du lien, car ça pourrait causer l'effet inverse de celui souhaité.

Maintenir son site à jour

Il faut bien maintenir son site web, ajouter du contenu, le modifier car être bien positionné prend du temps.

Échange de lien

C'est l'autre point capitale pour être bien référencé. Il y a différent type d'échange de lien.
  • Lien interne à votre site web
  • Lien entrant et sortant sur un même serveur est pénalisant car c'est détecté comme étant louche
  • Les échanges de lien relié entre eux A -> B -> A ne sont plus pris en compte par Google.
  • Les échanges de lien non relié entre eux A -> B -> C -> A
  • Les site en .org ou .gov sont excellent car ses sites ne sont pas sanctionné par les moteurs de recherche.

Contenu dynamique

Il faut impérativement changer le contenu des zones critiques dans les pages de votre site. Ces zones sont le titre, descripion, nom de page etc. Ces sections devraient être dynamiques. Il est ainsi possible de s'adapter plus aisément.

Outils d'aide

Standard w3c

Le respect des standards web permet de s'assurer que les moteurs de recherche n'auront pas de problème technique à analyser votre site web. Un validateur pour le contenu html et css est disponible.

Générateur de mot clé

Générateur de mot clé adwords

Google Webmestre

Cet outil présente les recherches effectués qui ont permis de faire un clique vers votre site.

Sitemap

Le système de Sitemap aide les moteurs de recherche à l'indexation des pages de votre site. Il est constitué de d'url dans un fichier XML. Ce système est devenu un standard et est utilisé par les ténors du domaine: Google, Yahoo et Microsoft.

Connaître les sites qui ont des liens vers notre site Web

Dans la boîte de navigation de google, il faut inscrire: link:www.laboiteaprog.com
Nous avons vu dans cet article, quelques techniques qui permettent d'être référencé plus efficacement par les moteurs de recherche. Les moyens d'y parvenir exigent de plus en plus de connaissance et de complexité, c'est même devenu un métier très recherché.

dimanche 14 mai 2006

Les patrons


LES PATRONS

Il arrive régulièrement dans un domaine qu'il y ait des problèmes récurrents. L'informatique ne fait pas exception. Les programmeurs doivent régulièrement résoudre les mêmes problèmes.

Les patrons tentent de corriger cette lacune. Les patrons ressoudent de façon globale ces problèmes classiques. Les patrons ne sont pas liés à une implémentation. L'utilisation de cet outil permet d'avoir une solution qui a été éprouvée. Ils font parties des concepts de bonne pratique prôné par le génie logiciel. Il permet de résoudre un problème qui a été résolu maintes fois. Plusieurs solutions peuvent exister, mais certaines peuvent être plus adéquates que d'autres. Les utiliser permet d'économiser du temps et d'avoir une solution rapidement. À long terme, on pourrait dire que le but serait d'avoir un "handbook" tel qu'on en retrouve en mécanique et électronique.

Documentation

Il y a de plus en plus de patron qui est créé. La création d'une documentation pour un patron permet de partager nos connaissances et d'offrir une solution à plusieurs personnes qui pourront à leurs tours l'utiliser. Il est ainsi possible de déceler les problèmes s'il y en a et d'améliorer la solution.
La documentions d'un patron suit une syntaxe particulière.
  • Nom du patron, il doit être signification
  • Une description du problème que le patron tente de résoudre
  • Le contexte du patron.
  • Forces, une liste des points négatifs et positifs du patron
  • Une solution possible pour résoudre le problème
  • On crée un exemple

Divers patrons

Singleton

Description

Le Singleton s'assure qu'une seule instance de la classe est créée.

Contexte

Il y a plusieurs occasions où une seule instance d'un objet doit exister. Ce patron s'applique dans les situations où le nombre d'instances d'un programme doit être unique. Il n'est donc pas possible d'ouvrir plusieurs fois le même programme. Imaginez que vous écrivez une classe qui permet d'écouter un mp3. Si deux instances fonctionnent simultanément, l'utilisateur n'entendra rien. La classe écrite devrait terminer le flux audio courant et démarrer le nouveau.

Forces

Il n'y a qu'une instance de créée. Cette instance est accessible à tous ses clients et aux autres classes qui accèdent à elle. Il y a un gain au niveau de la mémoire.

Solutions

Il y a de nombreuse façon possible de s'assurer qu'une seule instance existe. Un moyen simple serait d'employer une variable globale, mais on peut rapidement rendre le programme illisible et difficile à maintenir. Une meilleure approche consiste à donner la responsabilité à la classe. La classe peut ainsi être en mesure de créer une instance seulement si aucune autre n’existe. Il est aussi possible de créer une fonction recevant une classe en paramètre et de vérifier à l'aide d'une variable si une autre instance existe.

Exemple

Le premier exemple utilisera une fonction afin de restreindre la classe à une seule instance. Cette fonction est codée en php.

function staticInstance($class) {
    static $instance; 
    if(!isset($instance)) { 
        $instance =& new $class; 
    }
    return($instance); 
}

La fonction reçoit une classe en paramètre, une variable statique est créée, si l'instance
n'existe pas on crée une instance de la classe.
Dans cet autre exemple, c'est la classe elle-même qui vérifie si une instance existe déjà.

public class Singleton
{
  private Singleton() {}

  static private Singleton instance;

  static public Singleton getInstance() {
    if (instance == null) 
      instance = new Singleton();
    return _instance;
  }
}

Le constructeur de cette classe est privé afin d'empêcher l'instanciation en dehors de la classe. Cette variable
de classe ne peut donc pas être accédé et modifié par aucune autre classe. Une instance de Singleton
sera créée lors du premier appel de getInstance. Instance aura donc une valeur nulle. 
S'il y a d'autres appels, la valeur ne sera pas nulle et une référence sur l'objet Singleton existant
sera retournée.

Façade

Description

Cache l'accès de nombreux objet derrière une classe

Contexte

Une classe x peut avoir de nombreuses relations avec d'autres classes. Il est alors fastidieux d'employer cette classe x, car cette classe doit en connaître plusieurs autres. La classe x devient alors plus difficile à réutiliser. Le patron façade ajoute une barrière entre la classe de base et les autres. La complexité est ainsi masquée.

Force

Il y a simplification de la classe client, déplace la complexité vers la classe façade.

Solution

L'objet façade permet l'accès direct à d'autres objets qui fournit la fonctionnalité désirée via une méthode.

Object pool

Description

Gérer la réutilisation des objets

Contexte

Il arrive souvent que plusieurs clients utilisent les mêmes ressources. Il peut être intéressant de limiter le nombre d'accès à ces ressources afin d'obtenir de bonnes performances. Un serveur Web qui fait des accès à une base de données peut-être rapidement mis à bout de souffle si toutes les connexions demandées sont acceptées. Chaque connexion à la base de donnée prend du temps et il y a dégradation des performances à chaque connexion d'ajoutée. Il est souvent possible d'utiliser les instances existantes.

Forces

Limiter le nombre d'instances créé, donc limiter les ressources utilisées. Éviter de créer des ressources afin d'utiliser ce qui existe déjà.

Solution

La réutilisation d'instance est privilégié. Il est possible d'utiliser un tableau lorsqu'on limite le nombre d'instances. L'objet qui crée l'instance doit être celui qui compte aussi les instances créées. Il y a donc un gestionnaire. La façon de prendre un objet de la pool et d'y retourner un objet est importante.

Exemple

Lors de de la première initialisation du ArrayPoolManager, un tableau est créé pour y entreposer les objets. Lors d'une insertion ou suppression, la quantité d'objets est mise à jour. La méthode getObject permet d'obtenir un objet dans la liste. L'objet est retourné. La méthode putObject remet un objet dans la pool. Cette méthode est employée lorsqu'on n'a plus besoin de l'objet. Le code source a été pris du site : microjava.
/**
    * Tableau qui contient les objets prêt à être utilisé
    */
   private Object[]  m_Pool;
    /**
    * La taille maximale du tableau
    */
   private int       m_Capacity;
   /**
    * Le prochain projet disponible, -1 signifie qu'il y a aucun objet.
    */
   private int       m_NextAvail = -1;
 
   public ArrayPoolManager(int capacity)
   {
      m_Capacity = capacity;
      m_Pool = new Object[m_Capacity];
   }


   public Object getObject()
   {
      /* Vérifie si un objet est disponible pour être retourné */
      if (m_NextAvail >= 0)
      {
         /*Libère l'objet du tableau, seul l'appelant à une référence à l'objet*/

         Object t = m_Pool[m_NextAvail];
         m_Pool[m_NextAvail--] = null;
         return t;
      }
 
      return null;
   }
   
   public void putObject(Object obj)
   {
      if (m_NextAvail < m_Capacity)
      {
         m_Pool[++m_NextAvail] = obj;
      }
   }
Les gains s'améliorent à mesure: que le nombre d'objets nécessaires s'accroît et que la complexité des objets est grande.

Délégation

Description

donnée des responsabilités d'une classe à une autre.

Contexte

Il arrive fréquemment qu'on utilise l'héritage afin d'obtenir les méthodes et attribut d'une classe. C'est un des concepts clés de la programmation orientée objet. En utilisant à outrance cette technique, des problèmes sur le plan des performances peuvent survenir.

Forces

Limiter le couplage, mais augmenter la cohésion. L'héritage est moins utilisé. Le code est donc plus simple et les mises à jour sont plus aisées à effectuer. Le code peut par contre être moins clair.

Solutions

Via une instance de classe dans un objet, on accède à ces méthodes.

Exemple

On établie un lien des fonctions désirées à l'objet «delageted». L'objet «delegate» implémente les fonctions voulues qui sont liées à une fonction de l'objet «delageted».


class Delegated
{
    public int fonction1(String args)
    {

    }
}

class Delegate
{
    protected delegated = new Delegated();

    public int fonction1(String args)
    {
         //On appele l'objet Delegated
         return delegated.fonction1(args);
    }
} 

Quelques patrons ont été abordés dans cet article. Il en existe plusieurs autres. Documentez-vous sur le sujet lors de la création d'un système. De cette façon, vous pouvez résoudre vos problèmes de façon efficace