Partie 2 : Architecture
Un principe clé de la création d’applications multiplateformes consiste à créer une architecture qui se prête à une optimisation du partage de code entre les plateformes. L’adhésion aux principes de programmation orienté objet suivants permet de créer une application bien conçue :
- Encapsulation : s’assurer que les classes et même les couches architecturales exposent uniquement une API minimale qui exécute leurs fonctions requises et masque les détails de l’implémentation. Au niveau de la classe, cela signifie que les objets se comportent comme des « boîtes noires » et que la consommation de code n’a pas besoin de savoir comment ils accomplissent leurs tâches. Au niveau architectural, cela signifie implémenter des modèles comme Façade qui encouragent une API simplifiée qui orchestre des interactions plus complexes pour le compte du code dans des couches plus abstraites. Cela signifie que le code de l’interface utilisateur (par exemple) doit uniquement être responsable de l’affichage des écrans et de l’acceptation de l’entrée utilisateur ; et n’interagissant jamais directement avec la base de données. De même, le code d’accès aux données doit uniquement lire et écrire dans la base de données, mais n’interagir jamais directement avec des boutons ou des étiquettes.
- Séparation des responsabilités : assurez-vous que chaque composant (au niveau de l’architecture et de la classe) a un objectif clair et bien défini. Chaque composant doit effectuer uniquement ses tâches définies et exposer cette fonctionnalité via une API accessible aux autres classes qui doivent l’utiliser.
- Polymorphisme : la programmation vers une interface (ou une classe abstraite) qui prend en charge plusieurs implémentations signifie que le code de base peut être écrit et partagé sur plusieurs plateformes, tout en interagissant avec des fonctionnalités spécifiques à la plateforme.
Le résultat naturel est une application modélisée d’après des entités réelles ou abstraites avec des couches logiques distinctes. La séparation du code en couches facilite la compréhension, le test et la maintenance des applications. Il est recommandé que le code de chaque couche soit physiquement séparé (soit dans des répertoires, soit dans des projets distincts pour de très grandes applications) ainsi que logiquement distinct (à l’aide d’espaces de noms).
Couches d’application standard
Tout au long de ce document et des études de cas, nous faisons référence aux six couches d’application suivantes :
- Couche de données : persistance des données non volatiles, susceptible d’être une base de données SQLite, mais qui peut être implémentée avec des fichiers XML ou tout autre mécanisme approprié.
- Couche d’accès aux données : wrapper autour de la couche de données qui fournit un accès CRUD (Create, Read, Update, Delete) aux données sans exposer les détails de l’implémentation à l’appelant. Par exemple, le dal peut contenir des instructions SQL pour interroger ou mettre à jour les données, mais le code de référence n’a pas besoin de le savoir.
- Couche métier : (parfois appelée couche de logique métier ou BLL) contient des définitions d’entité métier (le modèle) et une logique métier. Candidat pour le modèle de façade d’entreprise.
- Couche d’accès au service : utilisée pour accéder aux services dans le cloud : des services web complexes (REST, JSON, WCF) à la simple récupération de données et d’images à partir de serveurs distants. Encapsule le comportement de mise en réseau et fournit une API simple à utiliser par les couches application et interface utilisateur.
- Couche d’application : code généralement spécifique à la plateforme (pas généralement partagé entre les plateformes) ou code spécifique à l’application (non généralement réutilisable). Un bon test pour savoir s’il faut placer du code dans la couche Application par rapport à la couche d’interface utilisateur est (a) pour déterminer si la classe a des contrôles d’affichage réels ou (b) si elle peut être partagée entre plusieurs écrans ou appareils (par exemple, iPhone et iPad).
- Couche d’interface utilisateur : la couche orientée utilisateur contient des écrans, des widgets et les contrôleurs qui les gèrent.
Une application peut ne pas nécessairement contenir toutes les couches. Par exemple, la couche d’accès au service n’existe pas dans une application qui n’accède pas aux ressources réseau. Une application très simple peut fusionner la couche de données et la couche d’accès aux données, car les opérations sont extrêmement basiques.
Modèles logiciels mobiles courants
Les modèles sont un moyen établi de capturer des solutions récurrentes aux problèmes courants. Il existe quelques modèles clés qui sont utiles à comprendre lors de la création d’applications mobiles maintenables/compréhensibles.
- Model, View, ViewModel (MVVM) : le modèle Model-View-ViewModel est populaire avec les frameworks qui prennent en charge la liaison de données, comme Xamarin.Forms. Il a été popularisé par les sdk compatibles XAML comme Windows Presentation Foundation (WPF) et Silverlight, où ViewModel agit comme un intermédiaire entre les données (Modèle) et l’interface utilisateur (View) via la liaison de données et les commandes.
- Modèle, vue, contrôleur (MVC) : modèle commun et souvent mal compris, MVC est le plus souvent utilisé lors de la création d’interfaces utilisateur et fournit une séparation entre la définition réelle d’un écran d’interface utilisateur (Affichage), le moteur derrière celui-ci qui gère l’interaction (Contrôleur) et les données qui le remplissent (Modèle). Le modèle est en fait une pièce entièrement facultative et, par conséquent, le cœur de la compréhension de ce modèle réside dans la vue et le contrôleur. MVC est une approche populaire pour les applications iOS.
- Business Façade – AKA Manager Pattern, fournit un point d’entrée simplifié pour les travaux complexes. Par exemple, dans une application de suivi des tâches, vous pouvez avoir une
TaskManager
classe avec des méthodes telles queGetAllTasks()
,GetTask(taskID)
,SaveTask (task)
, etc. LaTaskManager
classe fournit une façade aux rouages internes de l’enregistrement/récupération des objets de tâches. - Singleton : le modèle Singleton permet d’utiliser un seul instance d’un objet particulier. Par exemple, lorsque vous utilisez SQLite dans des applications mobiles, vous ne souhaitez jamais qu’une seule instance de la base de données. L’utilisation du modèle Singleton est un moyen simple de s’en assurer.
- Fournisseur : modèle inventé par Microsoft (sans doute similaire à la stratégie ou à l’injection de dépendances de base) pour encourager la réutilisation du code dans les applications Silverlight, WPF et WinForms. Le code partagé peut être écrit dans une interface ou une classe abstraite, et des implémentations concrètes spécifiques à la plateforme sont écrites et passées lorsque le code est utilisé.
- Async : à ne pas confondre avec l’mot clé asynchrone, le modèle Async est utilisé quand un travail de longue durée doit être exécuté sans avoir à maintenir l’interface utilisateur ou le traitement actuel. Dans sa forme la plus simple, le modèle Async décrit simplement que les tâches de longue durée doivent être lancées dans un autre thread (ou une abstraction de thread similaire telle qu’une tâche) pendant que le thread actuel continue à traiter et écoute une réponse du processus en arrière-plan, puis met à jour l’interface utilisateur lorsque des données et ou l’état sont retournés.
Chacun des modèles sera examiné plus en détail à mesure que leur utilisation pratique est illustrée dans les études de cas. Wikipédia contient des descriptions plus détaillées des modèles MVVM, MVC, Façade, Singleton, Stratégie et Fournisseur (et des modèles de conception en général).