Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

Stratégie de développement Cross-Platform–Partie 1

[new:31/12/2012]Développer cette année c’est forcément développer cross-plateforme. Mieux, c’est développer cross-form factor... Android, iOS, Windows 7, Windows 8, sur PC, tablette, smartphone... Un vrai casse-tête qui peut couter une fortune si on n’adopte pas dès le départ la bonne stratégie et les bons outils. C’est une stratégie opérationnelle avec ses outils que je vais vous présenter dans cette série de billets dont voici la première partie.

Cross-platform, cross-form factor

Développer c’est toujours prendre en compte les extensions et évolutions futures. Donc adopter une stratégie de développement “propre”, claire, maintenable, évolutive. Cela réclame déjà beaucoup de méthode, de savoir-faire et d’expérience.

Mais développer aujourd’hui c’est bien plus que ça...

C’est aussi prendre en compte la diversité des plateformes et des form factors.

Et là, cela devient tout de suite un numéro d’équilibriste, même pour ceux qui maitrisent les impératifs sus-cités.

Nous avons tous nos choix, nos préférences techniques, mais nous avons tous, en professionnels, l’obligation de satisfaire la demande des utilisateurs, des clients et d’intégrer dans nos stratégies de développement la réalité du marché.

La réalité du marché c’est aujourd’hui par exemple 68.1% de parts pour Android sur le segment des smartphones en Europe... Qui peut négliger près de 70% des utilisateurs européens de smartphone ? La réalité du marché c’est l’IPad qui dédient à peu près le même pourcentage de parts au niveau mondial sur le segment des tablettes. Qui peut l’ignorer ? La réalité du marché ce sont des centaines de millions d’utilisateurs de Windows XP et 7 sur toute la planète. Qui peut se permettre de les ignorer ?

Enfin, la réalité du marché c’est Windows 8, du smartphone au PC, arrivant avec retard sur ses concurrents mais avec l’avantage d’une cohérence de gamme très séduisante. Qui peut se permettre le luxe d’ignorer WinRT qui équipera tous les nouveaux PC dès l’annonce du 26 octobre prochain ?

Bref, développer aujourd’hui c’est intégrer le design, MVVM, l’évolutivité, la maintenabilité, mais aussi les différentes plateformes qui se sont imposées dans un partage du marché durable où Windows n’est plus le seul et unique OS car le PC n’est plus le seul et unique type d’ordinateur à prendre en considération.

C’est à cette réalité qu’il faut se préparer. Non, c’est à ce défi technologique qu’il faut être déjà prêt !

Comme tous les ans, j’avais rêvé des vacances les pieds en éventail. J’avais rêvé de pouvoir boucler le mixage de quelques un des dizaines de morceaux que j’ai composés ces dernières années sans avoir le temps de les terminer proprement (il y a bien quelques mix sur ma page SoundCloud mais c’est peu), j’avais prévu mille et une chose futiles ou non. Hélas cet été comme les autres, je me dis que je verrai ça cet hiver. Hélas pour mes rêves mais heureusement pour vous (en tout cas je l’espèce Sourire) je me suis mis en tête de formaliser ma stratégie de développement pour l’année à venir et d’écrire cette série de billets pour vous présenter une solution viable de développement cross-platform et cross-form factor !

My Strategy, for today

Ce que je vais vous présenter est le fruit de mon travail, de ma réflexion sur ce sujet et de mes tests et essais ces derniers mois de nombreux outils, frameworks, unités mobiles, etc. C’est “ma stratégie”, et “pour aujourd’hui”, car le marché et les technologies évoluent et peut-être que l’année prochaine je vous proposerai une autre méthode ou des aménagements ... ou pas.

En tout cas cette stratégie est pérenne, c’est l’un des critères ayant présidé à son élaboration. Il y a aura peut-être mieux à un moment ou un autre, mais pour les mois à venir et les développements à lancer elle restera un très bon choix.

C’est une stratégie qui s’accorde aussi bien aux développements internes en entreprise qu’à une logique éditeur où la couverture maximale du marché est un impératif vital. Le développeur y trouvera son compte autant que le DSI.

J’ai testé de nombreuses approches, comme par exemple ce qu’on appelle “l’hybride” ou même HTML 5. Les méthodes et outils que j’ai fini par assembler dans un tout cohérent dans la stratégie que je vais développer ici ont tous la particularité de répondre à de très nombreuses contraintes. Les outils ou méthodes que j’ai écartés ne sont pas forcément “mauvais” en eux-mêmes, mais ils ne répondent pas à toutes les contraintes que je m’étais posées.

Il s’agit donc bien de “ma” solution pour les développements à lancer “aujourd’hui”, entendez par là pour les mois à venir.

Une contrainte forte : la cohérence

Parmi ces contraintes, la plus forte était la cohérence.

Je veux dire que ma stratégie ne devait pas ressembler à un tableau de Miro ou de Picasso, où la réalité est déstructurée à l’extrême. Ici, en bon ingénieur, je voulais de l’ordre, de la logique, de la lisibilité. Je voulais un puzzle de paysage paisible où chaque pièce s’emboite avec l’autre, l’ajustement devant être parfait ou presque pour former un tout ayant un sens et de la rigueur.

Cette contrainte m’a fait écarter de nombreuses solutions tout simplement parce que la pièce ne trouvait pas sa place dans le puzzle final.

Les solutions écartées peuvent ponctuellement être utilisées avec succès par certains d’entre vous. Ma stratégie n’est pas exclusive, elle admet que d’autres solutions ponctuelles fonctionnent. Pas exclusive mais unique : elle n’accepte que ce qui entre dans le puzzle final avec harmonie. Son originalité, son unicité c’est sa cohérence.

Un But : Unifier ce qui est épars

Le but que je m’étais fixé est issu d’une constatation : il n’existe aucun point commun ni passerelle entre les différentes plateformes à prendre en considération sur le marché : iOS, Android, Linux, Windows 7/Vista, WinRT. Aucun de ces OS n’a prévu une quelconque compatibilité avec les autres. Rien. Et c’est même conçu “pour”.

Unifier ce qui est épars semble un but inaccessible dans une telle condition.

Mais ce que les OS n’ont pas prévu (ni souhaité), ce lien, cette passerelle, on peut la créer grâce à des outils, à du soft.

Le tout étant de trouver le bon package d’outils et de méthodes qui permettent de créer ce lien immatériel unifiant des plateformes si différentes.

Un principe : Concentrer la compétence

Une autre constatation s’impose quand on a commencé à réfléchir à la question et qu’on a commencé à tester différentes choses : aucune technologie existante n’est capable de régler à elle seule le problème dans sa totalité.

La solution ne peut passer que par l’utilisation habile de plusieurs outils et méthodes. Il doit y en avoir un minimum dans la solution. Le foisonnement des outils, des langages, des APIs pour faire un logiciel je n’ai jamais aimé cela. On ne peut être expert en tout et forcément on s’éparpille.

Comme un Laser concentre la puissance de quelques photons inoffensifs pour en faire un outil redoutable d’efficacité et de précision, la stratégie qu’il fallait concevoir se devait de concentrer le savoir-faire du développeur pour maximiser son efficacité et minimiser la dispersion de son expertise.

Les cibles visées

 

Des plateformes, pas des technologies de développement

Les cibles visées sont des plateformes globales, je ne parle pas ici de plateforme de développement, de langages ou de technologies particulières (comme WPF ou Silverlight).

Les cibles

Comme cela a déjà été évoqué ici en divers endroits, les cibles visées par cette stratégie de la “grande unification” sont les suivantes :

  • iOS (tablettes et IPhone)
  • Android (idem)
  • Windows XP, Vista, 7
  • Windows 8 (WinRT sur tablettes, smartphones et PC)
  • Windows Phone 7.x
  • Linux

Apple

Mon désamour d’Apple n’a pas changé, mais il est aujourd’hui en tout cas indispensable de prendre en compte la réalité du phénomène IPad. Autant on peut faire abstraction de l’IPhone qui a perdu pied en Europe, autant sa cousine la tablette domine toujours ses concurrentes. On pourrait discuter des heures des parts de marché que les tablettes WinRT prendront ou bien du succès des tablettes Android qui finiront peut être par éliminé Apple du marché comme les smarphones Android l’ont fait avec l’IPhone. Mais tout cela est trop spéculatif. J’ai préféré prendre la réalité telle qu’elle est. Intégrer l’IPad dans la stratégie était une obligation. De toute façon, WinRT et Android sont aussi pris en compte... La stratégie finale est tellement “englobante” qu’elle supportera tous les réajustements du marché au moins à courts et moyens termes.

Android

Android est une réalité difficile à intégrer pour certains car le phénomène est apparu très vite en venant de l'à où on ne l’attendait pas... Alors il faut le temps que cela “monte” au cerveau. Une fois ce cheminement effectué force est de constater qu’avec presque 70% du marché des smartphones en Europe, Android est devenu tout simplement incontournable. Peu importe ce qu’on en pense, peu importe le succès à venir de WP8. Android est là pour rester. En douter serait une grossière erreur.

Windows classique

Windows XP, Vista et 7 forment une triade aux pourcentages relatifs en évolution (au profit de 7) mais reste un socle solide de plusieurs centaines de millions de PC dans le monde qui ne va pas changer au lendemain du 26 octobre pour du Windows 8. Et Windows 7 étant encore meilleur que XP, je parie qu’il aura la vie aussi longue que son grand frère, notamment en entreprises. Dès lors, difficile de faire l’impasse. Mais là on enfonce des portes ouvertes.

Windows 8

Windows 8 avec WinRT sera la nouveauté de la rentrée. Windows 8 est assurément un bon OS, et pour l’utiliser depuis un moment je peux assurer que l’efficacité technique est au rendez-vous. Je reste toujours circonspects concernant certains choix mais je ne doute pas un instant que la grande cohérence de la plateforme ne finisse par l’imposer. Une même API du smartphone au PC en passant par les tablettes, c’est unique sur le marché et est séduisant. D’autant que WinRT peut se programmer en réutilisant le savoir-faire .NET. Ne pas cibler WinRT serait idiot et dangereux.

WP7

Enfin, Windows Phone 7.x est une plateforme qui si elle n’a pas rencontré un succès immédiat pourrait bien profiter du mouvement positif autour de Windows 8. Après tout c’est une belle plateforme, efficace, riche de nombreuses applications, ayant le même look que ModernUI (alias Metro Style) puisque s’en est la première utilisation. Certes la plateforme sera caduque à la sortie de Windows Phone 8. Oui, mais... WP8 sera compatible avec les anciennes applications WP7. Et selon les marchés il sera peut-être plus futé de développer en Silverlight WP7 pour être compatible avec tous les smartphones Windows qu’en WinRT qui écartera les possesseurs actuels de ces machines (puisqu’on sait que l’upgrade sera impossible). Par exemple WP7 fait environ 5% du marché du Allemagne, selon ce que vous développez pourquoi ignorer ces clients potentiels ? WP7 n’est pas dans ma liste de priorités, mais cela serait une bonne idée de l’intégrer dans la stratégie pour toutes les raisons évoquées.

Linux

Linux, il m’a toujours amusé. Depuis sa création j’entends ses partisans m’annoncer le “grand soir” pour demain, un peu comme Lutte Ouvrière. Ce n’est jamais arrivé. Néanmoins, et j’en avais parlé dans ces colonnes, Android c’est Linux, une base identique à celle de Ubuntu. Et le succès du premier fait que ce dernier tente désormais de revendiquer ses liens de sang avec l’OS de Google.
Après tout, quand une majorité d’Européens possède un smartphone Android, voire une tablette du même OS pour certains, il ne reste plus qu’à leur dire la vérité : c’est du Linux... Alors pourquoi pas un PC sous Ubuntu ? Finalement vous aurez un ensemble cohérent...
Le coup sera peut-être gagnant cette fois-ci. En tout cas si un jour Linux doit se faire une place sérieuse sur le marché, c’est maintenant que cela va se jouer (2013). Si Linux rate cette fantastique occasion, autant dire qu’il restera ce qu’il est depuis toujours : un OS de serveur Web pour ceux qui ne veulent pas payer une licence IIS. Même si cette plateforme n’entre pas dans les priorités de ma stratégie, l’émergence d’Ubuntu comme père spirituel de Android dans un style Star Wars “Android, je suis ton père !” est suffisamment troublant pour se dire que si cela est possible, il serait judicieux d’intégrer un lien Linux avec les autres plateformes ciblées au départ. D’où la présence de Linux dans cette liste. Toutefois cela reste une simple possibilité que je ne couvrirai pas dans l’immédiat mais reste parfaitement envisageable dans le cadre de ma stratégie.

Un rêve ? Non, une réalité !

Quand on regarde cette liste à la Prévert on se dit que c’est un doux délire, qu’il sera impossible de trouver un moyen de créer des applications pour toutes ces plateformes à la fois sans que cela ne coute une fortune en formation et en personnel qualifié...

Et pourtant !

HTML 5 ? Non, vous n’y êtes pas.
Pas de bricolage de ce genre chez moi. Et puis HTML via un browser ce n’est pas ça sur les unités mobiles. j’ai déjà argumenté ici plusieurs fois que cette norme était dépassée par les évènements, que depuis qu’elle a forké c’est encore plus évident, et que sur les unités mobiles c’est le natif qui est roi. L’universalité visée par ma stratégie m’a forcé à rejeter (avec joie et soulagement) cette fausse bonne idée (ou vraie mauvaise idée) qu’est HTML 5. Et puis, vous l’avez remarqué et je l’ai dit : je vise des cibles en tant que plateformes globales, pas une utilisation particulière de l’informatique que sont les browsers.

Donc exit HTML 5 comme solution universelle. Donc out de ma stratégie.

Je ne voulais pas concevoir une stratégie fondée sur des sables mouvants. Il ne s’agit pas d’un rêve, juste d’ingénierie.

Dans la partie 2 vous découvrirez l’écriture d’un projet fonctionnel tournant sur plusieurs des plateformes ciblées avec une seul code et un seul langage.

(le suspens est insoutenable non ?)

Et le Web ?

Toutefois, certains se diront que ma liste pour aussi longue qu’elle soit ne prévoit rien pour le Web.

Le Web est une cible bien à part, qui, on le voit bien à ma liste, ne compte plus que pour une parcelle dans toute cette débauche de nouvelles plateformes. Mais le Web est éternel... Eternel mais plus universel.

Si Microsoft a perdu la suprématie absolue dans le monde des OS avec la naissance d’iOS et Android, le Web a perdu son universalité avec le succès du natif sur ces machines.

Mais je pourrais ajouter à ma liste, par gourmandise, ASP.NET. Pour créer des applications Web professionnelles avec de vrais langages, une vraie plateforme et du HTML 3/4 pour être sûr de passer sur tous les browsers. Cela restera tout à fait compatible avec ma stratégie.

Et pour me faire plaisir, la cerise sur le gâteau, j’ajouterai même Silverlight pour faire de l’Intranet (mais Silverlight est déjà présent dans la liste puisque c’est avec lui qu’on programme WP7).

Il reste qu’il ne faut pas confondre les choses. Ma démarche cible des plateformes techniques différentes. Certes on peut voir le Web comme l’une d’entre elle. Mais du point de vue du développement ce n’est qu’une façon possible parmi d’autres d’utiliser Internet. Je ne mets pas l’accent sur le Web ici pour cette raison. Le Web n’est pas un OS, il n’est pas une plateforme définies clairement, ce n’est qu’une utilisation d’Internet via des logiciels spécifiques (les browsers). Le succès des applications natives sur unités mobiles ou même des données dans le Cloud (DropBox, SkyDrive...) nous prouvent qu’on peut fort bien aller vers toujours plus d’importance d’Internet tout en allant vers moins d’importance pour le Web...

Les effets néfastes de la canicule sur un esprit surmené ?

Bref je vise le monde entier, toutes les plateformes, tous les form-factors ! Façon Cortex et Minus :

“Gee Brain, what do you wanna do tonight ?
The same thing we do every night Pinky, try to take over the world! “

(“hey Brain, qu’est-ce qu’on va faire cette nuit ? – La même chose que nous faisons toutes les nuits Pinky, tenter de conquérir le monde !”)

Quand nous aurons passé cette introduction vous verrez que tout cela est possible et je vous montrerai comment le faire... Si folie il y a c’est peut-être d’avoir cherché une telle stratégie, mais dans les faits elle est on ne peut plus raisonnable et terre-à-terre.

La stratégie

Entre humour et réalité (rappelons que je suis censé être en vacances et qu’il faut bien prendre les choses avec un peu de légèreté) vous me connaissez assez maintenant pour savoir que je n’ai pas tapé toute cette tartine juste pour un joke.

Je préfèrerai siroter un martini “Shaken, not stirred !”  - les amateurs de James Bond auront compris - le tout en appréciant le déhanchement de quelques créatures pulpeuses à Acapulco qu’être rivé derrière mon écran, climatisation à fond et volets fermés pour éviter que les serveurs ne grillent en ces jours de canicules. Franchement. Si, croyez moi.

Après cette introduction essentielle sur mes motivations et le véritable sérieux qui a présidé à tout cela, après avoir préciser les cibles visées, les contraintes, le but, il est tant de présenter cette stratégie et son contenu.

Divide ut regnes !

Nicolas de Machiavel, reprenant ici une expression latine prêtée notamment à Philippe de Macédoine, savait qu’il tenait là l’une des clés du pouvoir. Diviser pour mieux régner, ça marche ! Ca n’a qu’un temps parfois, mais c’est un bon vieux truc qui marche toujours.

Nous aussi, mais en poursuivant des buts plus nobles, nous pouvons utiliser cette méthode.

Divisez pour mieux développer.

C’est avant tout séparer les tiers convenablement.

La base de ma stratégie passe par une segmentation rigoureuse du code d’une application.

  • Le premier segment est un serveur Web qui centralise le code métier
  • Le second segment consiste en la définition des ViewModels dans un projet portable.
  • Le troisième segment ce sont les UI.

MVVM

Séparer du code de l’UI nous savons le faire depuis un moment, ça fonctionne bien si on sait trouver “sa voie” et la bonne librairie pour maitriser sa mise en œuvre.

Ici je pousserai encore plus la séparation imposée par MVVM : les ViewModels et les Models seront définis dans un projet commun que j’appellerai le “noyau” alors que les Vues seront définies dans les projets gérant les UI des différentes plateformes / form factors.

Un langage et un seul

J’aime C# et il se trouve que je l’aime aussi pour sa versatilité et sa capacité à être une base solide pour développer tout type de projets.

C’est donc lui qui sera le fil unificateur en arrière scène.

Une seule plateforme

C# n’est pas un électron libre. Derrière lui se tient aussi le framework .NET. Il sera lui aussi à la base de ma construction pour des milliers de raisons. S’il n’en fallait qu’une : il est complet et permet de tout faire.

Un seul EDI

Pourquoi s’enquiquiner avec différents EDI et langages. Qui dit C# et .NET dit Visual Studio, l’EDI le mieux fait. C’est lui qui sera utilisé de bout en bout. Pour les UI Xaml (WPF, Silverlight, WinRT) j’utiliserai aussi Expression Blend.

Mais plusieurs versions...

Armé de C# et de .NET il ne va guère être facile d’attaquer toutes les plateformes que j’ai listées plus haut...

... Sauf si on trouve un moyen de programmer iOS et Android en C#...

Et ce moyen existe.

Il s’agit de MonoTouch et MonoDroid dont j’ai déjà parlé ici. Deux petites merveilles. MonoDroid qui se pluguent dans VS (avec éditeur visuel intégré désormais), MonoTouch qui s'utilise avec MonoDevelop (copie Mono de VS) sous Mac, le tout  se programmant en C# sur une base Mono de niveau .NET 3/4.

Conçus et vendus par Xamarin dont j’ai aussi parlé ici, ces deux produits permettent de satisfaire toute nos contraintes, dont celle de cohérence.

Un seul EDI, un seul langage, un seul framework, et pas moins de onze cibles touchées !

IPad, IPhone, Android smartphone, Android Tablette, Silverlight, WPF, WinRT smartphone, WinRT tablette, WinRT PC, ASP.NET, et même Linux avec MonoDevelop fourni avec MonoTouch ou MonoDroid.

Onze cibles unifiées grâce à Visual Studio et deux plugins (disponible de façon séparée chez Xamarin).

Cela semble régler le problème mais il n’en ai rien. En tout cas pas totalement. Dans une telle stratégie il n’y a pas que les outils qui compte. Il y a aussi la façon de s’en servir...

On l’a vu, je vais utiliser les principes de MVVM qui, malgré certaines imperfections, reste une méthode solide pour développer des logiciels modernes.

MVVM se base sur le Binding... Or, point de Binding sous Objective-C ni le Java sous Eclipse de Android.

Déception ?

Non. MonoTouch et MonoDroid n’y peuvent rien (ils n’ont rien à avoir avec MVVM), mais en revanche MVVMCross lui peut nous aider à la faire !

Une librairie Cross-platform

Le ciment de base est C# et le framework .NET. Dans leur version Microsoft et leur version Mono. Déclinées dans MonoTouch et MonoDroid.

Avec ce ciment nous pouvons construire les murs porteurs de notre stratégie.

Mais pour le toit, il faut quelque chose capable d’englober toutes ces versions en proposant un toolkit MVVM se chargeant des différences.

Ce toolkit existe, c’est MVVMCross, projet Github qui supporte MonoDroid, MonoTouch, Silverlight, WPF7, le mode console et WinRT.

Bien que jeune, la librairie est fonctionnelle et déjà bien testée.

Un tooling simplifié

Finalement, c’est un tooling ultra simplifié que je vais utiliser. Pour résumer il est formé de :

  • Visual Studio
  • MonoDroid
  • MonoTouch
  • MVVMCross

Un seul EDI. Un ou deux plugins (selon les cibles que vous voulez supporter). Un seul framework MVVM.

Autant dire que mon souhait de réduire au strict nécessaire les outils, langages et EDIs est parfaitement réalisé.

Pour développer il faut au minimum un EDI et un langage, et au moins une librairie de type MVC ou MVVM proposant de l’IoC. Au bout du compte, je n’aurai ajouté que MonoTouch et MonoDroid pour pouvoir compiler et tester les applications destinées aux plateformes non Microsoft. Tout le reste est le minimum vital même pour un seul projet ne ciblant qu’une plateforme.

Le strict minimum. Pari gagné sur ce point.

Explication par l’image

Un dessin valant mille discours :

concept.design

Le serveur “métier”

Une grande partie de la stratégie se trouve ici : créer un serveur contenant le code métier. Ici je parlerai de serveur métier, sous entendant un serveur capable de fournir des services évolués et non pas seulement des opérations CRUD sur les tables d’une base de données.

Le code placé sur ce serveur doit être le plus dense possible, il doit prendre en charge le maximum d’intelligence, de règles métiers, de fonctions de haut niveau.

Tout l’art d’ingénierie qui se trouvera derrière consistera à savoir effectuer un tel découpage des fonctions de haut de niveau et de savoir les exposer en créant une API logique, facile à comprendre et efficace. Par essence, et puisque nous parlons ici de créons des applications natives et non des pages Web, le serveur devra autant que faire se peut rester “stateless”, le “stateful” est géré par les ViewModels côté client. Il reste néanmoins possible d’adapter la stratégie avec un serveur stateful ce qui n’est malgré tout pas sans soulever des questions qui dépassent le cadre de ce billet.

On notera que le “serveur métier” peut dans la réalité se décomposer en plusieurs applications serveur, en plusieurs services. Cela peut même essentiel pour répartir la charge ou pour disposer de serveurs rapides au plus près des clients. Le ou les serveurs métiers peuvent même être dupliqués pour gérer une montée en charge. Les applications serveurs peuvent elles-mêmes faire appel à d’autres services locaux ou distants, il n’y a aucune limite ni contrainte imposée par la stratégie présentée.

Mais il est nécessaire de suivre la logique d’un serveur métier car vous le verrez au travers de l’exemple réel de la Partie 2 c’est la clé de voute de la pérennité du code... Vous comprendrez mieux quand j’aborderai l’exemple concret.

Un noyau, des projets spécifiques

C’est là qu’entre en scène MVVMCross. Grâce à lui nous allons créer un premier projet qui contiendra l’ensemble du code des ViewModels de l’application. On choisira comme base l’OS le plus restrictif. Dans l’exemple que nous verrons ce projet est créé en Mono pour Android version 1.6, autant dire une vieillerie. Mais programmé en .NET 4 (Mono) tout de même.

Ce projet “noyau” ne peut hélas être utilisé directement par tous les OS cibles, ça serait trop simple.

Il s’agit donc ensuite de créer autant de projets qu’il y a de ciblent différentes. Ces projets “bis” ne font que réutiliser tout le code du vrai noyau (sous VS on ajoute un “item existant” avec lien et non par copie).

Au final nous avons des projets Noyau.Android, Noyau.WinRT, Noyau.WindowsPhone, etc... On créé uniquement ceux dont on va avoir besoin bien entendu, et j’insiste, leur code est totalement le même que le noyau “vrai”, seul le fichier projet est différent pour indiquer quel compilateur utiliser.

Bien sûr, ces différentes noyaux donneront naissance à des binaires différents. Mais cela c’est le travail de VS et des compilateurs, nous, de notre côté nous n’avons écrit qu’une seule fois le code !

On acceptera ponctuellement, parce qu’il faut être réaliste, la définition dans chaque projet d’un switch de compilation (par exemple WP7, ANDROID, etc) et la présence de constructions #if s’il n’y a vraiment pas moyen de faire autrement pour conserver le même code. Dans les cas extrêmes, la stratégie permet, même si cela n’est pas souhaitable, de totalement repenser un ViewModel pour une cible en particulier. Sachant que l’essentiel du code intelligent est côté serveur, les ViewModels ne sont pas censés faire beaucoup de choses, les adapter dans certains cas reste une option qui ne remet pas en cause la logique globale.

Grâce à MVVMCross qui lui aussi existe en différentes versions (Android, iOS, WinRT...), le code de nos ViewModels est le même pour toutes les plateformes visées, MVVMCross sait ajouter le Binding aux plateformes ne le gérant pas. Nos classes seront développées comme pour WPF ou du Silverlight, sans aucune différence (sauf l’utilisation de MVVMCross au lieu de MVVM Light ou Jounce par exemple).

Des UI spécifiques

C’est là que les divergences apparaissent, mais seulement arrivé là, en bout de course. En utilisant MVVMCross nous allons créer autant de projets que nécessaires, un par cible visé. Ces projets vont définir les Vues. Chaque projet possède en référence la version ad hoc du Noyau.

Bien sûr, ici il faudra faire du spécifique. Mais la mise en page d’une application Android, iOS ou WinRT reste quelque chose de spécifique lié à la plateforme.

Toutefois grâce à cette stratégie nous avons repoussé au plus loin possible dans le cycle de développement la partie spécifique à chaque OS et nous avons fortement limité l’ampleur du code spécifique.

C’est là que la stratégie est payante...

Un coût maitrisé

La plus grosse partie du code, le code métier, est créée de la façon qu’on préfère. Par cohérence on la codera en C#, mais cela peut être un projet IIS Windows aussi bien qu’un projet Apache Mono sous Linux... Pourquoi pas... Toutes les plateformes, toutes les libertés, c’est ça l’essence de la stratégie présentée ici.

De fait, l’investissement de développement le plus important va se trouver en un seul exemplaire concentré sur le serveur métier. La variabilité assumée pour ce projet central est de 0%, il sera valable pour toutes les cibles sans aucune modification.

Choisir la plateforme (Apache ou IIS) autant que les modalités de transport de données (XML ou JSon) et la façon de sécuriser les accès au service (où au n services du serveur métier) n’a pas d’impact sur la stratégie présentée, je ne développerai pas cet aspect des choses, même s’il est très important.

Ensuite le développement des ViewModels, qui peut être important aussi (mais qui généralement est assez léger puisque le code intelligent est sur le serveur métier), se déroule de telle façon à n’écrire qu’une seule fois le code. La création des projets spécifiques par cible, les manipulations pour copier/coller des liens vers le noyau de base ne sont pas des opérations longues ni complexes. Mais il faut le faire. C’est pourquoi nous assumons à ce niveau entre 0 et 5% de variabilité uniquement pour signifier qu’il y a une charge de travail faible mais non nulle pour supporter toutes les cibles. En réalité la “variabilité” même du code reste nulle. Un seul code. Dans certains cas il peut être nécessaire d’adapter le code des ViewModels aux cibles (utilisations du hardware par exemple). Cela est rare mais la structure générale le supporte. Toutefois on préfèrera toujours créer une abstraction au niveau des ViewModels afin de laisser la totalité du code spécifique au niveau des projets gérant les Vues.

Enfin, nous écrivons des projets spécifiques pour les UI car les machines, les OS, les form factors l’imposent. Mais ici ce ne sont plus que des Vues fonctionnant avec du Binding sur les ViewModels... Il n’y a qu’un travail de mise en page, voire d’intégration entre le travail de l’infographiste/designer et celui des informaticiens (les ViewModels). Ici nous acceptons une variabilité de 90 à 100%, c’est la règle du jeu...

Mais pour certaines cibles cette variabilité sera souvent moindre. Supporter Windows Phone 7 et Windows Phone 8 et WinRT permettra de réutiliser peut-être 50 à 60% du code Xaml, voire plus. Par exemple on récupèrera les définitions de style, les animations, les DataTemplates, qui, dans un projet bien écrit représentent l’essentiel du code de l’UI. On accepte aussi dans l’autre sens que dans certains cas les Vues puissent contenir du code totalement spécifique pour gérer notamment du hardware.  Par exemple, une capture image sera une fonction des ViewModels exposant les commandes et les propriétés nécessaires pour passer l’image, mais la capture elle-même sera codée dans les projets contenant les Vues car chaque plateforme aura ses spécificités. Autant les grouper au même endroit et ne pas détruire l’universalité des ViewModels dans la construction présentée ici.

Ainsi, le bloc le plus cher à une variabilité de 0 %, le second bloc qui réclame un investissement important à une variabilité de 5 % maximum, seul le bloc des UI a une variabilité maximale.

En adoptant cette stratégie le coût final pour supporter une dizaine de cibles différentes, c’est à dire tout le marché, reste très proche du coût de développement d’une seule version spécifique... Le surcoût ne se trouvant que dans les cibles qu’on souhaite supporter. Mais en suivant la stratégie exposée c’est aussi à cet endroit que la stratégie adoptée à permis de limiter drastiquement les couts...

En gros, plus le code devient spécifique, moins il y a de code à produire. Dans l’autre sens : plus le code est cher à produire, plus il est universel et n’est développé qu’une fois...

Conclusion

La stratégie de développement cross-platform et cross-form factor présentée ici est une méthode qui permet de maitriser les couts tout en offrant la possibilité de couvrir toutes les cibles qu’on souhaite.

Sa mise en œuvre ne réclame qu’un seul EDI, Visual Studio, un seul langage, C#, un seul pattern, MVVM, une seule librairie pour le gérer.

Grâce à MonoTouch et MonoDroid, nous pouvons ajouter les 4 cibles les plus importantes du marché (IPhone, IPad, Android phone et Android tablette) pour le prix, fort modeste, d’une licence de ces produits.

Grâce à MVVMCross, gratuit et open-source, nous pouvons unifier le support de plateformes aussi différentes que Windows 8 et iOS ou Android.

Le tout dans la cohérence, sans s’éparpiller.

Et surtout : le tout en produisant des applications natives pour chaque cible, sans compromis technique.

Bien entendu, la réalité pourra parfois s’éloigner légèrement de ce tableau idyllique. Par exemple dès qu’on souhaitera attaquer des fonctions spécifiques à une plateforme donnée (téléphone, caméras, etc). Mais d’abord très peu d’applications LOB (qui reste ma cible en entreprise) nécessitent ce genre d’artifice, et ensuite ces spécificités resteront ponctuelles. Cela ne remet pas en cause le gain énorme de productivité, la simplification de la maintenance évolutive et corrective que la stratégie présentée fera gagner.

Ne reste plus, pour convaincre les éventuels sceptiques et pour éclairer au mieux ceux qui ont compris l’intérêt de cette stratégie à vous présenter une mise en œuvre complète. Il s’agira d’une démonstration fonctionnelle utilisant un service web réel développé il y a 4 ans, bien avant qu’on ne parle des nécessités évoquées ici, qui tourne sur l’un de mes serveurs en Angleterre, et plusieurs cibles tel que le Web avec Silverlight, Windows Phone, Android et même une console Windows. Cela sera bien assez pour vous montrer que ce dont je parle ici est une stratégie mature et fonctionnelle et, je l’espère, vous convaincre qu’avec C#, .NET et Visual Studio, aidé de quelques bons outils comme MonoTouch et MonoDroid, on peut aujourd’hui tout faire et conquérir le monde !

 

Pour la Partie 2 ...  Stay Tuned !

Accéder à la Partie 2 de l'article

blog comments powered by Disqus