Exemples de modèles de conception GoF dans les bibliothèques principales de Java

J’apprends les modèles de conception Java de GoF et je veux en voir des exemples concrets. Quels sont les bons exemples de ces modèles de conception dans les bibliothèques principales de Java?

Vous pouvez trouver un aperçu de beaucoup de modèles de conception dans Wikipedia . Il mentionne également les modèles mentionnés par le GoF. Je vais les résumer ici et essayer d’atsortingbuer autant d’implémentations de modèles que possible, à la fois dans les API Java SE et Java EE.


Motifs de création

Fabrique abstraite (reconnaissable par des méthodes créatives renvoyant la fabrique elle-même qui peut à son tour être utilisée pour créer un autre type abstrait / d’interface)

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

Builder (reconnaissable par des méthodes de création renvoyant l’instance elle-même)

  • java.lang.SsortingngBuilder#append() (non synchronisé)
  • java.lang.SsortingngBuffer#append() (synchronisé)
  • java.nio.ByteBuffer#put() (également sur CharBuffer , ShortBuffer , IntBuffer , LongBuffer , FloatBuffer et DoubleBuffer )
  • javax.swing.GroupLayout.Group#addComponent()
  • Toutes les implémentations de java.lang.Appendable
  • java.util.stream.Stream.Builder

Méthode d’usine (reconnaissable par des méthodes créatives renvoyant 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(Ssortingng) (Retourne l’object 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 renvoyant une instance différente de lui-même avec les mêmes propriétés)

  • java.lang.Object#clone() (la classe doit implémenter java.lang.Cloneable )

Singleton (reconnaissable par des méthodes de création renvoyant la même instance (généralement de lui-même) à chaque fois)

  • java.lang.Runtime#getRuntime()
  • java.awt.Desktop#getDesktop()
  • java.lang.System#getSecurityManager()

Modèles structurels

Adaptateur (reconnaissable par des méthodes de création prenant une instance de type abstrait / interface différent et renvoyant une implémentation de son propre type / autre résumé / interface qui décore / remplace l’instance donnée)

  • java.util.Arrays#asList()
  • java.util.Collections#list()
  • java.util.Collections#enumeration()
  • java.io.InputStreamReader(InputStream) (renvoie un Reader )
  • java.io.OutputStreamWriter(OutputStream) (renvoie un Writer )
  • javax.xml.bind.annotation.adapters.XmlAdapter#marshal() et #unmarshal()

Bridge (reconnaissable par des méthodes de création prenant une instance de type abstrait / interface différent et renvoyant une implémentation de son propre type abstrait / interface qui délègue / utilise l’instance donnée)

  • Aucun ne vient encore à l’esprit. Un exemple fictif serait le new LinkedHashMap(LinkedHashSet, List) qui renvoie un mappage lié non modifiable qui ne clone pas les éléments, mais les utilise . Les java.util.Collections#newSetFromMap() et singletonXXX() toutefois proches.

Composite (reconnaissable par des méthodes comportementales prenant une instance du même type abstrait / interface dans une structure arborescente)

  • java.awt.Container#add(Component) (pratiquement partout sur Swing)
  • javax.faces.component.UIComponent#getChildren() pratiquement partout sur l’interface utilisateur JSF

Décorateur (reconnaissable par des méthodes de création prenant une instance du même type abstrait / interface qui ajoute un comportement supplémentaire)

  • Toutes les sous-classes de java.io.InputStream , OutputStream , Reader et Writer ont un constructeur prenant une instance du même type.
  • java.util.Collections , les checkedXXX() , synchronizedXXX() et unmodifiableXXX() .
  • javax.servlet.http.HttpServletRequestWrapper et HttpServletResponseWrapper
  • javax.swing.JScrollPane

Facade (reconnaissable par des méthodes comportementales qui utilisent en interne des instances de différents types abstraits / interfaces indépendants)

  • javax.faces.context.FacesContext , il utilise en interne entre autres les types abstract / interface LifeCycle , ViewHandler , NavigationHandler et bien d’autres, sans que l’utilisateur final ait à se soucier de cela (qui peut toutefois être surpassé par l’injection).
  • javax.faces.context.ExternalContext , qui utilise en interne ServletContext , HttpSession , HttpServletRequest , HttpServletResponse , etc.

Flyweight (reconnaissable par des méthodes de création renvoyant une instance en cache, un peu l’idée “multiton”)

  • java.lang.Integer#valueOf(int) (également sur Boolean , Byte , Character , Short , Long et BigDecimal )

Proxy (reconnaissable par des méthodes de création qui renvoie une implémentation de type abstrait / interface donné, qui à son tour délègue / utilise une implémentation différente 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

Motifs comportementaux

Chaîne de responsabilité (reconnaissable par des méthodes comportementales qui invoquent (indirectement) la même méthode dans une autre implémentation du même type abstrait / interface dans une queue)

  • java.util.logging.Logger#log()
  • javax.servlet.Filter#doFilter()

Commande (reconnaissable par des méthodes comportementales dans un type abstrait / interface qui invoque une méthode dans une implémentation d’un type abstrait / interface différent qui a été encapsulé 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 des méthodes comportementales renvoyant une instance / un type structurellement différent de l’instance / du type donné; notez que l’parsing / formatage ne fait pas partie du modèle, en déterminant le modèle et comment l’appliquer)

  • java.util.Pattern
  • java.text.Normalizer
  • Toutes les sous-classes de java.text.Format
  • Toutes les sous-classes de javax.el.ELResolver

Iterator (reconnaissable par des méthodes comportementales renvoyant séquentiellement des instances d’un type différent d’une queue)

  • Toutes les implémentations de java.util.Iterator (donc entre autres aussi java.util.Scanner !).
  • Toutes les implémentations de java.util.Enumeration

Mediator (reconnaissable par des méthodes comportementales prenant une instance de 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 (toutes scheduleXXX() méthodes scheduleXXX() )
  • java.util.concurrent.Executor#execute()
  • java.util.concurrent.ExecutorService (les invokeXXX() et submit() )
  • java.util.concurrent.ScheduledExecutorService (toutes scheduleXXX() méthodes scheduleXXX() )
  • java.lang.reflect.Method#invoke()

Memento (reconnaissable par des méthodes comportementales qui modifient en interne l’état de toute l’ instance)

  • java.util.Date (les méthodes setter font cela, Date est représenté en interne par une valeur long )
  • Toutes les implémentations de java.io.Serializable
  • Toutes les implémentations de javax.faces.component.StateHolder

Observer (ou Publish / Subscribe) (reconnaissable par des méthodes comportementales qui invoquent une méthode sur une instance d’ un autre type abstrait / d’interface, en fonction de son propre état)

  • java.util.Observer / java.util.Observable (rarement utilisé dans le monde réel)
  • Toutes les implémentations de java.util.EventListener (pratiquement partout sur Swing)
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAtsortingbuteListener
  • javax.faces.event.PhaseListener

Etat (reconnaissable par des méthodes comportementales qui modifient son comportement en fonction de l’état de l’instance pouvant être contrôlé en externe)

  • javax.faces.lifecycle.LifeCycle#execute() (contrôlé par FacesServlet , le comportement dépend de la phase en cours (état) du cycle de vie JSF)

Stratégie (reconnaissable par des méthodes comportementales dans un type abstrait / interface qui invoque une méthode dans une implémentation d’un type abstrait / interface différent qui a été passé en tant qu’argument de méthode dans l’implémentation de la stratégie)

  • java.util.Comparator#compare() , exécuté par d’autres Collections#sort() .
  • javax.servlet.http.HttpServlet , les javax.servlet.http.HttpServlet service() et doXXX() prennent HttpServletRequest et HttpServletResponse et l’implémenteur doit les traiter (et ne pas les saisir comme variables d’instance!).
  • javax.servlet.Filter#doFilter()

Méthode de modèle (reconnaissable par des 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 et java.io.Writer .
  • Toutes les méthodes non abstraites de java.util.AbstractList , java.util.AbstractSet et java.util.AbstractMap .
  • javax.servlet.http.HttpServlet , toutes les méthodes doXXX() par défaut une erreur HTTP 405 “Method Not Allowed” à la réponse. Vous êtes libre d’implémenter aucun ou aucun d’entre eux.

Visiteur (reconnaissable par deux types abstraits / interfaces différents qui ont des méthodes définies qui prennent chacun le type abstrait / interface, l’un appelle la méthode de l’autre et l’autre exécute la stratégie désirée)

  • javax.lang.model.element.AnnotationValue et AnnotationValueVisitor
  • javax.lang.model.element.Element et ElementVisitor
  • javax.lang.model.type.TypeMirror et TypeVisitor
  • java.nio.file.FileVisitor et SimpleFileVisitor
  • javax.faces.component.visit.VisitContext et VisitCallback
  1. Modèle d’observateur tout au long du swing ( Observable , Observer )
  2. MVC aussi en mouvement
  3. Modèle d’adaptateur: InputStreamReader et OutputStreamWriter REMARQUE: ContainerAdapter , ComponentAdapter , FocusAdapter , KeyAdapter , MouseAdapter ne sont pas des adaptateurs; ce sont en réalité des objects nuls. Choix de nom médiocre par Sun.
  4. Modèle de décorateur ( BufferedInputStream peut décorer d’autres stream tels que FilterInputStream )
  5. AbstractFactory Pattern pour AWT Toolkit et les classes de look-and-feel enfichables Swing
  6. java.lang.Runtime#getRuntime() est Singleton
  7. ButtonGroup pour le modèle Mediator
  8. Action , AbstractAction peut être utilisé pour différentes représentations visuelles pour exécuter le même code -> Modèle de commande
  9. Chaînes internées ou CellRender dans JTable pour Flyweight Pattern (pensez aussi à différents pools – Pools de threads, pools de connexions, pools d’objects EJB – Le poids est vraiment une question de gestion des ressources partagées)
  10. Le modèle d’événement Java 1.0 est un exemple de chaîne de responsabilité, tout comme les filtres de servlet.
  11. Modèle d’iterator dans le cadre des collections
  12. Les conteneurs nesteds dans AWT / Swing utilisent le motif composite
  13. Les gestionnaires de disposition dans AWT / Swing sont un exemple de stratégie

et beaucoup plus je suppose

  1. Flyweight est utilisé avec certaines valeurs de Byte, Short, Integer, Long et Ssortingng.
  2. La façade est utilisée dans de nombreux endroits, mais la plus évidente est celle des interfaces de script.
  3. Singleton – java.lang.Runtime vient à l’esprit.
  4. Abstract Factory – Aussi scripting et API JDBC.
  5. Commande – Undo / Redo du composant TextComponent.
  6. Interpreter – RegEx (java.util.regex. ) Et SQL (java.sql. ) API.
  7. Prototype – Pas sûr à 100% si ce nombre, mais je pense que la méthode clone() peut être utilisée à cette fin.

RMI est basé sur Proxy.

Devrait être possible d’en citer un pour la plupart des 23 modèles du GoF:

  1. Abstract Factory: les interfaces java.sql reçoivent toutes leurs implémentations concrètes à partir du JDBC JAR lorsque le pilote est enregistré.
  2. Générateur: java.lang.SsortingngBuilder.
  3. Méthode d’usine: usines XML, entre autres.
  4. Prototype: Peut-être clone (), mais je ne suis pas sûr d’acheter ça.
  5. Singleton: java.lang.System
  6. Adapter: Classes d’adaptateur dans java.awt.event, par exemple, WindowAdapter.
  7. Bridge: classes de collection dans java.util. Liste implémentée par ArrayList.
  8. Composite: java.awt. java.awt.Component + java.awt.Container
  9. Décorateur: partout dans le package java.io.
  10. Façade: ExternalContext se comporte comme une façade pour effectuer des opérations de cookie, de session et similaires.
  11. Poids mouche: Entier, Caractère, etc.
  12. Proxy: package java.rmi
  13. Chaîne de responsabilité: filtres Servlet
  14. Commande: balancer les éléments du menu
  15. Interpreter: Non directement dans JDK, mais JavaCC l’utilise certainement.
  16. Iterator: interface java.util.Iterator; ne peut pas être plus clair que cela.
  17. Mediator: JMS?
  18. Mémento:
  19. Observateur: java.util.Observer/Observable (mal fait, cependant)
  20. Etat:
  21. Stratégie:
  22. Modèle:
  23. Visiteur:

Je ne peux pas penser à des exemples en Java pour 10 sur 23, mais je verrai si je peux faire mieux demain. C’est pour cela que l’édition est

Le motif de la fabrique abstraite est utilisé à divers endroits. Par exemple, DatagramSocketImplFactory , PreferencesFactory . Il y en a beaucoup plus – cherchez dans le Javadoc des interfaces qui portent le mot “Factory”.

Il y a aussi quelques exemples du modèle Factory.

Même si je suis en quelque sorte une horloge cassée avec celle-ci, l’API Java XML utilise beaucoup Factory. Je veux dire juste regarder ceci:

 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); Ssortingng title = XPathFactory.newInstance().newXPath().evaluate("//title", doc); 

…et ainsi de suite.

De plus, divers tampons (SsortingngBuffer, ByteBuffer, SsortingngBuilder) utilisent Builder.

  • Méthode d’usine

java.util.Collection # Iterator est un bon exemple de méthode d’usine. Selon la sous-classe concrète de Collection que vous utilisez, cela créera une implémentation Iterator. Comme la superclasse Factory (Collection) et l’iterator créés sont tous deux des interfaces, ils sont parfois confondus avec AbstractFactory. La plupart des exemples de AbstractFactory dans la réponse acceptée (BalusC) sont des exemples de Factory , une version simplifiée de la méthode Factory, qui ne fait pas partie des modèles GoF originaux. Dans Facory, la hiérarchie de classes Factory est réduite et la fabrique utilise d’autres moyens pour choisir le produit à retourner.

  • Usine abstraite

Une usine abstraite a plusieurs méthodes d’usine, chacune créant un produit différent. Les produits fabriqués par une usine sont destinés à être utilisés ensemble (votre imprimante et vos cartouches doivent provenir de la même usine (abstraite)). Comme mentionné dans les réponses ci-dessus, les familles de composants de l’interface graphique AWT, qui diffèrent d’une plateforme à l’autre, en sont un exemple (bien que leur implémentation diffère de celle décrite dans Gof).