<?xml version='1.0' encoding='UTF-8'?> <rss version='2.0'><channel><title>http://michael.carbenay.info</title><link>http://michael.carbenay.info/</link><language>fr-Fr</language><generator>CPointSoftware e-commerce (weblogs module)</generator><item><title>Conseils pour développeurs (asp.net) du dimanche</title><link>http://michael.carbenay.info/post-378.htm</link><pubDate>Fri, 22 Aug 2008 11:22:28 GMT</pubDate><description><![CDATA[<p>Cela fait quelques semaines que j'interviens de façon ponctuelle sur la maintenance d'un extranet pour un client, et que je m'énerve régulièrement sur l'incapacité de la plupart des développeurs à comprendre qu'un code doit être un minimum propre... L'application, écrite en asp.net, est un ensemble de morceaux de code réalisés, probablement, à la va-vite par des CDD si j'en juge par la "qualité" très médiocre.</p> <p>Voici donc quelque conseils à retenir si vous faites du développement ASP.net et que vous souhaitez voir votre code être maintenu...</p> <p><strong>N'accèdez jamais</strong>, directement dans votre page,<strong> à des variables de sessions ou d'application</strong> : c'est probablement le B-A-BA du développement avec des langages typés... Il n'est pas normal de voir dans une page ASP.net (sauf cas exceptionnels) des accès du type :</p> <blockquote><pre class="csharpcode">(<span class="kwrd">int</span>) Session[<span class="str">"MEMBRE_ID"</span>] <span class="rem">// non !!!!!</span></pre></blockquote>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>Pourquoi cela n'est-il pas bien ? eh bien tout simplement parce que si une autre page accède (ou encore plus catastrophique met à jour) votre valeur, il y a 1 chance sur 2 pour que celle-ci ne manipule pas le même type de données (dans l'exemple de l'application extranet, l'une des pages traitait l'identifiant client comme un decimal et l'autre comme un int...). Pour réaliser un code maintenable, il vous reste à faire une class "Helper" qui se charge de masquer l'accès à la variable de session et le typage :</p>
<blockquote><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> SessionHelper
{
    <span class="kwrd">public</span> <span class="kwrd">int</span> MembreId
    {
        get
        {
            <span class="kwrd">object</span> o = Session[<span class="str">"MEMBRE_ID"</span>];
            <span class="kwrd">if</span> (o == <span class="kwrd">null</span> || !(o <span class="kwrd">is</span> <span class="kwrd">int</span>))
                <span class="kwrd">return</span> 0;
            <span class="kwrd">return</span> (<span class="kwrd">int</span>)o;
        }
        set
        {
            Session[<span class="str">"MEMBRE_ID"</span>] = <span class="kwrd">value</span>;
        }
    }
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</blockquote>
<p>Avec ça, plus jamais de "InvalidCastException" - enfin, si je ne me suis pas trompé dans l'écriture de la classe :) - et vous risquez moins de problème qu'à tout stocker en string (je pense principalement à des soucis d'injection sql...). Sans parler du fait que vous ne chercherez plus si vous avez appelé votre variable "MEMBRE_ID", "IdMembre", "MEMBREID", ou tout autre variation...</p>
<p>Dans le même ordre d'idée, <strong>ne réalisez jamais les updates sans typer vos variables</strong> : à moins de réaliser une application poubelle et donc d'utiliser le RAD à 100%, vous avez probablement écrit des méthodes (si ce n'est des objets) pour l'implémentation de vos règles métiers et de vos accès aux données. Bien ! mais pitié, <strong>n'utilisez pas des signatures du type</strong> :</p>
<blockquote><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> Membre GetMembre(<span class="kwrd">string</span> membreId)
{
     <span class="rem">// non !!!!!</span>
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</blockquote>
<p>lorsque <strong>vous savez que membreId est un int</strong>, cela fait désordre. Lorsque je vois ce genre de signature, cela m'effraie toujours un peu : si le développeur n'a même pas été capable de typer ses variables, il y a peu de chance qu'il ai fait des requêtes paramétrées, et c'est donc une porte ouverte à l'injection SQL...</p>
<p>Si <strong>vous avez des cas complexes</strong> dans vos règles de gestion, <strong>découpez le problème en différentes méthodes</strong> axées chacune sur la résolution d'un problème simple. Ce conseil la, je pensais vraiment que tout le monde l'avait en tête, mais je me trompais lourdement... Toujours sur le même exemple (oui, cela pourrait être un cas d'école cet extranet, pour le cours "programmez comme des pieds, c'est mieux !"), l'application présente une menu général dont les fonctionnalités changent en fonction de critères multiples (droits accordé à un client, type de structure dont il fait partie, etc.), voici (extrêmement simplifiée) la façon dont cela est traité :</p>
<blockquote><pre class="csharpcode"><span class="kwrd">string</span> matricePossibilite = <span class="str">""</span>;
matricePossiblite += Session[<span class="str">"MEMBRE_TYPE"</span>].ToString();
matricePossibilite += Session[<span class="str">"..."</span>].ToString();
<span class="rem">// il y a encore 3 autres criteres comme ceci...</span>

<span class="kwrd">switch</span> (matricePossibilite)
{
    <span class="kwrd">case</span> <span class="str">"11012"</span>:
        <span class="rem">// une bonne cinquentaine de lignes de code</span>
        <span class="kwrd">break</span>;

    <span class="kwrd">case</span> <span class="str">"21012"</span>:
        <span class="rem">// d'autres lignes...</span>
        <span class="kwrd">break</span>;
}</pre></blockquote>
<p>Non, non, vous ne rêvez pas, c'est bel est bien écrit comme cela, avec un minimum de commentaires, pour la plupart inutiles d'ailleurs, histoire de simplifier l'affaire... Hormis le fait que tout le code se trouve dans la même méthode, c'est aussi typiquement le cas ou un switch est une très mauvaise idée : cela rends plus difficile à lire. Admettons que l'on garde le switch pour une premiere ré-écriture, il est déjà plus qu'obligatoire de virer toutes ces lignes de codes :</p>
<blockquote><pre class="csharpcode"><span class="kwrd">string</span> matricePossibilite = <span class="str">""</span>;
matricePossibilite += Session[<span class="str">"MEMBRE_TYPE"</span>].ToString();
matricePossibilite += Session[<span class="str">"..."</span>].ToString();
<span class="rem">// il y a encore 3 autres critères comme ceci...</span>

<span class="kwrd">switch</span> (matricePossibilite)
{
    <span class="kwrd">case</span> <span class="str">"11012"</span>:
        NomDuCasNumero1();
        <span class="kwrd">break</span>;

    <span class="kwrd">case</span> <span class="str">"21012"</span>:
        NomDuCasNumero2();
        <span class="kwrd">break</span>;
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</blockquote>
<p>C'est déjà un poil plus lisible... Il reste ensuite, soit à bien documenter ce que signifie chacun des cas :</p>
<blockquote><pre class="csharpcode"><span class="kwrd">case</span> <span class="str">"11012"</span>:
<span class="rem">// l'utilisateur est de type ...</span>
<span class="rem">// dans une structure ....</span>
<span class="rem">// etc</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</blockquote>
<p>Ou même encore mieux : ne pas utiliser de variable bizarre pour déterminer les droits mais des <strong>variables avec des noms compréhensibles</strong> :</p>
<blockquote><pre class="csharpcode"><span class="kwrd">bool</span> estAdmin = SessionHelper.MembreType == MembreType.Admin;
TypeStruct type = SessionHelper.TypeStructure;
<span class="rem">// les autres critères selon le même principe</span>

<span class="kwrd">if</span>(estAdmin)
{
    <span class="kwrd">if</span>(...) <span class="rem">// un autre critère</span>
        NomDuCasNumero1();
    <span class="kwrd">else</span>
        NomDuCasNumero2();
}
<span class="kwrd">else</span> <span class="kwrd">if</span>(!estAdmin &amp;&amp; type==TypeStruct.Type1)
{
    NomDuCasNumero3();
}
<span class="rem">// etc.</span>
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</blockquote>
<p>C'est un peu plus verbeux, et <strong>cela demandera</strong> certainement <strong>un peu de réflexion pour ne pas tomber dans une liste de if/else if ou une cascade de if imbriqués</strong> - pensez de nouveau à découper en plusieurs méthodes si vous avez trop de if... - mais qu'est-ce que c'est plus simple à comprendre !</p>
<p>Si <strong>vous êtes adepte des procédure stockées</strong> (ce n'est pas mon cas, mais bon, tous les goûts sont dans la nature...), <strong>n'hésitez pas à les nommer proprement</strong> : mbr_s c'est bien comme nom mais MembreSuppr c'est carrément plus lisible... et tant qu'à faire, pensez à définir des méthodes-metier dont les noms sont en relation avec celui de la proc-stock.</p>
<p>&nbsp;</p>
<p>Voila, ce sont les quelques conseils/remarques qui me sont venus à l'esprit au cours des heures passées à me battre avec cette application. Pour résumer :</p>
<ul>
<li>la plupart des langages actuels sont fortement typés (cela n'a pas que des avantages, mais évite certains dérapages...), assurez vous donc que votre code en soit conscient et compense automatiquement les cas où le typage est plus léger (pour asp.net, il faut comprendre par là : tout ce qui à été conservé compatible avec asp...) 
<li>votre code doit pouvoir être compris dans son ensemble par un autre développeur sans avoir à lire 2000 pages de document Word ou sans avoir besoin de lire dans vos pensées, un peu de commentaires et surtout un code lisible qui peut se comprendre facilement est très souvent préférable à un code plus optimisé - ou du moins qui vous paraît plus optimisé. 
<li>ah...oui... pour avoir eu aussi un problème de code source livré différents de l'application en production : utilisez un système de gestion de source : il est rageant de devoir décompiler la version de production pour retrouver des bouts de code...</li></ul>
<p>Et pour thierry, si il passe sur ce billet : essayez de trouver un prestataire qui ne soit pas en carton pour la prochaine fois :)</p>]]></description><guid>http://michael.carbenay.info/post-378.htm</guid></item><item><title>Une médaille d'or pour Silverlight 2 ?</title><link>http://michael.carbenay.info/post-375.htm</link><pubDate>Tue, 19 Aug 2008 00:48:37 GMT</pubDate><description><![CDATA[<p>Après le "proof of concept" qu'étais Silverlight premier du nom, il semblerait que la v2 (qui, soit dit en passant, est une petite merveille pour les développeurs) soit en train de marquer des points pour sa première utilisation grandeur nature ! Vous ne le savez peut-être pas, mais NBC a confié la rediffusion des J.O. de Pékin au travers de leur site Internet à une application Silverlight, et jusque là, tout se passe bien. Avec 250TB de données streamée sur une seule journée, on peut se dire que l'architecture mise en place par MS pour la distribution vidéo à l'air de bien tenir ! N'oublions pas, en effet, que le streaming multimédia est la partie la plus mise en avant pour Silverlight et ses services hébergés. </p> <p>Rappelons aussi que Silverlight 2 n'est pas encore terminé, et qu'on l'attends pour dans quelques semaines, mais, si les chiffres sont exacts et se maintiennent, le taux de problèmes rencontrés est très faible et c'est extrêmement encourageant pour tous ceux qui souhaitent faire des applications RIA et qui en ont un peu marre d'Action Script !</p> <p>via <a href="http://arstechnica.com/journals/microsoft.ars">Ars Technica</a></p>]]></description><guid>http://michael.carbenay.info/post-375.htm</guid></item><item><title>A la recherche d'un task switcher</title><link>http://michael.carbenay.info/post-372.htm</link><pubDate>Wed, 13 Aug 2008 17:28:46 GMT</pubDate><description><![CDATA[<p>A la recherche d'un bon task switcher - pour power user - j'ai fini cet après midi par installer un clone de Exposé, en me demandant franchement si - pour mon type d'utilisation - cela n'allait pas tourner au cauchemard. Pour le peu que j'utilise la plateforme MacOS, exposé ne me sert quasiment jamais : je conserve rarement plus de deux ou trois fenêtres ouvertes, c'est plus rapide de déplacer les fenêtres pour retrouver celle qui m'initeresse. Mais ne boudons pas notre plaisir, les quelques fois où je m'en sert c'est pratique et très joli.</p> <p>Donc, installation d'un clone de exposé, disais-je... Je ne le citerai pas - vu que je ne vais pas en dire que du bien - mais bon, il n'y en a pas de masses et si je vous dit qu'il est payant vous devriez facilement le retrouver :). L'installation se fait sans trop de soucis, et je suis même impressionné par le fait qu'il s'installe par défaut en mode "user" et n'accède donc pas à Program Files. Quel dommage par contre qu'il s'installe dans le profil itinérant, même si il est assez léger, ce n'est quand même pas la place pour installer un logiciel... Le premier démarrage est un peu laborieux : pour pouvoir afficher le contenu des fenêtres - et bien que je sois sous vista (évidemment) qui propose tout ce qu'il faut pour éviter cela - le logiciel se sent obligé de me les ré-ouvrir toutes... Après un petit passage par les options, il est enfin prêt à m'afficher mes fenêtres en mode exposé-like. Voila le résultat :</p> <p align="center"><a href="http://files.blog-engine.net/1/15705.jpg"><img height="312" alt="sous-exposelike" src="http://files.blog-engine.net/1/16740.jpg" width="500" border="0"></a></p> <p>Hormis l'affichage des fenêtres qui est d'une qualité douteuse et un placement un peu moins bon que celui de son modèle, je me rends ici compte d'une très grosse erreur de ma part : comme je suis allergique aux "virtual desktop" (parce que je passe mon temps à chercher entre les différents bureaux...), le nombre de fenêtres - et franchement, il y en a moins que d'habitude - est bien trop grand pour ce type de présentation.. Par comparaison, même Flip 3D semble moins inquiétant et pourrait même être plus pratique - quoique beaucoup plus long puisqu'il faut passer sur chaque fenêtre une à une - :</p> <p>&nbsp;</p> <p align="center"><a href="http://files.blog-engine.net/1/16684.jpg"><img height="312" alt="sous-flip3D" src="http://files.blog-engine.net/1/20336.jpg" width="500" border="0"></a></p> <p>Enfin, tout ça pour dire que si vous connaissez un bon taskswitcher qui soit intuitif même lorsque l'on utilise de nombreuses fenêtres, n'hésitez pas à laisser un commentaire.</p>]]></description><guid>http://michael.carbenay.info/post-372.htm</guid></item><item><title>Une image en background sur un moteur de recherche ? on aura tout vu !</title><link>http://michael.carbenay.info/post-371.htm</link><pubDate>Wed, 06 Aug 2008 16:04:21 GMT</pubDate><description><![CDATA[<p>Depuis quelques jours, la version US de live.com a quelque peu changé : elle affiche maintenant une (jolie) image en fond, avec quelques hotspots contextuels... c'est p'tet pas hyper utile, mais c'est assez joli, ça change du fond blanc rébarbatif de google.</p> <p align="center"><a href="http://files.blog-engine.net/1/7990.png"><img height="309" alt="image" src="http://files.blog-engine.net/1/34760.png" width="500" border="0"></a></p>]]></description><guid>http://michael.carbenay.info/post-371.htm</guid></item><item><title>décidément... web 2 - ergo 0</title><link>http://michael.carbenay.info/post-364.htm</link><pubDate>Tue, 08 Jul 2008 22:01:55 GMT</pubDate><description><![CDATA[<p>Après la banque il y a quelques jours, c'est l'hébergement web qui est à l'honneur ce soir... enfin à l'honneur, c'est beaucoup dire !</p> <p>OVH héberge la plupart de mes noms de domaines, et alors que, pour mes clients/partenaires, j'utilise mon propre serveur DNS, ce soir, après avoir acheté un domaine à titre personnel, j'ai voulu configurer mes hosts &amp; alias. Beeeeenn... c'est pas gagné !</p> <p>Premier point désagréable : mon hébergeur (je suis pourtant plutôt satisfait de leurs services, mais leur ergonomie est à revoir) a créé automatiquement une tonne de CNAME dans mon domaine, qui vont de imp.ledomainekivabien.com à jabber.ledomainekivabien.com... je ne sais pas - enfin si je sais, plus ou moins, mais je n'ai jamais utilisé - ce que sont imp et jabber, mais franchement, que voulez-vous que j'en fasse ? Alors zou, premiere phase, on les vire... un par un... avec un bazillon d'écran de validation (plus que pour installer un soft sous Vista, c'est dire...). Commençons par virer les éléments les plus simples :</p> <p>D'abord un clic sur l'îcone supprimer dans la liste :</p><a href="http://files.blog-engine.net/1/8902.jpg"></a> <p align="center"><a href="http://files.blog-engine.net/1/9776.jpg"><img height="88" alt="pas-ergo-1" src="http://files.blog-engine.net/1/32950.jpg" width="511" border="0"></a>&nbsp; </p> <p>puis forcément, la page de validation :</p> <p align="center"><a href="http://files.blog-engine.net/1/46365.jpg"><img height="242" alt="pas-ergo-2" src="http://files.blog-engine.net/1/1599.jpg" width="532" border="0"></a> </p> <p>puis une boite de validation...</p> <p align="center"><a href="http://files.blog-engine.net/1/30172.jpg"><img height="221" alt="pas-ergo-3" src="http://files.blog-engine.net/1/40805.jpg" width="430" border="0"></a> </p> <p>Multipliez ça, par les 8 ou 9 alias DNS qui sont définis et savourez :)</p> <p>Ca ne vous a pas énervé, juste en imaginant ? Aors on continue avec le plus grandiose de tous : la suppression de l'enregistrement MX ! C'est l'extase, cela commence (après le clic sur l'îcone supprimer) par un dialog d'avertissement :</p> <p align="center"><a href="http://files.blog-engine.net/1/1438.jpg"><img height="186" alt="pas-ergo-5" src="http://files.blog-engine.net/1/12070.jpg" width="515" border="0"></a></p> <p>Puis la fenêtre de validation : </p> <p align="center"><a href="http://files.blog-engine.net/1/32462.jpg"><img height="235" alt="pas-ergo-6" src="http://files.blog-engine.net/1/34914.jpg" width="538" border="0"></a> </p> <p>On continue avec confirmation puis un bon gros message d'erreur :</p> <p align="center"><a href="http://files.blog-engine.net/1/9127.jpg"></a>&nbsp;<a href="http://files.blog-engine.net/1/1820.jpg"><img height="212" alt="pas-ergo-7" src="http://files.blog-engine.net/1/30393.jpg" width="415" border="0"></a></p> <p align="center"><a href="http://files.blog-engine.net/1/48003.jpg"><img height="279" alt="pas-ergo-8" src="http://files.blog-engine.net/1/4276.jpg" width="500" border="0"></a>&nbsp; </p> <p>Il ne reste plus qu'a cocher la case "Forcer l'opération" et à recommencer avec la boite de dialogue de confirmation :</p> <p align="center"><a href="http://files.blog-engine.net/1/29028.jpg"><img height="212" alt="pas-ergo-7" src="http://files.blog-engine.net/1/47842.jpg" width="415" border="0"></a> </p> <p>là, si vous n'avez pas encore tué femme et enfants, vous avez enfin réussi à supprimer l'enregistrement MX...</p> <p>Formidable, non ?</p>]]></description><guid>http://michael.carbenay.info/post-364.htm</guid></item><item><title>Quand je vous disais que je n'étais pas un cas désespéré...</title><link>http://michael.carbenay.info/post-363.htm</link><pubDate>Sat, 05 Jul 2008 17:38:23 GMT</pubDate><description><![CDATA[<p>J'ai fait que 62% au "<a href="http://www.oneplusyou.com/bb/geek">geekotest</a>"...</p> <p align="center"><a style="display: block; background: url(http://www.oneplusyou.com/bb/css/img/quiz/geek_badge.jpg) no-repeat; width: 268px; height: 82px; text-decoration: none" href="http://www.oneplusyou.com/bb/geek"><span style="display: block; padding-left: 125px; font-size: 22px; color: #000; padding-top: 28px; font-family: arial">62% Geek</span></a></p>]]></description><guid>http://michael.carbenay.info/post-363.htm</guid></item><item><title>Super ergonomie !</title><link>http://michael.carbenay.info/post-362.htm</link><pubDate>Tue, 01 Jul 2008 11:12:32 GMT</pubDate><description><![CDATA[<p>J'ai de plus en plus de mal à supporter les interfaces bâclées de la plupart des sites webs... Preuve encore ce matin, avec le site de ma banque - que je ne citerai pas - et leur module de gestion des virements.</p> <p>Réaliser un virement se fait en deux étapes (enfin, pour les destinataires connus, parce que pour ajouter un nouveau compte, direction votre agence, c'est quand même plus pratique de devoir faire 10 bornes..., mais passons) :</p> <ol> <li>D'abord la saisie d'un mot de passe pour sécuriser cette partie, c'est plutôt une bonne idée, pour - par exemple - une société cela permet de séparer le droit de visualisation de celui de réaliser des opérations</li> <li>Puis viens l'écran de définition du virement en lui même</li></ol> <p>Tout va bien, me direz vous ? oui... mais non...</p> <p>La page de saisie du mot de passe ressemble à ça :</p> <p><a href="http://files.blog-engine.net/1/10066.jpg"><img height="149" alt="bpn-pas-ergonomique-1" src="http://files.blog-engine.net/1/46651.jpg" width="430" border="0"></a> </p> <p>Quant à celle de saisie des informations, elle se termine comme ceci :</p> <p align="center"><a href="http://files.blog-engine.net/1/33236.jpg"><img height="138" alt="bpn-pas-ergonomique-2" src="http://files.blog-engine.net/1/35250.jpg" width="354" border="0"></a>&nbsp;</p> <p>Les boutons accepter/annuler sont inversés entre les deux écrans. J'ai du m'y reprendre a 3 fois pour valider... grrrr. et je ne parle pas de la différence d'aspect des boutons, parce qu'il y a plus grave :p</p> <p>Tout cela pour dire : l'ergonomie ce n'est pas fait pour les chiens, et dans le cas qui nous occupe, il faut au moins décider une fois pour toute si vous mettez les boutons "confirmer" à gauche ou à droite (à gauche c'est mieux, c'est comme cela que l'on est pour la plupart habitués, puisque c'est le sens habituels des boutons sous Windows) des boutons "annuler".</p>]]></description><guid>http://michael.carbenay.info/post-362.htm</guid></item><item><title>ah ouais... quand même...</title><link>http://michael.carbenay.info/post-361.htm</link><pubDate>Mon, 30 Jun 2008 00:27:01 GMT</pubDate><description><![CDATA[<p>Merci <a href="http://www.imazine.fr">Benoît</a> pour le lien :p</p> <p>&nbsp;</p> <div> <center><embed src="http://www.dailymotion.com/swf/x5x55e&amp;related=1" width="420" height="336" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"></embed><br></center></div> <p>Update : Arfff.... grilled ! <a title="http://www.imazine.fr/2008-06/video/pub-hp-touchsmart-pc-cest-du-lourd/" href="http://www.imazine.fr/2008-06/video/pub-hp-touchsmart-pc-cest-du-lourd/">http://www.imazine.fr/2008-06/video/pub-hp-touchsmart-pc-cest-du-lourd/</a></p>]]></description><guid>http://michael.carbenay.info/post-361.htm</guid></item><item><title>Conseils pour une présentation/formation réussie</title><link>http://michael.carbenay.info/post-356.htm</link><pubDate>Thu, 26 Jun 2008 06:23:37 GMT</pubDate><description><![CDATA[<p>Il y a déjà pas mal de temps (ah oui, 5 ans, tout de même...), Scott Hansleman donnait un <a href="http://www.hanselman.com/blog/content/radiostories/2003/01/22/scottHanselmansTipsForASuccessfulMsftPresentation.html">certain nombre de conseils pour la réalisation du présentation/formation technique</a>. Heureusement, il ne s'est pas arrêté là, et les a <a href="http://www.hanselman.com/blog/11TopTipsForASuccessfulTechnicalPresentation.aspx">remis à jour il n'y a pas bien longtemps</a>. Pour résumer (et hormis l'inévitable "essayez au moins de connaître un minimum votre sujet"), voici les remarques que je trouve les plus pertinentes - un peu remis à ma sauce - :</p> <ul> <li><strong>Utilisez des machines virtuelles pour vos présentations.</strong> Cela a deux gros intérêts : le premier, comme scott le suggère c'est d'avoir une solution de remise à zéro simple et rapide. Le second, encore plus intéressant, c'est de pouvoir laisser aux techniciens venus assister à la démo un environnement complet qu'ils pourront utiliser pour reproduire votre démonstration et/ou approfondir, sans avoir à se soucier de trouver un serveur, de prendre le temps d'installer etc. De quoi <em>Passer pour un dieu</em><font size="1">(TM)</font> . J'ai pour habitude de mettre ces machines virtuelles sur un disque USB (et depuis peu e-sata) mais rien ne vous empêche de graver un ou deux DVDs (et de pleurer sur le peu de données que l'on peut mettre sur 4.7go...)  <li><strong>Ne courrez pas au travers de la pièce pour faire avancer vos slides.</strong> J'ai utilisé aussi bien le <a href="http://www.logitech.com/index.cfm/mice_pointers/presentation_remote/devices/175&amp;cl=fr,fr">Cordless Presenter de Logitech</a> que la <a href="http://www.microsoft.com/france/hardware/mouseandkeyboard/productdetails.aspx?pid=085">Presenter Mouse 8000 de Microsoft</a>, et franchement, c'est vraiment indispensable. Nous ne pouvons pas tous être Steve Jobs et avoir quelqu'un juste là pour faire avancer la présentation, donc optez pour une solution vous permettant de ne pas avoir à vous pencher sur votre notebook. (Pour info, j'aime beaucoup l'horloge du Cordless, cela permet de ne pas trop dépasser le temps prévu)  <li><strong>Réduisez au maximum le "bruit" de vos interfaces</strong>. Vous avez 17 toolbars personnalisées dans l'application ? Oubliez les pour vos présentations : elles ne feront que surcharger l'écran pour pas grand chose. Rappelez vous que votre contenu devra être visible de loin donc que la quantité d'informations présentées doit être réduite. Tant que vous y êtes, en plus de supprimer les toolbars inutiles, regardez si vous pouvez changer la taille de police et ou le paramêtre dpi de Windows pour rendre le texte plus lisible à distance. (Si vous essayez de changer les dpi pour mettre en "grande police" selon la terminologie XP, soyez sûr de refaire un tour complet de votre présentation, peu d'applications supportent ce genre de plaisanterie sans faire n'importe quoi)</li></ul>]]></description><guid>http://michael.carbenay.info/post-356.htm</guid></item><item><title>HP Touchsmart... whhhhaaa ! et mon module domotique (beaucoup moins whhhhaaaa)</title><link>http://michael.carbenay.info/post-355.htm</link><pubDate>Wed, 25 Jun 2008 18:22:13 GMT</pubDate><description><![CDATA[<p><img height="180" alt="touchesmart" src="http://files.blog-engine.net/1/43808.jpg" width="240" align="left" border="0"> Si vous ne connaissez pas encore le Touchsmart d'HP, je vous invite à aller faire un p'tit tour sur le <a href="http://www.hp.com/touchsmart">site de présentation</a>, c'est assez sympa ! Avec l'iPhone, Surface et tout le buzz (et réussite commerciale dans le cas de l'iPhone) que ces deux produits ont générés, il ne restait plus très longtemps avant que les premières interface touch pour PC pointent le bout de leur nez !</p> <p>La démo est assez convaincante, même si la possibilité de "resizer" les bloc du haut avec plusieurs doigts semble un peu ajoutée juste pour montrer que c'est du multi-touch :)</p> <p>Quoiqu'il en soit, ca m'a redonné l'envie (mais malheureusement pas le temps) de retravailler un peu sur l'interface touch que j'utilise pour ma domotique. Bon, c'est clair que ca n'a pas le look ni la finition du produit de HP, mais même si ce n'est pas satisfaisant au niveau graphique, c'est quand même bien utile, que ce soit à partir d'un UMPC ou d'un ecran touch.</p> <p align="center"><a href="http://files.blog-engine.net/1/10616.jpg"><img height="354" alt="domotique" src="http://files.blog-engine.net/1/32043.jpg" width="500" border="0"></a></p> <p align="center"><font size="1">Screenshot réalisé sur la version de test du module domotique</font></p>]]></description><guid>http://michael.carbenay.info/post-355.htm</guid></item><item><title>PARC, retiens bien ce terme : PARC...</title><link>http://michael.carbenay.info/post-354.htm</link><pubDate>Sun, 22 Jun 2008 23:50:30 GMT</pubDate><description><![CDATA[<p>Bon, c'est presque un message personnel - à Seb, qui se reconnaîtra -, mais puisqu'il est quasiment impossible de discuter avec les fanboys Apple...</p><a href="http://en.wikipedia.org/wiki/PARC_%28company%29">PARC, mon gars, retiens bien ces 4 lettres : PARC</a>  <p>Ah... oui et retiens aussi <a href="http://en.wikipedia.org/wiki/Xerox_Alto">Alto</a>...</p> <p>Pour ceux que ça intéresse, PARC - à l'époque Xerox PARC (Palo Alto Research Center) - est l'inventeur de (presque) tout ce qui fait l'informatique telle que nous la connaissons aujourd'hui : souris, affichage &amp; interface graphique, l'affichage Wysiwyg, les Remote Procedure Call, la programmation objet (enfin, en tout cas le premier langage objet qui ai tenu le coup : smalltalk)...</p>]]></description><guid>http://michael.carbenay.info/post-354.htm</guid></item><item><title>Un an et demi avec Vista</title><link>http://michael.carbenay.info/post-352.htm</link><pubDate>Tue, 27 May 2008 16:43:32 GMT</pubDate><description><![CDATA[<p>Bon, eh bien cela fait un an et demi que j'ai installé vista... Le temps est venu de faire le constat sur ce qui s'est bien passé, ce qui me plaît et ce qui m'enerve sur cet OS... Bon, bien évidemment, comme tout le monde sait que je suis (presque) un fanboy de Microsoft,vous ferez ce que vous voulez de mon opinion :)</p> <p>Les bons côtés</p> <ol> <li><strong>La recherche intégrée au menu démarrer</strong>. On l'avait vu en 2003, au PDC (enfin disons plutôt qu'on l'avait vu sur les vidéo APRES le PDC), avant SpotLight et Google Desktop Search, mais ne plus avoir à aller dans ce très énervant écran de recherche pour se servir de l'indexation des fichiers c'est quand même l'extase. Surtout qu'au passage, le moteur d'indexation - déjà présent dans XP, et je me demande même si il ne l'était pas dans Windows 2000 - est plus intelligent : il indexe aussi le menu démarrer, les e-mails etc.  <li><strong>Le volet de prévisualisation</strong>. On se croirait un peu revenu au temps de Windows 95 - ou de 98, je ne sais plus lequel contenait quickview - avec cette fonctionnalité, même si elle est mieux intégrée. Pour la plupart des fichiers "standards" (images, videos, texte, et bien d'autres en ajoutant de nouveaux filtres), vous n'avez plus besoin d'ouvrir l'application associée pour visualiser le contenu : il s'affiche directement dans l'explorateur  <li><strong>.net 3.0 intégré au système</strong>. Pas besoin d'en dire plus : .net rocks !  <li><strong>UAC</strong>. Je dois bien être le seul utilisateur qui trouve qu'UAC&nbsp; est une véritable merveille, mais bon : ne plus avoir à utiliser des scripts du type MakeMeAdmin.bat pour effectuer des changements "administratifs" ça n'a pas de prix. En effet, si vous n'aviez pas la mauvaise habitude de travailler en administrateur sur vos machines, vous verriez qu'UAC est vraiment sympa en retirant tous ces passages compliqués du compte "normal" au compte "admin".  <li><strong>Media Center intégré</strong>.  <li><strong>Superfetch</strong>. On mets pas mal de temps à en voir l'interêt mais en fait, c'est pas mal du tout : superfetch se charge de "pré-charger" une partie de vos applications habituelles en mémoire... impressionant comment cela améliore le premier démarrage des grosses applications, du type Office.</li></ol> <p>&nbsp;</p> <p>Les trucs énervants</p> <ol> <li><strong>C'est quand même super gourmand</strong>. Si vous voulez vraiment profiter de vista, exit les vieux PCs, ce n'est même pas la peine d'y songer. Pour que vista soit à son aise, prévoyez un strict minimum de 2go de mémoire et un bon processeur (heureusement que le double core se retrouve presque partout). Bon d'un autre coté, cela fait plus d'un an que (mis à part peut-être la mémoire, mais à 20€ le Go/25€ pour les portables, ce n'est pas hors de prix...) ce type de configuration se retrouve partout.  <li><strong>Les redémarrages de Windows Update ne peuvent pas être annulés</strong> (enfin pas par les utilisateurs "non-administrateurs"). Ca c'est vraiment pénible sur mes PCs hors domaine - ceux faisant partie du domaine (et donc servant au boulot) ont une stratégie d'application des patchs spécifiques - et a fait que j'ai repassé mes utilisateurs en administrateur, ce qui est un peu dommage, surtout qu'il aurait suffit d'un prompt UAC...  <li><strong>L'aspect Glass</strong> : la c'est purement affaire de gout, mais je n'aime pas les nouvelles bordures et barre de titre des fenetres, je trouve cela disgracieux - pas autant que l'effet alu brossé de MacOS, mais quand même très moche. J'aimais beaucoup l'aspect playskool de Windows XP  <li><strong>nVidia</strong>. Oui, bon, c'est facile de toujours taper sur eux, mais ils l'ont cherché... 8 mois avant de sortir un driver potable, c'est long !  <li>En parlant drivers, d'ailleurs, <strong>l'impossibilité d'utiliser les drivers XP pour certains composants/périphériques</strong> (imprimantes, son, etc) est assez pénible, surtout quand la société qui a fait votre carte son 7.1 est inscrite aux abonnés absents...</li></ol>]]></description><guid>http://michael.carbenay.info/post-352.htm</guid></item><item><title>WPF : laisser le designer libre de faire ce qu'il veut !</title><link>http://michael.carbenay.info/post-351.htm</link><pubDate>Thu, 22 May 2008 08:19:39 GMT</pubDate><description><![CDATA[<p>Dans un billet précédent, je vous faisait part d'une grande découverte que nous avions fait lors du développement de nos applis WPF : <strong>Vos développeurs vont devoir oublier une bonne partie de ce qu'ils savent sur l'écriture d'une application</strong> ! Eh bien, pour que cela soit un peu plus parlant, voici un exemple.</p> <p><em>NB : tous les codes fournis dans cet article ne sont pas à utiliser dans l'état, et présentent juste une façon naïve et simplifiée à outrance des concepts que je souhaite démontrer. A vous de compléter&nbsp; tout cela par les habituelles optimisations, gestion d'erreurs etc.</em></p> <p>Imaginons que vous ayez à afficher dans un écran une liste de clients, en Windows Forms, cela devrait ressembler plus ou moins à cela :</p><pre><span style="color: #008000">// ...</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Search(<span style="color: #008000">/* ... */</span>)
{
    List&lt;Client&gt; clients = MonObjetMetier.Search(<span style="color: #008000">/* ... */</span>);
    listView1.Items.Clear();
    <span style="color: #0000ff">foreach</span> (Client c <span style="color: #0000ff">in</span> clients)
    {
        ListViewItem it = listView1.Items.Add(c.Nom);
        it.SubItems.Add(c.CodePostal);
        it.Tag = c;
    }
}
<span style="color: #008000">// ...</span>
</pre>
<p>Une méthode Search(), qui raffraichit une liste- bon, évidemment, dans la vraie vie vous auriez fait quelque chose de plus complexe pour utiliser le multi-threading ainsi que pour éviter le listview1.Items.Clear() - et cela roule. Maintenant, imaginez que vous ayez la même chose à faire en WPF... bien sûr, la même technique est parfaitement utilisable, mais vous n'allez pas vous faire aimer de votre designer : il aura besoin de vous ne serait-ce que pour échanger l'ordre des colonnes !</p>
<p>La première chose à faire, c'est de ne plus réflechir en terme de "texte affiché" mais en terme "d'objet affiché" : ce n'est pas à vous, en tant que développeur, de décider ni où, ni comment seront affichés (si ils le sont) les codes postaux ! Contentez-vous de vous dire que l'écran affiche des clients, et laissez quelqu'un d'autre se charger de la présentation. </p><pre><span style="color: #008000">// ...</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Search(<span style="color: #008000">/* ... */</span>)
{
    List&lt;Client&gt; clients = MonObjetMetier.Search(<span style="color: #008000">/* ... */</span>);
    listView1.Items.Clear();
    <span style="color: #0000ff">foreach</span> (Client c <span style="color: #0000ff">in</span> clients)
    {
        listView1.Items.Add(c);
    }
}
<span style="color: #008000">// ...</span>
</pre>
<p>Si vous utilisez cette méthode, le designer pourra assez facilement modifier la façon dont seront affichées chacune des lignes de la liste (avec un DataTemplate) et/ou l'apparence globale de celle-ci (par un ControlTemplate ou un ItemsPanelTemplate). En vous arrêtant là, vous aurez déjà fait un gros progrès par rapport à WinForms, mais il est possible d'aller beaucoup plus loin : dans l'extrait de code ci-dessus, c'est encore le developpeur qui decide de mettre les données dans la listview. Et si le designer voulait utiliser autre chose qu'une listview ? ? </p>
<p>La deuxieme partie de l'équation est&nbsp; donc d'arrêter, aussi, de réaliser des écrans qui affichent quelque chose : encore une fois "ce n'est pas à vous, en tant que développeur, de décider ni où, ni comment seront affiché[e]s (si [elles] le sont)" les données. Contentez vous de fournir des données (sous la forme de collections, par exemple, à vous d'optimiser la façon dont ses données sont chargées/mise à disposition).</p><pre><span style="color: #008000">// ...</span>
<span style="color: #0000ff">public</span> ObservableCollection&lt;Client&gt; LesClients = ...</pre><pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Search(<span style="color: #008000">/* ... */</span>)
{
    List&lt;Client&gt; clients = MonObjetMetier.Search(<span style="color: #008000">/* ... */</span>);
    LesClients.Clear();
    <span style="color: #0000ff">foreach</span> (Client c <span style="color: #0000ff">in</span> clients)
    {
        LesClients.Add(c);
    }
}
<span style="color: #008000">// ...</span>
</pre>
<p>En écrivant vos programmes de cette manière, vous devriez voir&nbsp; une grande simplification du workflow développeur&lt;&gt;designer, chacun pouvant alors s'occuper de ce qu'il connait le mieux : la gestion des règles métiers et de l'aspect technique ou la représentation des informations et leur manipulation.</p>]]></description><guid>http://michael.carbenay.info/post-351.htm</guid></item><item><title>Extrait de code pour traitement asynchrone en WPF</title><link>http://michael.carbenay.info/post-339.htm</link><pubDate>Sat, 26 Apr 2008 10:03:00 GMT</pubDate><description><![CDATA[<p>Si vous faites un peu de programmation WPF, vous avez certainement dû vous retrouver assez souvent à écrire du code ressemblant à :</p><pre class="code"><span style="color: rgb(43,145,175)">ThreadPool</span>.QueueUserWorkItem
    (<span style="color: rgb(0,0,255)">new</span> <span style="color: rgb(43,145,175)">WaitCallback</span>(<span style="color: rgb(0,0,255)">delegate</span>(<span style="color: rgb(0,0,255)">object</span> ignored)
    {
        <span style="color: rgb(0,128,0)">// un appel à un traitement long comme une requête 
</span>        <span style="color: rgb(0,128,0)">// sql ou un web-service

</span>        Dispatcher.BeginInvoke(
            <span style="color: rgb(43,145,175)">DispatcherPriority</span>.Normal,
            <span style="color: rgb(0,0,255)">new</span> <span style="color: rgb(43,145,175)">WaitCallback</span>(<span style="color: rgb(0,0,255)">delegate</span>(<span style="color: rgb(0,0,255)">object</span> ignored_too)
            {
                <span style="color: rgb(0,128,0)">// le traitement de mise à jour de votre
</span>                <span style="color: rgb(0,128,0)">// controle 
</span>            }
            ), <span style="color: rgb(0,0,255)">null</span>);
    }
    ));
</pre><a href="http://11011.net/software/vspaste"></a>
<p>Je vous propose donc un petit extrait de code qui se charge d'écrire cela à votre place (le bonus étant que les namespaces sont importés automatiquement) :</p>
<ul>
<li>téléchargez le snippet au <a href="http://files.blog-engine.net/1/snippets/wpf-threadtask.vsi">format .vsi</a></li></ul>
<p>Une fois installé, vous pourrez utiliser le snippet <strong>wpfthreadtask</strong> :</p>
<p><a href="http://files.blog-engine.net/1/49620.png"><img height="257" alt="image" src="http://files.blog-engine.net/1/49455.png" width="403" border="0"></a> </p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7d2ae288-32b3-402d-a14a-360a2f0c15d5" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Mots clés Technorati : <a href="http://technorati.com/tags/WPF" rel="tag">WPF</a>,<a href="http://technorati.com/tags/ThreadPool" rel="tag">ThreadPool</a>,<a href="http://technorati.com/tags/.snippet" rel="tag">.snippet</a>,<a href="http://technorati.com/tags/.vsi" rel="tag">.vsi</a>,<a href="http://technorati.com/tags/extrait%20de%20code" rel="tag">extrait de code</a></div>]]></description><guid>http://michael.carbenay.info/post-339.htm</guid></item><item><title>Video sympa sur Surface</title><link>http://michael.carbenay.info/post-338.htm</link><pubDate>Mon, 21 Apr 2008 23:02:09 GMT</pubDate><description><![CDATA[<p>C'est un peu ancien, mais je viens juste de le voir : une démo de l'application AT&amp;T utilisant surface.</p> <p><embed src="http://www.youtube.com/v/fSAVIueUS1M&amp;hl=en" width="425" height="355" type="application/x-shockwave-flash" wmode="transparent"></embed></p>]]></description><guid>http://michael.carbenay.info/post-338.htm</guid></item></channel></rss>