IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Réflexion sur la mise en place du patron de conception Function Object en Java, un tutoriel de Yann Caron


Sujet :

Langage Java

  1. #1
    Rédacteur
    Avatar de CyaNnOrangehead
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    777
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2008
    Messages : 777
    Points : 1 731
    Points
    1 731
    Par défaut Réflexion sur la mise en place du patron de conception Function Object en Java, un tutoriel de Yann Caron
    Bonjour à tous,

    Je vous propose un petit article intitulé : « Fonction Object Design pattern - Tutoriel sur les foncteurs - En attendant les lambdas de Java 8 » disponible ici : http://caron-yann.developpez.com/tut...osures-java-8/

    Ce tutoriel ce compose comme suit :
    • une présentation du design pattern « function object » ou plus connu sous le nom de foncteur ;
    • une implémentation de celui-ci en Java qui respecte le principe de signature des méthodes en s'appuyant sur les génériques (ce qui n'est pas tout à fait le cas de librairies telles que Guava) ;
    • des cas concrets d'utilisations comme la création de callbacks, l’ajout de méthodes fonctionnelles aux listes (each et map-filter-reduce), parcours depth-first, décorateur fonctionnel et conteneurs IOC.


    Cette dernière partie est le résultat d'une discussion ouverte avec, entre autrez, Thierry, que je continuerai très volontiers avec vous.
    Elle démontre que Java, depuis la version 5 de son framework, n'a rien à envier à des langages tels que Ruby. Et qu'il n'est pas nécessaire de ce mettre à Groovy pour faire du fonctionnel avec le langage Java.

    Et n'oubliez pas de commenter cet article. Vos retours nous aident à améliorer nos publications.

    Bonne lecture.

  2. #2
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Il me semblerait intéressant de compléter avec deux choses:
    - un véritable pattern Commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    public interface CommandFor<T> {
        public  void invokeOn(T instance);
    }
     
    public class CommandForDoer  implements CommandFor<Doer>, Serializable {
        private final String aString ;
        private final int anInt ;
     
        public CommandForDoer(String aString, int anInt) {
            this.aString = aString;
            this.anInt = anInt;
        }
     
        @Override
        public void invokeOn(Doer instance) {
            instance.show(aString, anInt);
        }
    }
    avec utilisations

    - un exemple de dynamic Proxy

  3. #3
    Rédacteur
    Avatar de CyaNnOrangehead
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    777
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2008
    Messages : 777
    Points : 1 731
    Points
    1 731
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    Il me semblerait intéressant de compléter avec deux choses:
    - un véritable pattern Commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    public interface CommandFor<T> {
        public  void invokeOn(T instance);
    }
     
    public class CommandForDoer  implements CommandFor<Doer>, Serializable {
        private final String aString ;
        private final int anInt ;
     
        public CommandForDoer(String aString, int anInt) {
            this.aString = aString;
            this.anInt = anInt;
        }
     
        @Override
        public void invokeOn(Doer instance) {
            instance.show(aString, anInt);
        }
    }
    avec utilisations
    Citation Envoyé par professeur shadoko Voir le message
    Oui très bonne idée.
    Citation Envoyé par professeur shadoko Voir le message
    - un exemple de dynamic Proxy
    Excellent, effectivement il y a moyen de faire des trucs pas mal en combinant les deux techniques.
    Je regarde dés que j'ai un moment !

  4. #4
    Rédacteur
    Avatar de CyaNnOrangehead
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    777
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2008
    Messages : 777
    Points : 1 731
    Points
    1 731
    Par défaut
    Voici également la résolution d'un problème que je voulais ajouter :
    Compter le nombre de fois ou l'on trouve un mot dans un texte.

    Le principe est le suivant :
    Un premier map/reduce s'occupe du split "\n"
    Un second, à l'intérieur s'occupe de compter les mots "elements"

    Voilà ce que ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    	public void testCountWords() throws Exception {
     
    		String csv = "" +
    			"element 1.1, element 1.2, element 1.3, element 1.4\n" +
    			"element 2.1, element 2.2\n" +
    			"element 3.1, element 3.2, element 3.3\n" +
    			"element 4.1, element 4.2, element 4.3, element 4.4, element 4.5\n" +
    			"";
     
    		int count = split(csv, "\n").<Integer>map(new Function<Integer, Arguments2<String, Integer>>() {
     
    			@Override
    			public Integer invoke(Arguments2<String, Integer> arguments) {
    				// the line
    				System.out.println("Line : " + arguments.getArgument1());
     
    				return split(arguments.getArgument1(), " ").<Integer>map(new Function<Integer, Arguments2<String, Integer>>() {
     
    					@Override
    					public Integer invoke(Arguments2<String, Integer> arguments) {
    						// the element
    						System.out.println("Word :" + arguments.getArgument1());
     
    						if ("element".equalsIgnoreCase(arguments.getArgument1())) {
    							return 1;
    						} else {
    							return 0;
    						}
    					}
    				}).reduce(new Function<Integer, Arguments2<Integer, Integer>>() {
     
    					@Override
    					public Integer invoke(Arguments2<Integer, Integer> arguments) {
    						return arguments.getArgument1() + arguments.getArgument2();
    					}
    				});
     
    			}
    		}).reduce(new Function<Integer, Arguments2<Integer, Integer>>() {
     
    			@Override
    			public Integer invoke(Arguments2<Integer, Integer> arguments) {
    						return arguments.getArgument1() + arguments.getArgument2();
    			}
    		});
     
    		System.out.println("number of 'element' word in text : " + count);
     
    	}

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 144
    Points : 97
    Points
    97
    Par défaut
    Merci pour cet article complet mais je ne vois pas très bien l'intérêt de la solution proposée: y-a-t-il un cas d'utilisation réel emblématique qui permettrait de bien comprendre l'utilité concrète de cette implémentation?

  6. #6
    Rédacteur
    Avatar de CyaNnOrangehead
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    777
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2008
    Messages : 777
    Points : 1 731
    Points
    1 731
    Par défaut
    Citation Envoyé par LDPDC Voir le message
    Merci pour cet article complet mais je ne vois pas très bien l'intérêt de la solution proposée: y-a-t-il un cas d'utilisation réel emblématique qui permettrait de bien comprendre l'utilité concrète de cette implémentation?
    Salut LDPDC,
    Déjà, cet article est un ensemble de réflexions sur le design pattern Function Object.
    Le cas concret emblématique c'est la manipulation des listes qui est présentée dans le chapitre map / filter / reduce
    Cette approche est complètement différente de l'approche impérative classique de java (et autres).

    Le but en soi du fonctionnel à ce niveau est de rendre plus concis et plus lisible le code pour gérer des listes (évidement, avec les générique imposés par java, comme ça, ça ne saute pas aux yeux ).
    Guava, bien qu'un petit peu plus limité au niveaux des définitions des foncteurs, propose une très bonne implémentation de ce que j'expose.

    Ce week-end, j'ai essayé le langage Scala qui est fondé sur une fusion fonctionnel / objet, on y retrouve tout ça et bien plus. J'y ai écrit les exemples de cet article, et là pour le coup c'est le code source est vraiment concis (moins de 5 lignes pour faire la moyenne des âges chiens mâles d'une liste d'individus).
    5 lignes également pour le parcours d'un csv.

    L'autre intérêt de tout ceci, c'est surtout de cacher l'implémentation des manipulations de listes à l'utilisateur. Ca permet, entre autre, de faire joujou avec les threads à son insu de façon à optimiser de façon transparent pour l'utilisateur. Un exemple en annexe illustre ceci.

  7. #7
    Membre expérimenté Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Developpeur Java/JEE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Points : 1 622
    Points
    1 622
    Par défaut
    Un article vraiment intéressant !

    J'ai bien aimé le coté "réflexion à haute voix". Ça apporte à mon sens une facilité de lecture et on comprends tout de suite dans quoi on met les pieds.

    En bref, je vais me laisser le temps de digérer tout ça, et je pense bien rajouter ce pattern dans ma boite à outils.

    Cdt.

  8. #8
    Rédacteur
    Avatar de CyaNnOrangehead
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    777
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2008
    Messages : 777
    Points : 1 731
    Points
    1 731
    Par défaut
    Citation Envoyé par Nico02 Voir le message
    Un article vraiment intéressant !

    J'ai bien aimé le coté "réflexion à haute voix". Ça apporte à mon sens une facilité de lecture et on comprends tout de suite dans quoi on met les pieds.

    En bref, je vais me laisser le temps de digérer tout ça, et je pense bien rajouter ce pattern dans ma boite à outils.

    Cdt.
    Oui foncteur est un pattern ultra utile quand on y a goûter.

    Après mon implémentation est très puriste sur les arguments, leur nombre et leurs types, mais la contrepartie c'est qu'elle oblige à créer énormément d'objet Arguments et c'est pas idéal pour les performances.
    Un interface de ce type est plus rapide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public interface Function1 <R, A1> {
      R invoke (A1 arg1);
    }
     
    public interface Function2 <R, A1, A2> {
      R invoke (A1 arg1, A2 arg2);
    }

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/09/2013, 19h30
  2. question sur la mise en place d'une architecture glpi oracle
    Par sousoujda2 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 17/08/2008, 17h07
  3. conseil sur la mise en place d une solution BI
    Par pass38 dans le forum Approche théorique du décisionnel
    Réponses: 7
    Dernier message: 23/06/2008, 19h32
  4. Aide sur la mise en place en réseau de PC
    Par NELAIN dans le forum Administration
    Réponses: 2
    Dernier message: 10/04/2007, 19h24
  5. Réponses: 3
    Dernier message: 25/08/2006, 19h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo