Forums Développement Multimédia

Aller au contenu

typer par interface ?

CODE Actionscript

30 réponses à ce sujet

#1 ka9988

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 16 November 2008 - 16:51 PM

Bonjour,
Suite à un article paru sur mediabox concernant les interfaces (http://magazine.mediabox.fr/b_Utiliser+les...ces+en+AS3.html),
Je me pose certaines questions...
D'après les dires de l'auteur, si une classe implémente une interface, un appel de cette classe devrait se faire en typant par son interface...

Action Script


//exemple
var tutu:ITutu=new Tutu();

Sur le principe ça à l'air cool, mais je trouve çca assez lours à mettre en place et assez restrictif.
Par exemple,pour pouvoir faire un addChild de cette classe il faut rajouter dans son interface un getter qui retourne cette même classe

Action Script


//exemple
addChild(tutu); // erreur


/******
public function get content():Sprite
{

}
******/

addChild(tutu.content);


#2 ka9988

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 16 November 2008 - 17:02 PM

Bonjour,
Suite à un article paru sur mediabox concernant les interfaces (http://magazine.mediabox.fr/b_Utiliser+les...ces+en+AS3.html),
Je me pose certaines questions...
D'après les dires de l'auteur, si une classe implémente une interface, un appel de cette classe devrait se faire en typant par son interface...

Action Script


//exemple
var tutu:ITutu=new Tutu();

Sur le principe ça à l'air cool, mais je trouve ça assez lours à mettre en place et assez restrictif.
Par exemple,pour pouvoir faire un addChild de cette classe il faut rajouter dans son interface un getter qui retourne cette même classe

Action Script


//exemple
addChild(tutu); // erreur


/******
on rajoute cela dans Tutu
public function get content():Sprite
{
return this;
}

et bien sur cela dans l'interface
function get content():Sprite
******/

addChild(tutu.content); //ok

Même galère si l'on veut écouter des evenements sur cette classe
je dois alors étendre mon interface par IEventDispatcher...

En gros, typer par interface ou pas ? Ca vaut la peine ou c'est juste pour se la péter? Car a part qui faut rajouter des mots en plus, j'en vois pas l'intérêt...

Voila !

Merçi de vos reponses !

ka9988

ps:desoler du doublon, une erreur s'est produite et je ne peux pas editer mon message


#3 durss

  • Members
  • PipPipPipPipPipPipPipPip
  • 1965 messages

Posté 16 November 2008 - 17:17 PM

Pour faire un addChild cast ton objet typé sur l'interface, sur Sprite c'est plus simple :

Action Script

addChild(obj as Sprite);


#4 armetiz

  • Members
  • PipPipPipPipPipPipPipPip
  • 623 messages

Posté 16 November 2008 - 21:18 PM

Les interfaces ne sont utiles (d'apres moi), que pour des fonctionnalités communes à differente classe..
Exemple IDelete est une interface obligeant la fonction "dispose ()".

Donc, toute les classes implementants IDelete peuvent etre supprimer "joliement".

Exemple suivant

Action Script


//On recupere un objet dont nous avons terminer le traitement, on va le supprimer
function onFinish (ev : Event) : void
{
//Dernier traitement... bla bla bla

if (ev.target is IDelete)
{
(ev.target as IDelete).dipose ();
}
}

On pourrai utiliser IDisplay qui impose la fonction "contentDisplay () : DisplayObject"... Pour un objet qui n'est pas forcement enfant de DisplayObject ca peut-etre interessant, même si l'exemple pris ainsi est nul icon_razz.gif

Modifié par armetiz, 16 November 2008 - 21:20 PM.


#5 profdeco2

    Ceinture Bleue

  • Members
  • PipPipPipPipPip
  • 75 messages

Posté 18 November 2008 - 23:38 PM

Soit dit en passant, si tu définis un getter qui renvoie un Sprite, pas besoin d'en écrire un autre pour avoir un EventDispatcher, puisque Sprite étend déjà EventDispatcher.
Plus fondamentalement, typer par interface répond au principe général "code to an interface, not to an implementation."
Citation
Les interfaces ne sont utiles (d'apres moi), que pour des fonctionnalités communes à differente classe.

Oui mais il est bien difficile de dire à l'avance quelles fonctionnalités seront commune si les spécifications du projet évoluent.
Exemple, j'ai une classe ChargementXML qui implémente IChargement, et puis demain je m'aperçois que j'ai fait une c..., il fallait mettre mes données dans une base : c'est pas grave je peux toujours implémenter IChargement avec IChargementPhp.
J'ai une image qui arrive en tournant et là on me dit non, elle doit faire en fondu enchainé, c'est pas grave car j'ai confié la gestion du mouvement à StrategieTransitionTournante qui implémente IStrategieTransition. Je peux écrire StrategieTransitionFondu. etc.
D'autre par les interfaces sont des marqueurs bien utiles pour identifier de quel type d'élément d'interface viennent les évènement utilisateurs notamment quand on développe en modèle vue controleur.
Si tu as un environnement de développement bien fait ce n'est pas très contraignant car une fois la signature de la méthode écrite dans l'interface elle peut être répliquée automatiquement dans les classes qui doivent l'implémenter.
Voilà si ça peut contribuer au débat...

#6 ka9988

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 19 November 2008 - 08:33 AM

bonjour,
Je n'avais pas réflechi plus loin que le bout de mon nez, j'ai laisser tomber le getter qui revoie un sprite et j'emploi la methode de durss(je caste lors de mon addchild)...

#7 dada

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 8510 messages

Posté 19 November 2008 - 10:36 AM

Salut,

Si tu dois caster à chaque fois que tu veux gérer l'affichage de l'objet c'est que ton interface peut être remise en question... smile.gif
Tu peux utiliser une classe abstraite plutôt qu'une interface (qui hérite de Sprite ou autre), ou l'astuce du getter vue plus haut.

#8 la pieuvre

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3055 messages

Posté 19 November 2008 - 15:05 PM

il me semble surtout que l'utilité de typer une variable avec une interface et pour permettre d'utiliser dans le cas précis de cette variables des objets de type différent en étant sûr que les méthode existent et sont implémenter de la même manière... et c'est plus général que l'héritage parce que (entre autre) une classe peut interfacer plusieurs interface. (mais je peux me tromper).

#9 frederic.dufau

  • Members
  • PipPipPipPipPipPipPipPip
  • 684 messages

Posté 20 November 2008 - 10:23 AM

Hum, pour ma part, je trouve l'article de barnabé2 trés bien fait mais il est dans une logique de pureté qui ne se marie pas toujours trés bien avec des délais de réalisation assez court.

#10 dada

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 8510 messages

Posté 20 November 2008 - 10:40 AM

Citation (Fidiman @ Nov 20 2008, 10:23 AM) Voir le message
Hum, pour ma part, je trouve l'article de barnabé2 trés bien fait mais il est dans une logique de pureté qui ne se marie pas toujours trés bien avec des délais de réalisation assez court.

Cà dépend, sur un gros projet on gagnera du temps à bien conceptualiser plutôt que se retrouver à un moment à devoir recoder une usine à gaz. smile.gif Et petit ou gros, comme çà facilite la réutilisation et modularité du code on est plus rapide sur les projets suivants, tout comme le sont les modifications/MAJ. smile.gif
Et plus on en fait, plus on est efficace. icon_razz.gif

#11 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 10:44 AM

Bonjour à tous,

Bon j'ai beau chercher et après avoir vu le tuto de Bernabé http://wiki.mediabox.fr/tutoriaux/utiliser_les_interfaces l'utilisation des interfaces comporte encore quelques zones d'ombres !

+ Ce que j'ai compris :
- l'utilisation des interfaces ne sert que dans le cas où l'on veut utiliser les méthodes d'une classe mais que l'ont ne peut pas étendre celle-ci, on utilise donc l'interface de cette classe pour être sûr d'utiliser les mêmes méthodes (puisqu'il faut absolument les remettre dans la classe qui implémente l'interface) ! Mais ça ne remplace pas l'héritage !?

+ Ce que je n'ai pas compris :
- Son utilisation dans son exemple avec l'ISF etc. C'est certainement parce que je n'aime pas trop parler d'ISF et d'impôts en générale héhé ! Quelqu'un aurait-il un exemple claire (avec des oranges et des pommes par exemple sur un marché ...) qui reflète ce que notre ami à voulu expliquer avec son exemple sur l'ISF ?

+ Une autre question :
- A part forcer un autre développeur à utiliser les méthodes d'une classe bien précise, qu'elle est l'intérêt d'utiliser une Interface ?

Merci pour vos réponses ...

#12 paodao

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 7081 messages

Posté 20 November 2008 - 11:03 AM

salut

imagine une classe Homme et une classe Femme
ayant toutes les 2 une fonction marche()

maintenant dans ton programme principal tu creer de facon aleatoire soit un Homme soit une Femme

Action Script


var perso
if(Math.random()>0.5)
{
perso = new Homme()
}else
{
perso = new Femme()
}

tu remarquera deja que tu ne peux pas typer perso puisque tu ne sait pas si se sera un homme ou une femme
tu ne peux pas appeller la fonction marche puisque perso n'est pas typer

maintenant tu as une interface Personne avec la fonction marche() definni dedans

du coup tu peux faire

Action Script


var perso: Personne
if(Math.random()>0.5)
{
perso = new Homme()
}else
{
perso = new Femme()
}
perso.marche()

tu me dira qu'on peux faire la meme chose avec l'heritage
une classe Perso qui definni la fonction marche et donc Homme et Femme herite
oui tu peux le faire si Homme et Femme marche de la meme facon
seulement s'il marche de facon differente ca va plus
avec une interface tu es sure que la fonction marche sera bien definni au seins des classes qui l'implemente
ainsi si demain tu veux rajouter une autre classe ("Enfant") il lui suffira d'implenter Personne et cela ira

a+

#13 dada

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 8510 messages

Posté 20 November 2008 - 11:10 AM

Intéresse-toi aux design pattern pour y voir de très bonnes utilisations d'interfaces. smile.gif
Bouquin incontournable dans le domaine : Design Pattern chez la collection Tête la Première (autrefois distribué chez O'Reilly France...).

#14 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 12:30 PM

merci pour l'explication.

Donc si j'ai bien compris, si je veux recevoir des infos comme le résultat d'un calcul simple il faudra que dans mon Interface Personne (appelons le IPersonne) j'étends une classe bien précise pour recevoir le résultat exemple :

Action Script


public Interface IPersonne extends CalculExemple {



#15 paodao

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 7081 messages

Posté 20 November 2008 - 12:36 PM

heu j'ai pas trop compris ta question mais pour le code non c'est po ca
une interface ne peux etendre qu'une autre interface

a+

#16 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 12:46 PM

Citation (paodao @ Nov 20 2008, 12:36 PM) Voir le message
heu j'ai pas trop compris ta question mais pour le code non c'est po ca
une interface ne peux etendre qu'une autre interface

a+

Heu oui pardon ma question n'était pas fini, c'est juste une erreur de manip.
En fait dans ton exemple le fait de faire perso.marche() ne me retourne rien ou n'exécute rien ... Donc quel intérêt d'utiliser l'interface ... Ok les deux hommes / femme /enfant utilise la même méthode mais qu'est-ce qu'ils en retire ?

Désolé, y a certainement quelquechose qui m'échappe mais je vois pas quoi !



#17 paodao

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 7081 messages

Posté 20 November 2008 - 12:51 PM

Citation
le fait de faire perso.marche() ne me retourne rien ou n'exécute rien


ba si les classes Hommes et Femmes definnissent ce que la fonction marche doit faire
et si tu ne la definni pas, flash ne compilera pas ton swf et te dira qu'il faut que les classes definnissent la fonction marche

#18 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 12:53 PM

Interface IPersonne

Action Script


public Interface IPersonne {
function recalcul (param1:int,param2:int)

}

classe Homme :

Action Script


public class Homme extends sprite implements IPersonne {
public function recalcul (param1,param2):Number {
var calcul = param1 + param2
return calcul
}
}


classe Femme :

Action Script


public class Homme extends sprite implements IPersonne {
public function recalcul (param1,param2):Number {
var calcul = param1 - param2
return calcul
}
}

Dans ce cas précis quel est l'intérêt ?

Modifié par ARROWPHIL, 20 November 2008 - 12:54 PM.


#19 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 12:56 PM

Citation (paodao @ Nov 20 2008, 12:51 PM) Voir le message
ba si les classes Hommes et Femmes definnissent ce que la fonction marche doit faire
et si tu ne la definni pas, flash ne compilera pas ton swf et te dira qu'il faut que les classes definnissent la fonction marche


Ok mais
Citation
et si tu ne la definni pas

Si je la défini pas où ?

#20 paodao

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 7081 messages

Posté 20 November 2008 - 13:00 PM

Citation
Si je la défini pas où ?


dans les classes

pour ton exemple
essai de creer un objet de type Homme ou Femme aleatoirement et d'appeller la fonction recalcul sans passer par une interface icon_wink.gif


#21 la pieuvre

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3055 messages

Posté 20 November 2008 - 13:09 PM

je crois surtout qu'il faut voir une interface comme un cahier des charges. elles sont juste là pour dire ma classe doit avoir tel et tel fonctionnalité qui s'appelle de cette manière... contrairement à l'héritage qui définie une parenté est une action précise (l'implémentation est déjà faite).

#22 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 13:15 PM

Citation (paodao @ Nov 20 2008, 01:00 PM) Voir le message
dans les classes

pour ton exemple
essai de creer un objet de type Homme ou Femme aleatoirement et d'appeller la fonction recalcul sans passer par une interface icon_wink.gif

Bah là ça fonctionne bien ?

Je t'ai mit les fichiers en pièce jointe.

Fichier(s) joint(s)



#23 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 13:17 PM

Citation (la pieuvre @ Nov 20 2008, 01:09 PM) Voir le message
je crois surtout qu'il faut voir une interface comme un cahier des charges. elles sont juste là pour dire ma classe doit avoir tel et tel fonctionnalité qui s'appelle de cette manière... contrairement à l'héritage qui définie une parenté est une action précise (l'implémentation est déjà faite).

Oui, c'est tout ! Enfin comme toi, je ne vois pas la différence ... Peut-être que PAODAO va réussir à m'expliquer, désolé PAODAO, je suis un peu lent à piger la subtilité peut-être !!! icon_mrgreen.gif sorry

Modifié par ARROWPHIL, 20 November 2008 - 13:17 PM.


#24 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 13:35 PM

Ha moins que tu veuille parler de ce problème au cas où femme et homme n'utilise pas exactement la même méthode (voir pièce jointe) ce qui se traduit pas ajouter la fameuse interface pour être sûre qu'à la compilation on est ce message :

Citation
1144: La méthode d'interface recalcul de l'espace de nom IPersonne est implémentée avec une signature incompatible dans la classe Femme.


Qui nous informe qu'on a fait une erreur dans notre code, comme ça l'erreur est affiché à la compil et pas une fois le projet testé ou en ligne !
ça rejoindrait donc ce que dit la pieuvre :
Citation
je crois surtout qu'il faut voir une interface comme un cahier des charges. elles sont juste là pour dire ma classe doit avoir tel et tel fonctionnalité qui s'appelle de cette manière...


Tenez moi au courant pour me dire si j'ai pigé le truc ou pas parce que ça fait deux jours que je dors pas à cause de ça icon_mrgreen.gif Je vois des interfaces partout et j'ai même faillit changer de nom en IArrowphil lol

Fichier(s) joint(s)


Modifié par ARROWPHIL, 20 November 2008 - 13:35 PM.


#25 la pieuvre

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3055 messages

Posté 20 November 2008 - 13:36 PM

mais si je vois la différence!! il y en a un qui est un cahier des charges donc ma classe doit pouvoir distribuer des événements, elle implémente donc IEventDispatcher, ha elle doit aussi pouvoir être supprimer, bon elle doit alors aussi implémenter l'interface IDelete, elle doit avoir un autre comportement alors elle va implémenter un autre interface (là dans mon exemple ma classe implémente 3 interface pour prototyper les comportement voulu).

l'héritage est une hiérarchie ma classe qui étend ma SuperClasse prend tous les comportements et l'implémentation de SuperClasse mais que celle-ci (et des ses superclasses respective).
d'autre part les objets implémentant une interface n'ont pas forcement de raison d'hériter de la même classe.

une interface IMarcheArret qui définie des méthodes d'activation et d'arrêt d'un objet n'as pas forcement de raison d'être une super classe ( si Voiture l'implémente Ordinateur peut l'implémenter aussi, Progamme, ... et elles n'ont pas de raison d'hériter d'une super classe commune).

#26 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 13:45 PM

Citation (la pieuvre @ Nov 20 2008, 01:36 PM) Voir le message
mais si je vois la différence!!


héhé , pardon je me suis mal exprimé, je veux dire qu'à part le faite d'être un système de "Cahier des Charges" elle n'offre pas de simplification du code comme l'héritage ... Elle sert juste à forcer le développeur à utiliser tels méthodes pour exécuter proprement une action précise (dans ton exemple l'affichage d'objet et l'envoi d'évènements)

...


#27 la pieuvre

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3055 messages

Posté 20 November 2008 - 13:58 PM

ben oui et c déjà pas mal !! smile.gif

#28 paodao

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 7081 messages

Posté 20 November 2008 - 14:05 PM

Citation
Bah là ça fonctionne bien ?

oui ca fonctionne mais tu remarquera que ta variable perso est pas typer
donc c'est pas glop
alors que si tu as une interface tu peux type ta variable perso avec cette interface
cela te permet d'utiliser des objet sans connaitre forcement leur classe
en typant avec IPersonne tu es sure que ton objet aura la fonction recalcul de definni
sans parler du fait que dans un vrai editeur de code (style flashdevelop) tu as la completion du code
donc quand tu tape perso:IPersonne il te dis qu'il y a la fonction recalcul dedans

et que si demain tu ajoute une classe enfant qui implement IPersonne tu n'a pas a modifier ton code puisque qu'il gere des objets de type IPersonne

imagine un jeux de voiture
tu as le choix entre conduire une voiture ou conduire une moto
la conduite n'est donc pas la meme
mais par contre tu sais que les 2 vehicule ont une fontion avance
donc tu fait une interface IVehicule avec la fonction avance definni dedans
dans ton main tu utilisera un objet de type IVehicule sur lequel tu appellera la fonction avance
comme ton main n'a pas besoin de savoir si on conduit une moto ou une voiture, il a juste besoin de savoir que tu conduis un vehicule
si demain tu ajoute un tracteur tu n'aura pas a modifer ton main puisque un tracteur est un vehicule

a+

#29 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 14:13 PM

Super, je pense avoir compris !

Merci à vous deux !!!
Dada => promis mon prochain challenge est les pattern - Mais vu comment je rame sur l'interface à mon avis le pattern ça va être chaud !!!

Bonne journée à tous et surtout bon Beaujolais !!!

#30 dada

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 8510 messages

Posté 20 November 2008 - 14:45 PM

Je ne mettrais pas le fait que çà définisse un cahier des charges comme principal intérêt des interfaces.
L'essentiel se résume par la phrase : "Programmer pour des interfaces, pas pour des implémentations".
Qu'est-ce qu'une implémentation ? C'est du code qui fait quelque chose de bien spécifique, comme celui qu'on a dans une classe.
Si j'ai un objet client qui a besoin de la classe Truc, mon objet client est programmé pour une implémentation, celle de Truc et il ne peut fonctionner qu'avec elle.
Par contre, si l'objet client a besoin du type d'une interface, il n'est pas dépendant d'une implémentation spécifique, car toute classe implémentant cette interface pourra être utilisée par le client. Peu importe de quelle manière elle l'implémente. smile.gif
C'est plus ouvert à la modularité, favorise les évolutions du programme.

Citation
Dada => promis mon prochain challenge est les pattern - Mais vu comment je rame sur l'interface à mon avis le pattern ça va être chaud !!!
Ce livre est une démystification des patterns, c'est justement parce que tu as du mal avec les interfaces que tu devrais le lire. wink.gif

#31 phil

  • Members
  • PipPipPipPipPipPipPipPip
  • 738 messages

Posté 20 November 2008 - 14:49 PM

Citation (dada @ Nov 20 2008, 02:45 PM) Voir le message
Je ne mettrais pas le fait que çà définisse un cahier des charges comme principal intérêt des interfaces.
L'essentiel se résume par la phrase : "Programmer pour des interfaces, pas pour des implémentations".
Qu'est-ce qu'une implémentation ? C'est du code qui fait quelque chose de bien spécifique, comme celui qu'on a dans une classe.
Si j'ai un objet client qui a besoin de la classe Truc, mon objet client est programmé pour une implémentation, celle de Truc et il ne peut fonctionner qu'avec elle.
Par contre, si l'objet client a besoin du type d'une interface, il n'est pas dépendant d'une implémentation spécifique, car toute classe implémentant cette interface pourra être utilisée par le client. Peu importe de quelle manière elle l'implémente. smile.gif
C'est plus ouvert à la modularité, favorise les évolutions du programme.

Ce livre est une démystification des patterns, c'est justement parce que tu as du mal avec les interfaces que tu devrais le lire. wink.gif

Ha bah voilà ... Jolie nuance smile.gif Merci DADA



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)