Je suis en train d'apprendre les modèles de conception Java GoF et je veux voir des exemples concrets de ces modèles. Quels sont les bons exemples de ces Design Patterns dans les bibliothèques de base de Java ?
Réponses
Trop de publicités?Vous pouvez trouver une vue d'ensemble de nombreux modèles de conception dans Wikipedia . Il mentionne également les motifs mentionnés par GoF. Je les résumerai ici et j'essaierai d'attribuer autant d'implémentations de patrons que possible, trouvés à la fois dans les API Java SE et Java EE.
Modèles créatifs
Usine abstraite (reconnaissable aux méthodes de création renvoyant la fabrique elle-même qui, à son tour, peut être utilisée pour créer un autre type abstrait/interface)
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance()
Constructeur (reconnaissable par les méthodes de création retournant l'instance elle-même)
-
java.lang.StringBuilder#append()
(non synchronisé) -
java.lang.StringBuffer#append()
(synchronisé) -
java.nio.ByteBuffer#put()
(également surCharBuffer
,ShortBuffer
,IntBuffer
,LongBuffer
,FloatBuffer
yDoubleBuffer
) javax.swing.GroupLayout.Group#addComponent()
- Toutes les implémentations de
java.lang.Appendable
java.util.stream.Stream.Builder
Méthode d'usine (reconnaissable par les méthodes de création retournant une implémentation d'un type abstrait/interface)
java.util.Calendar#getInstance()
java.util.ResourceBundle#getBundle()
java.text.NumberFormat#getInstance()
java.nio.charset.Charset#forName()
-
java.net.URLStreamHandlerFactory#createURLStreamHandler(String)
(Renvoie un objet singleton par protocole) java.util.EnumSet#of()
-
javax.xml.bind.JAXBContext#createMarshaller()
et d'autres méthodes similaires
Prototype (reconnaissable par les méthodes de création retournant un <em>différents </em>instance de lui-même avec les mêmes propriétés)
-
java.lang.Object#clone()
(la classe doit implémenterjava.lang.Cloneable
)
Singleton (reconnaissable par les méthodes de création renvoyant le <em>même </em>instance (généralement de lui-même) à chaque fois)
Modèles structurels
Adaptateur (reconnaissable par des méthodes de création prenant une instance de <em>différents </em>abstrait/interface et renvoyer une implémentation de son propre/autre type abstrait/interface qui <em>décore/supprime </em>l'instance donnée)
java.util.Arrays#asList()
java.util.Collections#list()
java.util.Collections#enumeration()
-
java.io.InputStreamReader(InputStream)
(renvoie unReader
) -
java.io.OutputStreamWriter(OutputStream)
(renvoie unWriter
) -
javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
y#unmarshal()
Pont (reconnaissable par des méthodes de création prenant une instance de <em>différents </em>et retourner une implémentation de son propre type d'abstraction/interface qui <em>délégués/utilisateurs </em>l'instance donnée)
- Aucune ne me vient encore à l'esprit. Un exemple fictif serait
new LinkedHashMap(LinkedHashSet<K>, List<V>)
qui renvoie une carte liée non modifiable qui ne clone pas les éléments, mais utilise les. Le sitejava.util.Collections#newSetFromMap()
ysingletonXXX()
Cependant, les méthodes d'analyse s'en rapprochent.
Composite (reconnaissable par des méthodes comportementales prenant une instance de <em>même </em>type abstrait/interface dans une structure arborescente)
-
java.awt.Container#add(Component)
(pratiquement partout dans Swing donc) -
javax.faces.component.UIComponent#getChildren()
(pratiquement partout dans JSF UI donc)
Décorateur (reconnaissable par des méthodes de création prenant une instance de <em>même </em>type abstrait/interface qui ajoute un comportement supplémentaire)
- Toutes les sous-classes de
java.io.InputStream
,OutputStream
,Reader
yWriter
ont un constructeur prenant une instance du même type. -
java.util.Collections
lecheckedXXX()
,synchronizedXXX()
yunmodifiableXXX()
méthodes. -
javax.servlet.http.HttpServletRequestWrapper
yHttpServletResponseWrapper
javax.swing.JScrollPane
Façade (reconnaissable par les méthodes comportementales qui utilisent en interne des instances de <em>différents </em>types abstraits/interfaces indépendants)
-
javax.faces.context.FacesContext
il utilise en interne, entre autres, les types abstraits/interfaces suivantsLifeCycle
,ViewHandler
,NavigationHandler
et bien d'autres sans que l'utilisateur final ait à s'en préoccuper (qui sont cependant surmontables par injection). -
javax.faces.context.ExternalContext
qui utilise en interneServletContext
,HttpSession
,HttpServletRequest
,HttpServletResponse
etc.
Poids plume (reconnaissable par des méthodes de création retournant une instance en cache, un peu l'idée de "multiton")
-
java.lang.Integer#valueOf(int)
(également surBoolean
,Byte
,Character
,Short
,Long
yBigDecimal
)
Proxy (reconnaissable par des méthodes de création qui renvoient une implémentation d'un type abstrait/interface donné, qui à son tour <em>délégués/utilisateurs </em>a <em>différents </em>implémentation d'un type abstrait/interface donné)
java.lang.reflect.Proxy
java.rmi.*
-
javax.ejb.EJB
( explication ici ) -
javax.inject.Inject
( explication ici ) javax.persistence.PersistenceContext
Modèles de comportement
Chaîne de responsabilité (reconnaissable par les méthodes comportementales qui invoquent (indirectement) la même méthode en <em>un autre </em>mise en œuvre de <em>même </em>type abstrait/interface dans une file d'attente)
Commande (reconnaissable par les méthodes comportementales d'un type abstrait/interface qui invoque une méthode dans une mise en œuvre d'une <em>différents </em>type abstrait/interface qui a été <em>encapsulé </em>par l'implémentation de la commande lors de sa création)
- Toutes les implémentations de
java.lang.Runnable
- Toutes les implémentations de
javax.swing.Action
Interprète (reconnaissable par les méthodes comportementales retournant un <em>structurellement </em>instance/type différent(e) de l'instance/du type donné(e) ; notez que l'analyse syntaxique/le formatage ne fait pas partie du modèle, la détermination du modèle et la manière de l'appliquer en font partie)
java.util.Pattern
java.text.Normalizer
- Toutes les sous-classes de
java.text.Format
- Toutes les sous-classes de
javax.el.ELResolver
Itérateur (reconnaissable par les méthodes comportementales renvoyant séquentiellement des instances d'une <em>différents </em>d'une file d'attente)
- Toutes les implémentations de
java.util.Iterator
(ainsi, entre autres, égalementjava.util.Scanner
!). - Toutes les implémentations de
java.util.Enumeration
Médiateur (reconnaissable par des méthodes comportementales prenant une instance d'un type abstrait/interface différent (utilisant généralement le modèle de commande) qui délègue/utilise l'instance donnée)
-
java.util.Timer
(tousscheduleXXX()
méthodes) java.util.concurrent.Executor#execute()
-
java.util.concurrent.ExecutorService
(leinvokeXXX()
ysubmit()
méthodes) -
java.util.concurrent.ScheduledExecutorService
(tousscheduleXXX()
méthodes) java.lang.reflect.Method#invoke()
Memento (reconnaissable par des méthodes comportementales qui changent en interne l'état de la <em>ensemble du site </em>instance)
-
java.util.Date
(les méthodes setter le font,Date
est représenté en interne par unlong
valeur) - Toutes les implémentations de
java.io.Serializable
- Toutes les implémentations de
javax.faces.component.StateHolder
Observateur (ou Publier/S'abonner) (reconnaissable aux méthodes comportementales qui invoquent une méthode sur une instance de <em>un autre </em>type abstrait/interface, selon l'état propre)
-
java.util.Observer
/java.util.Observable
(rarement utilisé dans le monde réel cependant) - Toutes les implémentations de
java.util.EventListener
(pratiquement partout dans Swing donc) javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
État (reconnaissable par des méthodes comportementales qui modifient son comportement en fonction de l'état de l'instance qui peut être contrôlé de l'extérieur)
-
javax.faces.lifecycle.LifeCycle#execute()
(contrôlé parFacesServlet
le comportement dépend de la phase (état) actuelle du cycle de vie de JSF).
Stratégie (reconnaissable par les méthodes comportementales d'un type abstrait/interface qui invoque une méthode dans une mise en œuvre d'une <em>différents </em>type abstrait/interface qui a été <em>adopté </em>comme argument de méthode dans la mise en œuvre de la stratégie)
-
java.util.Comparator#compare()
exécuté, entre autres, parCollections#sort()
. -
javax.servlet.http.HttpServlet
leservice()
et toutdoXXX()
les méthodes prennentHttpServletRequest
yHttpServletResponse
et l'implémenteur doit les traiter (et non pas s'en emparer comme variables d'instance !). javax.servlet.Filter#doFilter()
Méthode du modèle (reconnaissable par les méthodes comportementales qui ont déjà un comportement "par défaut" défini par un type abstrait)
- Toutes les méthodes non abstraites de
java.io.InputStream
,java.io.OutputStream
,java.io.Reader
yjava.io.Writer
. - Toutes les méthodes non abstraites de
java.util.AbstractList
,java.util.AbstractSet
yjava.util.AbstractMap
. -
javax.servlet.http.HttpServlet
tous lesdoXXX()
envoie par défaut une erreur HTTP 405 "Method Not Allowed" à la réponse. Vous êtes libre de ne pas mettre en œuvre l'une ou l'autre de ces méthodes.
Visiteur (reconnaissable par deux <em>différents </em>des types abstraits/interfaces qui ont des méthodes définies qui prennent chaque <em>autre </em>type abstrait/interface ; l'un appelle effectivement la méthode de l'autre et l'autre exécute la stratégie souhaitée sur celle-ci)
- Motif d'observateur dans tout le swing (
Observable
,Observer
) - MVC aussi dans le swing
- Modèle d'adaptateur : InputStreamReader et OutputStreamWriter NOTE :
ContainerAdapter
,ComponentAdapter
,FocusAdapter
,KeyAdapter
,MouseAdapter
son no adaptateurs ; ils sont en fait des Null Objects. Mauvais choix de dénomination de la part de Sun. - Motif décorateur (
BufferedInputStream
peut décorer d'autres flux tels queFilterInputStream
) - Modèle AbstractFactory pour la boîte à outils AWT et les classes de look-and-feel enfichables Swing.
-
java.lang.Runtime#getRuntime()
est Singleton -
ButtonGroup
pour le modèle de médiateur -
Action
,AbstractAction
peut être utilisé pour différentes représentations visuelles pour exécuter le même code -> Modèle de commande - Chaînes internes ou CellRender dans JTable pour le modèle Flyweight (pensez aussi aux différents pools - pools de threads, pools de connexions, pools d'objets EJB - Flyweight est vraiment une question de gestion de ressources partagées).
- Le modèle d'événement Java 1.0 est un exemple de chaîne de responsabilité, tout comme les filtres de servlets.
- Modèle d'itérateur dans le cadre des collections
- Les conteneurs imbriqués dans AWT/Swing utilisent le modèle Composite.
- Les gestionnaires de mise en page dans AWT/Swing sont un exemple de stratégie.
et bien d'autres encore, je suppose
- Poids plume est utilisé avec certaines valeurs de Byte, Short, Integer, Long et String.
- Façade est utilisé dans de nombreux endroits, mais le plus évident est celui des interfaces de script.
- Singleton - Je pense à java.lang.Runtime.
- Usine abstraite - Egalement Scripting et JDBC API.
- Commande - Undo/Redo de TextComponent.
- Interprète - RegEx (java.util.regex. ) et SQL (java.sql. ) API.
-
Prototype - Je ne suis pas sûr à 100% que ça compte, mais je pense que
clone()
peut être utilisée à cette fin.
RMI est basé sur le Proxy.
Il devrait être possible d'en citer un pour la plupart des 23 motifs du GdF :
- Fabrique abstraite : les interfaces java.sql obtiennent toutes leurs implémentations concrètes à partir du JAR JDBC lorsque le pilote est enregistré.
- Constructeur : java.lang.StringBuilder.
- Méthode d'usine : Usines XML, entre autres.
- Prototype : Peut-être clone(), mais je ne suis pas sûr d'y croire.
- Singleton : java.lang.System
- Adaptateur : Classes d'adaptateur dans java.awt.event, par exemple WindowAdapter.
- Pont : Classes de collection en java.util. Liste implémentée par ArrayList.
- Composite : java.awt. java.awt.Component + java.awt.Container
- Décorateur : Partout dans le paquet java.io.
- Façade : ExternalContext se comporte comme une façade permettant d'effectuer des opérations sur les cookies, la portée de la session et autres opérations similaires.
- Poids plume : Entier, caractère, etc.
- Proxy : paquet java.rmi
- Chaîne de responsabilité : Les filtres de servlets
- Commandement : Faire pivoter les éléments du menu
- Interprète : Pas directement dans le JDK, mais JavaCC l'utilise certainement.
- Iterator : interface java.util.Iterator ; on ne peut pas être plus clair que ça.
- Médiateur : JMS ?
- Memento :
- Observer : java.util.Observer/Observable (mal fait, cependant)
- État :
- Stratégie :
- Modèle :
- Visiteur :
Je n'arrive pas à trouver d'exemples en Java pour 10 des 23, mais je verrai si je peux faire mieux demain. C'est à ça que sert l'édition.
- Réponses précédentes
- Plus de réponses