OVH Cloud OVH Cloud

java: les "grands principes" et la "vraie vie"

17 réponses
Avatar
Freddy
salut =E0 tous,

Dans tous les (bons) livres sur java on nous apprend de grands principes=20
de programmation et leur concr=E9tisation dans ce langage: encapsulation,=
=20
abstraction, modularit=E9, factorisation du code, etc...

N'ayant jamais fait de programmation java en =E9quipe, ni sur un gros=20
projet, je me pose la question suivante: que reste-t-il de ces grands=20
principes quand on fait de la programmation java dans une entreprise ?=20

Par exemple:=20
- est-ce que le code obtenu par copier-coller est si peu fr=E9quent ?=20
- est-ce qu'on r=E9utilise tant que =E7a ?=20
- est-ce qu'on cr=E9e ou manipule beaucoup de classes abstraites (en=20
dehors de celles des API standard) ?=20
- est-ce qu'on redefinit vraiment souvent equals et clone ? etc...

Pour ne pas que l'on se m=E9prenne, le sens general de ces questions n'est=
=20
pas: "=E0 quoi servent toutes ces c....ries abstraites ?", mais plutot:=20
"que deviennent toutes ces r=E8gles de bonne programmation lorsqu'on est=20
amen=E9 =E0 travailler sur un projet complexe, avec des contraintes=20
importantes de temps et d'efficacit=E9 ?"=20

J'aimerais avoir les temoignages de gens parmi vous qui sont dans cette=20
situation. Bien s=FBr je realise que "faire de la programmation java dans=
=20
une entreprise" recouvre des r=E9alit=E9s tr=E8s diff=E9rentes...

Merci (et bravo =E0 tous les participants de ce newsgroup tr=E8s=20
enrichissant)

Fred

10 réponses

1 2
Avatar
simon.oualid
Pour faire court, chez nous, java n'est utilisé que pour les
développements dont la durée de vie excède 6 mois (finances, webapp,
comptabilité, gestion), par opposition aux applis kleenex (un jeu en
ligne par exemple), pour lequel on utilisera les technos LAMP (et pour
lesquelles on externalisera les développement au forfait et en mode
"boite noire").

Pour les dev java, par contre, on est en boite blanche, et on est très
rigoureux sur la rationalisation et la qualité du code, car les
différents modules (éditorial, finance, mais aussi des modules plus
techniques : swing, web) sont massivement réutilisés entre les
différentes applis. On doit donc garantir la compatibilité ascendante
et s'assurer que les différentes couches applicatives sont bien
"découplées". Une mise en production d'un code instable pourrait
déstabiliser d'autres applications !

- est-ce que le code obtenu par copier-coller est si peu fréquent ?
- Jamais de copier / coller dans le code java, sinon le code

transversal ne peut pas évoluer "facilement" et de manière uniforme.

- est-ce qu'on réutilise tant que ça ?
- Oui ! Sinon chaque évolution du code partagé se ferait dans la

douleur (il faudrait penser à n'oublier aucune appli). ^_^

- est-ce qu'on crée ou manipule beaucoup de classes abstraites (en
dehors de celles des API standard) ?
- Oui, pour les notions métiers transverses (un contrat par exemple,

pour lequel il existera différentes spécialisations), mais aussi pour
les services et pour certaines IHM (une boite de recherche dont la
méthode de validation doit être redéfinie en fonction du contexte
applicatif par exemple)...

- est-ce qu'on redefinit vraiment souvent equals et clone ? etc...
- Oui, le clone pour le copier coller d'objets métiers, par exemple.

Et le reste pour pouvoir bénéficier des fonctionnalités de l'api
java (sorting, unicité, ...)

En bref, on essaie de faire "au mieux", mais on vit quand même dans le
monde réel et il faut souvent jouer sur les curseurs "qualité" et
"délais" pour pouvoir annoncer (et tenir !) des plannings qui tiennent
la route.

C'est parfois dur à faire comprendre aux dirigeants, mais sur le long
terme, cette approche transversale nous permet d'assurer une
évolutivité efficace et uniforme des grandes fonctions métiers sur
le moyen / long terme (que ce soit techniquement ou fonctionnellement).

Après, les expériences doivent varier d'une boite à une autre ...
j'avais toujours bossé dans des PME/TPE avant de rejoindre la grosse
boite pour laquelle je travaille aujourd'hui depuis un peu plus de 4
ans.

Symon

Freddy wrote:
salut à tous,

Dans tous les (bons) livres sur java on nous apprend de grands principes
de programmation et leur concrétisation dans ce langage: encapsulation,
abstraction, modularité, factorisation du code, etc...

N'ayant jamais fait de programmation java en équipe, ni sur un gros
projet, je me pose la question suivante: que reste-t-il de ces grands
principes quand on fait de la programmation java dans une entreprise ?

Par exemple:
- est-ce que le code obtenu par copier-coller est si peu fréquent ?
- est-ce qu'on réutilise tant que ça ?
- est-ce qu'on crée ou manipule beaucoup de classes abstraites (en
dehors de celles des API standard) ?
- est-ce qu'on redefinit vraiment souvent equals et clone ? etc...

Pour ne pas que l'on se méprenne, le sens general de ces questions n'est
pas: "à quoi servent toutes ces c....ries abstraites ?", mais plutot:
"que deviennent toutes ces règles de bonne programmation lorsqu'on est
amené à travailler sur un projet complexe, avec des contraintes
importantes de temps et d'efficacité ?"

J'aimerais avoir les temoignages de gens parmi vous qui sont dans cette
situation. Bien sûr je realise que "faire de la programmation java dans
une entreprise" recouvre des réalités très différentes...

Merci (et bravo à tous les participants de ce newsgroup très
enrichissant)

Fred


Avatar
vc.spam
Salut à tous,

Comme tu dis Freddy, chacun doit vivre une réalité différente, voire
différentes réalités succéssivement ou simultanément...

Je pense que tout ça dépend de beaucoup de paramètres:
- la volonté de la hiérarchie (et les moyens associé, le "propre"
c'est un investissement).
- la volonté des équipes.
- les connaissances et (surtout) l'expérience des équipes.
- le rapport à l'éxistant.

Personnellement, j'ai évolué, et le code de ma boite avec puisque je
suis maintenant le seul développeur java.

Au départ, j'ai tatonné une appli basique à base de FTP et décodage
XML, et déjà comprendre les mécanismes de XML et la programmation
FTP java pour un débutant total en Java et dans le monde des applis
réseaux sérieuses, c'était pas si mal.

Ensuite on m'a donné un client (au sens client-serveur) à traduire de
C/C++ (très peu "objet") à Java. Je l'ai fait, mais j'ai surtout
copier/coller et changé ce qui ne marchait pas (#define par exemple).
Et pour cause, je ne comprenait pas la version native avant de la
traduire. Donc, difficile de la réarchitecturer!!! De plus, personne
ne "parlant" java, on ne risquait pas de me montrer le chemin pour
programmer pour Java...

C'est dans ces conditions que j'ai attaqué la réalisation d'une appli
graphique. La raison du choix de java c'était:
- les compétences des ressources disponibles (hum! hum!).
- la "beauté" de Java (même le LNF de l'époque était mieux que
les MFC basiques).
- la perspective d'un éventuel portage (on excluait de fait VB
donc).

J'ai fait un proto semi-fonctionnel (fonctions principale OK, mais peu
de contrôle de cohérence des commandes dispos par exemple) pour
permettre au marketing de valider l'utilisation de Java. Ce proto à
été validé et le délai de finition imposé ne laissait pas de place
à d'autres choix que de modifier le proto pour en faire une appli
décente.
J'ai passé un certain temps à me débattre dans un code qui gonflait
à vue d'oeil. Une beaucoup trop grande partie du code était
directement lié à la partie graphique. A force de tenter de masquer
les défauts de départ (un proto graphique n'est pas conçu pour être
fiabilisé et ensuite maintenu).
A tel point qu'au plus fort de la tempête, j'avais une classe qui
devait faire environ 5000 lignes de code. Et encore, j'avais qq
principe en tête, je suis un convaincu de la programmation objet
"propre". Mais bon, dans la pratique, sans expérience de la
programmation objet (en particulier graphique, je trouve que c'est la
moins intuitive à rendre propre) et dans de telle conditions, on
subit!!!

En parralèle j'ai fait un essai d'implémentation de l'API Java
Speech. Cet exercice, même si on me l'a aussi fait bâcler, a été
salutaire. J'ai pu (enfin) intégrer la manière dont doivent dialoguer
les objets en java (et en général au passage).

Aujourd'hui, mes nouveaux composants sont de plus en plus propre et je
consacre du temps à rénover le code fait à mes débuts (ça apprend
l'humilité, lol). Les stagiaires que je prends sont invités à coder
selon les même principes, j'essaye de leur faire sauter qq étapes que
j'ai du faire ne rampant... Mais bon, faut pas rêver, les livres de
principes, les design patterns, les excellents profs ça ne remplace
pas l'expérience personnelle et la confrontation avec les collègues,
surtout si ils sont plus compétents!

Aujourd'hui, je crois qu'il est temps que j'aille me frotter à d'autre
developpeurs Java, JEE de préférence, pour évoluer.

Voilà une tranche de vie (4 ans) de développeur Java (notamment).

J'espère que ça répond un peu à ta question...

Vincent
Avatar
jeje900ss
Bonjour,


Dans tous les (bons) livres sur java on nous apprend de grands principes
de programmation et leur concrétisation dans ce langage: encapsulation,
abstraction, modularité, factorisation du code, etc...



C'est marrant mais j'ai un parcours trés ressemblant à celui de Vincent
qui a répondu. Moi aussi je suis dans une petite boite. Je gère tout le
développement et j'ai un developpeur et souvent quelque stagiaires à ma
charge.

Pour faire court, je vais dire que les grands principes je les applique
quand j'ai le temps. J'essaye de faire le meilleure compromis entre
délais et qualité, robustesse du code.

Je vais peut être en faire bondir plus d'un mais sur environ 70% de mes
projets, les tests unitaires sont passé à la trappe. Et mes projets
fonctionnent trés bien. Mais je gère presque tout de A à Z donc, je suis
capable d'être trés réactif en cas de Bug. Il est vrai que mes
developpements et mes architectures sont de plus en plus propres aussi
avec l'expérience.

En fait il faut savoir s'adapter suivant le contexte. Aprés faut savoir
imposer certain choix à la hiérarchie. Mais ce n'est pas facile.
Il doit avoir tout un monde entre gérer tout seul un projet de taille
moyenne (pas besoin de EJB en application WEB par exemple) en TPE et
travailler sur un projet énorme en SSII.

Et pour répondre à Vincent, moi j'ai fini par franchir le pas, et me
suis mis en recherche active d'un nouveau poste la semaine dernière.
En effet, je pense que je m'enchirai encore plus vite au contact d'autre
développeurs vraiment confirmé.

Jérôme

Avatar
Lionel
jeje900ss wrote:
Il doit avoir tout un monde entre gérer tout seul un projet de taille
moyenne (pas besoin de EJB en application WEB par exemple) en TPE et
travailler sur un projet énorme en SSII.


La différence entre TPE et grosse SSII ne se trouve pas forcément dans le
code.
J'ai un client qui m'a demandé de "récupérer" un gros projet codé par une
grosse SSII.
J'avais jamais vu un code aussi pourri, peu performant, buggé de toute ma
vie.
Et pourtant il y avait des tests unitaires.

Je n'ai eu qu'une seule expérience dans une équipe de 40 dév (dont certains
étaient très compétents), j'y ai constaté que plus le nombre de développeur
croit, plus la qualité globale et la maintenabilité du code diminue.
Ce n'est je l'espère pas systématique, mais probablement difficile à éviter
sans un très très bon management des équipes.

Avatar
Raphael Tagliani
Lionel wrote:
jeje900ss wrote:

Il doit avoir tout un monde entre gérer tout seul un projet de taille
moyenne (pas besoin de EJB en application WEB par exemple) en TPE et
travailler sur un projet énorme en SSII.



La différence entre TPE et grosse SSII ne se trouve pas forcément dans le
code.
J'ai un client qui m'a demandé de "récupérer" un gros projet codé par une
grosse SSII.
J'avais jamais vu un code aussi pourri, peu performant, buggé de toute ma
vie.
Et pourtant il y avait des tests unitaires.

Je n'ai eu qu'une seule expérience dans une équipe de 40 dév (dont certains
étaient très compétents), j'y ai constaté que plus le nombre de développeur
croit, plus la qualité globale et la maintenabilité du code diminue.
Ce n'est je l'espère pas systématique, mais probablement difficile à éviter
sans un très très bon management des équipes.


Je profite de ce post pour poser une question qui me taraude de plus en

plus.

Quelle est la meilleure façon de bien séparer les différentes parties
d'un programme en java?

En effet, il me semble que la meilleure pratique de développement
consiste à rendre 1 ou 2 personnes responsables d'un petit programme qui
sera très bien défini au niveau de son service model, de façon à pouvoir
l'intégrer dans un plus gros programme par la suite (en gros de l'Xtreme
prog...).

Donc, spécifiquement en java, comment feriez-vous?
- un package séparé pour le sous-programme, avec un package de stubs
pour les tests et une façade par sous-programme
- un programme totalement séparé, sous forme de jar, standalone pour les
tests et ayant sa propre doc/javadoc
- une meilleure idée?

et aussi, quel est l'impact de ces choix sur temps de développement
(réutilisation prise en compte)?

Merci, je me réjouis d'entendre votre expérience parler!


Avatar
Laurent Bossavit
Raphael,

En effet, il me semble que la meilleure pratique de développement
consiste à rendre 1 ou 2 personnes responsables d'un petit programme qui
sera très bien défini au niveau de son service model, de façon à pouvoir
l'intégrer dans un plus gros programme par la suite (en gros de l'Xtreme
prog...).


Pour ce qui est d'Extreme Programming: on recommande effectivement que 2
personnes (un binôme) s'occupent ensemble d'une /fonctionnalité/ qui est
formellement définie par un Test de Recette.

La façon la plus appropriée de structurer un programme objet est par
/composants/ et non pas par fonctionnalité.

Donc, la structure d'un programme Java ne reflètera *pas* le découpage
en fonctionnalités, et par conséquent pas l'affectation des tâches de
programmation aux personnes de l'équipe.

La structure par composants aura deux principes:
- minimiser le *couplage* entre les composants
- maximiser la *cohésion* entre les composants

Le couplage, c'est la propriété qu'a un composant d'entraîner, quand on
le modifie, des modifications "en cascade" dans d'autres composants.

Par exemple, imagine que tu as une classe Voiture, une interface Web
pour manipuler des voitures, et une base de données SQL qui stocke les
données. Le commanditaire du projet demande qu'on traite une nouvelle
information sur les voitures (mettons, la consommation aux cent Km). On
peut envisager deux types de scénarios:

- dans le premier, j'ai beaucoup de choses codées "à la main" et "en
dur", du coup il faut que je modifie le schéma SQL; trois écrans HTML
pour prendre en compte le champ "consommation"; trois classes Java qui
traitaient les données des formulaires HTML; et la classe Voiture elle-
même évidemment: tous ces composants sont *fortement couplés*

- dans le second, grâce à l'utilisation de composants plus génériques
(mapping OO-relationnel, générateur de formulaire) il suffit de deux
modifications: ajouter le champ dans la classe Voiture et créer un
"descripteur" qui précise le type du champ, les contraintes de
validation, etc. : la généricité permet un *couplage faible*

La cohésion, c'est le contraire: est-ce que les choses que j'ai rangées
ensemble sont "inséparables", ou bien puis-je envisager de les mettre
dans des modules différents sans entraîner un couplage fort entre ces
modules. Par exemple, si j'ai dans un seul package des classes qui
contiennent des algorithmes métier (calcul de la taxe sur les véhicules)
et d'autres qui s'occupent d'interface graphique (formulaires Web), la
cohésion de ce package est basse. Un module a une cohésion forte quand
il fait "une chose et une seule".

et aussi, quel est l'impact de ces choix sur temps de développement


Cohésion élevée et couplage faible égalent développement rapide, jusqu'à
ce qu'on peut appeler "hyperproductivité". C'est ce qui explique le
succès de frameworks comme Ruby On Rails.

Faible cohésion et couplage fort égalent la situation trop connue du
"plat de spaghetti". Nous savons tous ce qu'il en est sur les temps de
développement dans ce scénario: on va vite pendant quelques temps, et
ensuite on se retrouve avec du code non-maintenable et à dire au client
furibard "qu'il faut tout refaire de zéro".

Laurent

Avatar
dymezac
Bonjour Laurent,

je suis moi aussi débutant en java (étudiant) et je voulais savoir ce
qu'était le :
- mapping OO-relationnel
- un descripteur

pour le premier je ne sais pas du tout.

pour le descripteur, si je comprends bien (dans votre exemple) c'est
une classe qui va définir les propriétés du nouveau champ de la
classe Voiture, ensuite, l'interface Web n'aura qu'à interroger ce
descripteur pour ajouter automatiquement ce champ dans le formulaire ?

merci !
Avatar
Raphael Tagliani
Merci beaucoup, j'ai imprimé ce post, pour le relire avant de débuter
mon prochain projet! Je vais aussi m'intéresser à Ruby on rails, quand
j'aurai un moment.

Laurent Bossavit wrote:
Raphael,


En effet, il me semble que la meilleure pratique de développement
consiste à rendre 1 ou 2 personnes responsables d'un petit programme qui
sera très bien défini au niveau de son service model, de façon à pouvoir
l'intégrer dans un plus gros programme par la suite (en gros de l'Xtreme
prog...).



Pour ce qui est d'Extreme Programming: on recommande effectivement que 2
personnes (un binôme) s'occupent ensemble d'une /fonctionnalité/ qui est
formellement définie par un Test de Recette.

La façon la plus appropriée de structurer un programme objet est par
/composants/ et non pas par fonctionnalité.

Donc, la structure d'un programme Java ne reflètera *pas* le découpage
en fonctionnalités, et par conséquent pas l'affectation des tâches de
programmation aux personnes de l'équipe.

La structure par composants aura deux principes:
- minimiser le *couplage* entre les composants
- maximiser la *cohésion* entre les composants

Le couplage, c'est la propriété qu'a un composant d'entraîner, quand on
le modifie, des modifications "en cascade" dans d'autres composants.

Par exemple, imagine que tu as une classe Voiture, une interface Web
pour manipuler des voitures, et une base de données SQL qui stocke les
données. Le commanditaire du projet demande qu'on traite une nouvelle
information sur les voitures (mettons, la consommation aux cent Km). On
peut envisager deux types de scénarios:

- dans le premier, j'ai beaucoup de choses codées "à la main" et "en
dur", du coup il faut que je modifie le schéma SQL; trois écrans HTML
pour prendre en compte le champ "consommation"; trois classes Java qui
traitaient les données des formulaires HTML; et la classe Voiture elle-
même évidemment: tous ces composants sont *fortement couplés*

- dans le second, grâce à l'utilisation de composants plus génériques
(mapping OO-relationnel, générateur de formulaire) il suffit de deux
modifications: ajouter le champ dans la classe Voiture et créer un
"descripteur" qui précise le type du champ, les contraintes de
validation, etc. : la généricité permet un *couplage faible*

La cohésion, c'est le contraire: est-ce que les choses que j'ai rangées
ensemble sont "inséparables", ou bien puis-je envisager de les mettre
dans des modules différents sans entraîner un couplage fort entre ces
modules. Par exemple, si j'ai dans un seul package des classes qui
contiennent des algorithmes métier (calcul de la taxe sur les véhicules)
et d'autres qui s'occupent d'interface graphique (formulaires Web), la
cohésion de ce package est basse. Un module a une cohésion forte quand
il fait "une chose et une seule".


et aussi, quel est l'impact de ces choix sur temps de développement



Cohésion élevée et couplage faible égalent développement rapide, jusqu'à
ce qu'on peut appeler "hyperproductivité". C'est ce qui explique le
succès de frameworks comme Ruby On Rails.

Faible cohésion et couplage fort égalent la situation trop connue du
"plat de spaghetti". Nous savons tous ce qu'il en est sur les temps de
développement dans ce scénario: on va vite pendant quelques temps, et
ensuite on se retrouve avec du code non-maintenable et à dire au client
furibard "qu'il faut tout refaire de zéro".

Laurent



Avatar
Raphael Tagliani
Pour le mapping OO-relationnel:

Certaines architectures de bases de données, avec des clés étrangères,
sont dites relationnelles.
Exemple:
1 homme est le père de n enfants

OO fait référence à la prog orientée objet:
la classe Homme contient une liste chainée d'Enfants (une classe elle aussi)

Donc pour faire le mapping (donc la correspondance entre OO et
relationnel), on peut dire:
Puisque j'ai du côté langage de prog OO, une classe Homme et une classe
Enfant, je ferai du côté relationnel une table Homme et une table
enfants. De plus, une clé étrangère dans la base de données permettra de
modéliser le fait que Homme a n enfants.

Pour aller plus loin, vous pouvez regarder du côté d'EJBQL si vous
voulez utiliser des EJB.


dymezac wrote:
Bonjour Laurent,

je suis moi aussi débutant en java (étudiant) et je voulais savoir ce
qu'était le :
- mapping OO-relationnel
- un descripteur

pour le premier je ne sais pas du tout.

pour le descripteur, si je comprends bien (dans votre exemple) c'est
une classe qui va définir les propriétés du nouveau champ de la
classe Voiture, ensuite, l'interface Web n'aura qu'à interroger ce
descripteur pour ajouter automatiquement ce champ dans le formulaire ?

merci !



Avatar
Hervé AGNOUX
Raphael Tagliani wrote:

Pour le mapping OO-relationnel:

Certaines architectures de bases de données, avec des clés étrangères,
sont dites relationnelles.
Exemple:
1 homme est le père de n enfants

OO fait référence à la prog orientée objet:
la classe Homme contient une liste chainée d'Enfants (une classe elle
aussi)

Donc pour faire le mapping (donc la correspondance entre OO et
relationnel), on peut dire:
Puisque j'ai du côté langage de prog OO, une classe Homme et une classe
Enfant, je ferai du côté relationnel une table Homme et une table
enfants. De plus, une clé étrangère dans la base de données permettra de
modéliser le fait que Homme a n enfants.



Oui, si on admet qu'un homme est forcément un père :-)

Par ailleurs il n'est pas forcément indiqué de placer le lien "enfants" dans
la classe père. Il pourrait être placé dans une classe "Lien de Parenté",
par exemple. D'ailleurs, dans la base de données telle que tu la propose,
le lien lui même ne semble pas être placé dans la table père, qui ne
comporte qu'une clé étrangère, dis-tu. (un lien de lien ? )...

Je trouve que ces notions de liens sont la grande faiblesse des mises en
oeuvre des langages de POO actuels, et la situation ne semble pas vouloir
s'améliorer de ce coté. Je ne connais que UML qui ait un peu réfléchit à la
question (et d'autres moins connus, bien sûr) (il y a beaucoup d'études
dans la sphère Web sémantique / XML à ce sujet, mais c'est une autre
partie), et, dans "la vraie vie", cela pose des problèmes à n'en plus
finir. Heureusement, chacun se débrouille.

Et, d'ailleurs, soit dit en passant, si les bases de données XML parviennent
quelque fois à être plus efficaces et rapides que les bases de données
relationnelles, c'est justement parce qu'elles prennent mieux en compte ces
notions de liens. La vraie vie réserve quelque fois des surprises...


--
Hervé AGNOUX
http://www.diaam-informatique.com

1 2