Esempi di modelli di progettazione GoF nelle librerie principali di Java

Sto imparando i modelli di progettazione Java GoF e voglio vedere alcuni esempi di vita reale di loro. Quali sono alcuni buoni esempi di questi modelli di progettazione nelle librerie principali di Java?

Puoi trovare una panoramica di molti modelli di design in Wikipedia . Indica anche quali modelli sono citati da GoF. Li riassumerò qui e cercherò di assegnare il maggior numero ansible di implementazioni di pattern, che si trovano sia nelle API Java SE che in Java EE.


Schemi creativi

Fabbrica astratta (riconoscibile dai metodi creazionali che restituiscono la fabbrica stessa che a sua volta può essere utilizzata per creare un altro tipo di astratto / interfaccia)

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

Builder (riconoscibile dai metodi creazionali che restituiscono l’istanza stessa)

  • java.lang.StringBuilder#append() (non sincronizzato)
  • java.lang.StringBuffer#append() (sincronizzato)
  • java.nio.ByteBuffer#put() (anche su CharBuffer , ShortBuffer , IntBuffer , LongBuffer , FloatBuffer e DoubleBuffer )
  • javax.swing.GroupLayout.Group#addComponent()
  • Tutte le implementazioni di java.lang.Appendable
  • java.util.stream.Stream.Builder

Metodo factory (riconoscibile dai metodi creazionali che restituiscono un’implementazione di un tipo abstract / interface)

  • java.util.Calendar#getInstance()
  • java.util.ResourceBundle#getBundle()
  • java.text.NumberFormat#getInstance()
  • java.nio.charset.Charset#forName()
  • java.net.URLStreamHandlerFactory#createURLStreamHandler(String) (Restituisce object singleton per protocollo)
  • java.util.EnumSet#of()
  • javax.xml.bind.JAXBContext#createMarshaller() e altri metodi simili

Prototipo (riconoscibile dai metodi creazionali che restituiscono una diversa istanza di se stessa con le stesse proprietà)

  • java.lang.Object#clone() (la class deve implementare java.lang.Cloneable )

Singleton (riconoscibile dai metodi creazionali che restituiscono la stessa istanza (solitamente di per sé) ogni volta)

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

Schemi strutturali

Adattatore (riconoscibile dai metodi di creazione che prendono un’istanza di diverso tipo di astrazione / interfaccia e restituiscono un’implementazione del proprio / un altro tipo di astratto / interfaccia che decora / sovrascrive l’istanza data)

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

Bridge (riconoscibile dai metodi creazionali che prendono un’istanza di diverso tipo abstract / interface e restituiscono un’implementazione del proprio tipo abstract / interface che delega / utilizza l’istanza data)

  • A nessuno viene in mente ancora. Un esempio fittizio sarebbe la new LinkedHashMap(LinkedHashSet, List) che restituisce una mappa collegata non modificabile che non clona gli oggetti, ma li usa . I java.util.Collections#newSetFromMap() e singletonXXX() tuttavia si avvicinano.

Composito (riconoscibile dai metodi comportamentali che prendono un’istanza dello stesso tipo astratto / interfaccia in una struttura ad albero)

  • java.awt.Container#add(Component) (praticamente su tutto Swing quindi)
  • javax.faces.component.UIComponent#getChildren() (praticamente su tutta la JSF UI quindi)

Decoratore (riconoscibile dai metodi di creazione che prendono un’istanza dello stesso tipo di astratto / interfaccia che aggiunge un ulteriore comportamento)

  • Tutte le sottoclassi di java.io.InputStream , OutputStream , Reader e Writer hanno un costruttore che prende un’istanza dello stesso tipo.
  • java.util.Collections , i checkedXXX() , synchronizedXXX() e unmodifiableXXX() .
  • javax.servlet.http.HttpServletRequestWrapper e HttpServletResponseWrapper
  • javax.swing.JScrollPane

Facciata (riconoscibile dai metodi comportamentali che utilizzano internamente istanze di diversi tipi astratti / di interfaccia indipendenti)

  • javax.faces.context.FacesContext , utilizza internamente tra gli altri i tipi di elementi astratti / di interfaccia LifeCycle , ViewHandler , NavigationHandler e molti altri senza che l’utente finale si debba preoccupare di ciò (che sono comunque sovrascrivibili per iniezione).
  • javax.faces.context.ExternalContext , che utilizza internamente ServletContext , HttpSession , HttpServletRequest , HttpServletResponse , ecc.

Flyweight (riconoscibile dai metodi creazionali che restituiscono un’istanza memorizzata nella cache, un po ‘l’idea “multiton”)

  • java.lang.Integer#valueOf(int) (anche su Boolean , Byte , Character , Short , Long e BigDecimal )

Proxy (riconoscibile dai metodi creazionali che restituiscono un’implementazione di un dato tipo di astrazione / interfaccia che a sua volta delega / utilizza una diversa implementazione di un determinato tipo di astratto / interfaccia)

  • java.lang.reflect.Proxy
  • java.rmi.*
  • javax.ejb.EJB ( spiegazione qui )
  • javax.inject.Inject ( spiegazione qui )
  • javax.persistence.PersistenceContext

Modelli comportamentali

Catena di responsabilità (riconoscibile dai metodi comportamentali che (indirettamente) invoca lo stesso metodo in un’altra implementazione dello stesso tipo astratto / di interfaccia in una coda)

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

Comando (riconoscibile dai metodi comportamentali in un tipo abstract / interface che richiama un metodo in un’implementazione di un diverso tipo di astrazione / interfaccia che è stato incapsulato dall’implementazione del comando durante la sua creazione)

  • Tutte le implementazioni di java.lang.Runnable
  • Tutte le implementazioni di javax.swing.Action

Interprete (riconoscibile dai metodi comportamentali che restituiscono un’istanza / tipo strutturalmente differente dell’istanza / tipo specificata, si noti che l’analisi / formattazione non fa parte del modello, determina il modello e come applicarlo)

  • java.util.Pattern
  • java.text.Normalizer
  • Tutte le sottoclassi di java.text.Format
  • Tutte le sottoclassi di javax.el.ELResolver

Iterator (riconoscibile dai metodi comportamentali che restituiscono in sequenza istanze di un tipo diverso da una coda)

  • Tutte le implementazioni di java.util.Iterator (quindi tra gli altri anche java.util.Scanner !).
  • Tutte le implementazioni di java.util.Enumeration

Mediatore (riconoscibile dai metodi comportamentali che prendono un’istanza di diverso tipo astratto / interfaccia (di solito usando il modello di comando) che delega / utilizza l’istanza data)

  • java.util.Timer (tutti scheduleXXX() metodi scheduleXXX() )
  • java.util.concurrent.Executor#execute()
  • java.util.concurrent.ExecutorService (i invokeXXX() e submit() )
  • java.util.concurrent.ScheduledExecutorService (tutti scheduleXXX() metodi scheduleXXX() )
  • java.lang.reflect.Method#invoke()

Memento (riconoscibile dai metodi comportamentali che cambiano internamente lo stato dell’intera istanza)

  • java.util.Date (i metodi setter lo fanno, Date è internamente rappresentata da un valore long )
  • Tutte le implementazioni di java.io.Serializable
  • Tutte le implementazioni di javax.faces.component.StateHolder

Observer (o Publish / Subscribe) (riconoscibile dai metodi comportamentali che invoca un metodo su un’istanza di un altro tipo di astrazione / interfaccia, a seconda del proprio stato)

  • java.util.Observer / java.util.Observable (usato raramente nel mondo reale)
  • Tutte le implementazioni di java.util.EventListener (praticamente java.util.EventListener su Swing)
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener
  • javax.faces.event.PhaseListener

Stato (riconoscibile dai metodi comportamentali che cambiano il suo comportamento a seconda dello stato dell’istanza che può essere controllato esternamente)

  • javax.faces.lifecycle.LifeCycle#execute() (controllato da FacesServlet , il comportamento dipende dalla fase corrente (stato) del ciclo di vita JSF)

Strategia (riconoscibile dai metodi comportamentali in un tipo di astrazione / interfaccia che richiama un metodo in un’implementazione di un diverso tipo di astratto / interfaccia che è stato passato come argomento del metodo nell’implementazione della strategia)

  • java.util.Comparator#compare() , eseguito tra l’altro Collections#sort() .
  • javax.servlet.http.HttpServlet , il service() e tutti i metodi doXXX() accettano HttpServletRequest e HttpServletResponse e l’implementatore deve elaborarli (e non ottenerli come variabili di istanza!).
  • javax.servlet.Filter#doFilter()

Metodo template (riconoscibile dai metodi comportamentali che hanno già un comportamento “predefinito” definito da un tipo astratto)

  • Tutti i metodi non astratti di java.io.InputStream , java.io.OutputStream , java.io.Reader e java.io.Writer .
  • Tutti i metodi non astratti di java.util.AbstractList , java.util.AbstractSet e java.util.AbstractMap .
  • javax.servlet.http.HttpServlet , tutti i metodi doXXX() per impostazione predefinita inviano un errore HTTP 405 “Metodo non consentito” alla risposta. Sei libero di implementare nessuno o nessuno di essi.

Visitatore (riconoscibile da due diversi tipi di astrazione / interfaccia che ha metodi definiti che prende ciascuno l’ altro tipo di astrazione / interfaccia, quello in realtà chiama il metodo dell’altro e l’altro esegue la strategia desiderata su di esso)

  • javax.lang.model.element.AnnotationValue e AnnotationValueVisitor
  • javax.lang.model.element.Element e ElementVisitor
  • javax.lang.model.type.TypeMirror e TypeVisitor
  • java.nio.file.FileVisitor e SimpleFileVisitor
  • javax.faces.component.visit.VisitContext e VisitCallback
  1. Modello di osservatore per tutto lo swing ( Observable , Observer )
  2. MVC anche in altalena
  3. Schema adattatore: InputStreamReader e OutputStreamWriter NOTA: ContainerAdapter , ComponentAdapter , FocusAdapter , FocusAdapter , KeyAdapter non sono adattatori; sono in realtà oggetti null. Scarsa scelta di denominazione da parte di Sun.
  4. Pattern Decorator ( BufferedInputStream può decorare altri flussi come FilterInputStream )
  5. AbstractFactory Pattern per AWT Toolkit e le classi di look-and-feel pluggable Swing
  6. java.lang.Runtime#getRuntime() è Singleton
  7. ButtonGroup per modello Mediator
  8. Action , AbstractAction può essere utilizzato per diverse rappresentazioni visive per eseguire lo stesso codice -> Command pattern
  9. Stringhe Internate o CellRender in JTable per Flyweight Pattern (Pensa anche a vari pool – Pool di thread, pool di connessioni, pool di oggetti EJB – Flyweight riguarda davvero la gestione delle risorse condivise)
  10. Il modello di eventi Java 1.0 è un esempio di Chain of Responsibility, come lo sono i filtri servlet.
  11. Pattern iteratore in Collections Framework
  12. I contenitori annidati in AWT / Swing usano il modello Composito
  13. I gestori di layout in AWT / Swing sono un esempio di strategia

e molti altri credo

  1. Flyweight viene utilizzato con alcuni valori di Byte, Short, Integer, Long e String.
  2. La facciata è usata in molti posti, ma la più ovvia è l’interfaccia Scripting.
  3. Singleton – java.lang.Runtime mi viene in mente.
  4. Fabbrica astratta – Scripting e API JDBC.
  5. Comando – Annulla / Ripristina di TextComponent.
  6. Interprete : API RegEx (java.util.regex. ) E SQL (java.sql. ).
  7. Prototipo – Non sicuro al 100% se questo conta, ma il metodo thinkg clone() può essere utilizzato a questo scopo.

RMI è basato su Proxy.

Dovrebbe essere ansible citare uno per la maggior parte dei 23 modelli in GoF:

  1. Fabbrica astratta: le interfacce java.sql ottengono tutte le loro implementazioni concrete da JDBC JAR quando il driver è registrato.
  2. Builder: java.lang.StringBuilder.
  3. Metodo di fabbrica: fabbriche XML, tra gli altri.
  4. Prototipo: Forse clone (), ma non sono sicuro di averlo comprato.
  5. Singleton: java.lang.System
  6. Adattatore: classi dell’adattatore in java.awt.event, ad es. WindowAdapter.
  7. Bridge: classi di raccolta in java.util. Elenco implementato da ArrayList.
  8. Composito: java.awt. java.awt.Component + java.awt.Container
  9. Decoratore: tutto il pacchetto java.io.
  10. Facciata: ExternalContext si comporta come una facciata per l’esecuzione di cookie, l’ambito della sessione e operazioni simili.
  11. Peso vivo: numero intero, carattere ecc.
  12. Proxy: pacchetto java.rmi
  13. Catena di responsabilità: filtri servlet
  14. Comando: elementi del menu Swing
  15. Interprete: No direttamente in JDK, ma JavaCC sicuramente lo usa.
  16. Iterator: interfaccia java.util.Iterator; non può essere più chiaro di quello
  17. Mediatore: JMS?
  18. Memento:
  19. Observer: java.util.Observer/Observable (mal fatto, però)
  20. Stato:
  21. Strategia:
  22. Modello:
  23. Visitatore:

Non riesco a pensare ad esempi in Java per 10 su 23, ma vedrò se riuscirò a fare meglio domani. Ecco a cosa serve la modifica.

Il pattern Abstract Factory viene utilizzato in vari luoghi. Ad esempio, DatagramSocketImplFactory , PreferencesFactory . Ce ne sono molti altri — cerca Javadoc per le interfacce che hanno la parola “Factory” nel loro nome.

Ci sono anche alcuni esempi del pattern Factory.

Anche se sono un po ‘un orologio rotto con questo, l’API XML Java usa molto Factory. Voglio dire, guarda questo:

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

…E così via e così via.

Inoltre vari Buffer (StringBuffer, ByteBuffer, StringBuilder) usano Builder.

  • Metodo di fabbrica

java.util.Collection # Iterator è un buon esempio di metodo factory. A seconda della sottoclass concreta della raccolta che si utilizza, verrà creata un’implementazione di Iterator. Poiché sia ​​la superclass Factory (Collection) che Iterator create sono interfacce, a volte viene confusa con AbstractFactory. La maggior parte degli esempi di AbstractFactory nella risposta accettata (BalusC) sono esempi di Factory , una versione semplificata di Factory Method, che non fa parte dei pattern GoF originali. In Facory la gerarchia delle classi Factory viene compressa e la fabbrica utilizza altri mezzi per scegliere il prodotto da restituire.

  • Fabbrica astratta

Una fabbrica astratta ha più metodi di fabbrica, ognuno dei quali crea un prodotto diverso. I prodotti prodotti da una fabbrica sono destinati ad essere utilizzati insieme (la tua stampante e le tue cartucce dovrebbero essere dello stesso stabilimento (astratto)). Come menzionato nelle risposte sopra, le famiglie di componenti GUI AWT, diverse da piattaforma a piattaforma, ne sono un esempio (sebbene la sua implementazione differisca dalla struttura descritta in Gof).