Banner

Objective-C et la réflexivité

Posté par alpheccar le23 Mai 2005 à 19:42 CEST

OS X est un dérivatif d’Unix : un microkernel Mach (développé par Carnegie-Mellon et qui n’a aucun rapport avec les Macs initialement) + une couche BSD (des emprunts à diverses variantes de BSD) + des solutions propriétaires. La couche Unix (BSD/Mach) est totalement open-source et fonctionne même sur compatibles Pentium.

Les solutions propriétaires utilisent Objective-C : une variante peu connue du C et pourtant si élégante.

Cette utilisation d’Objective-C fait de OS X un dérivatif d’Unix assez différent et bien plus élégant que les nombreux OS qui sont restés au C ou qui -horreur- ont choisi le C++.

Objective-C est une extension objet de C qui s’inspire très fortement de Smalltalk. Objective-C est un langage assez simple dans le sens où il introduit peu de nouveautés par rapport au C (beaucoup moins que C++) mais ces extensions ont été bien pensées. Cela fait d’Objective-C un langage élégant et puissant qui permet de construire des architectures logicielles beaucoup plus flexibles et de bien meilleure qualité que ce que l’on peut rencontrer sur d’autres platformes.

Alors, qu’est-ce qui fait d’Objective-C un langage aussi magique ? Et bien, c’est un des rares langages compilés qui introduit de la réflexivité au cœur même de sa définition. Il n’est pas aussi réflexif, bien entendu, que des langages comme Lisp ou Smalltalk où la distinction entre code et data devient floue. Il est néanmoins suffisamment réflexif pour que l’impact sur les performances du langage soit faible tout en permettant de bénéficier de cette réflexivité.

Alors, cela veut dire quoi ? Objective-C est un langage objet (j’y reviendrai) où chaque objet appartient à une classe. Une classe est aussi un objet en Objective-C. Il y a donc des méta-classes. Or, une méta-class est aussi un objet mais c’est aussi sa propre classe. La récursion s’arrête là.

Une classe étant un objet, elle peut être modifiée et elle a un état. Cet état est alors commun à tous les objets de la classe.

Une classe étant un objet, on peut lui rajouter des fonctions à l’éxecution (et sans avoir besoin du source code de la classe). C’est le concept de Category. Imaginez que vous ayez besoin d’un algorithme de traitement de chaîne qui n’est pas fourni par défaut par la classe NSString (on ne peut pas prévoir tous les usages possibles futurs). Dans une approche objet standard, il faudrait créer une classe héritant de NSString et rajouter la fonction en question. Mais pourquoi polluer la hiérarchie de types pour une fonction qui devrait réellement faire partie de NSString ? En Objective-C, le problème ne se pose pas : il suffit de rajouter votre fonction à cette classe. Toutes les instances actuelles et futures peuvent alors utiliser cette fonction. Cela peut même être utilisé pour patcher une fonction dans une classe sans en avoir le source.

Vous pouvez aussi obtenir, à l’exécution, des informations sur une classe (ou un objet de cette classe) : la liste des variables internes, la listes des fonctions de la classe, une description de la classe. Cette “documentation” n’est pas un détail mais est fonctionnellement importante. Elle permet, par exemple, de créer une classe dérivée sans avoir besoin du code source de la classe parent. Il n’est pas rare sous OS X de downloader des framework permettant d’étendre et personnaliser les fonctions de l’OS grâce au subclassing et aux catégories.

Un objet pouvant s’étudier lui-même ou étudier d’autres objets, le couplage entre les objets n’a pas besoin d’être fort. Vous pouvez utiliser un objet sans savoir d’où il vient. Dans un langage comme C++, il faudrait au minimum connaître une classe parente et l’utiliser pour pouvoir compiler. En Objective-C ce n’est pas le cas car en plus de cette réflexivité (un objet pouvant s’étudier lui-même), le langage utilise un système de messaging.

Là où un langage comme C++ écrira myObject.draw(), en Objective-C on aura [myObject draw]. Ce n’est pas un simple changement syntaxique. C’est aussi sémantiquement très différent. La syntaxe Objective-C signifie que l’on envoie le message draw à l’objet myObject. Cet objet peut ne pas savoir répondre au message et peut le forwarder automatiquement à un autre objet. L’objet peut aussi être sur une autre machine du réseau ou dans un autre espace d’adressage. Le message peut être construit dynamiquement à l’éxecution car draw n’est pas une fonction c’est effectivement un message qui peut être stocké dans une variable. Ainsi, il y a un couplage très faible entre les objets. On a un réseau d’objets qui communiquent par envoi de messages.

Les interfaces de communication entre ces objets peuvent être sondées à l’éxecution. Par exemple, ces messages peuvent être regroupés selon leur usage en unités appelées protocoles. On pourra demander à l’exécution si un objet implémente un certain protocole.

Cette réflexivité d’Objective-C permet des choses très puissantes comme les bindings. Vous pouvez lier deux variables entre elles. Tout changement dans l’une de ces variables (appartenant à un objet particulier) sera automatiquement reflété par une autre variable définie dans un autre objet et réciproquement. Ce qu’il y a d’intéressant c’est que cela ne nécessite aucune ligne de code. Le binding s’établit sans que les deux objets liés en soit conscient et sans que le programmeur ait à écrire du code.

La réflexivité et le système de messaging permettent de faire du late-binding (ou dynamic-binding). Un objet est très peu dépendant de son environnement donc il peut facilement être réutilisé et un système Objective-C est facilement extensible.

Le meilleur moyen de concevoir la couche applicative de OS X : des objets dans des espaces d’adressage différents qui communiquent entre eux par envoi de messages. Les applications sont donc beaucoup moins indépendantes les unes des autres. Il est plus facile pour une application d’offrir des services à une autre. Mais, du code peut aussi offrir des services nouveaux à tout le système comme par exemple : pouvoir taper du LaTeX dans toute application et obtenir un embedded PDF qui contient l’équation correspondante comme illustré avec le notepad:

image

Ces extensions se font proprement sans mettre en danger l’intégrité du système. Ce ne sont pas des patches.

Un autre exemple : un framework peut fournir, dans toutes les zones de saisie de texte, de nouveaux services comme le dictionnaire, les expressions régulières, la tab-completion etc...

image

Ces services sont linkés quand l’utilisateur se logge.

OS X est donc un OS propriétaire mais ouvert. Il est facilement et proprement customisable. Les particularités d’Objective-C ont permi de concevoir un Application développement framework extrêmement fléxible et puissant qui permet de fournir aux applications des fonctionnalités difficiles à implémenter sur d’autres platformes.

Vive la réflexivité et les véritables langages objets !

Tags | | |

Commentaires

Ajouter un commentaire...

Smalltalk pour Objective-C

Posté par alpheccar le24 Mai 2005 à20:20 CEST