私はGoF Java Design Patternsを学んでいます、そしてそれらのいくつかの実際の例を見たいです。 Javaのコアライブラリにあるこれらのデザインパターンの良い例は何ですか?
多くのデザインパターンの概要は、 Wikipedia にあります。また、GoFが言及しているパターンについても言及しています。ここでそれらを要約し、Java SEとJava EE APIの両方にあるパターン実装をできるだけ多く割り当てようとします。
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance()
Java.lang.StringBuilder#append()
(非同期)Java.lang.StringBuffer#append()
(同期)Java.nio.ByteBuffer#put()
( CharBuffer
NAME _ 、 ShortBuffer
NAME _ 、 IntBuffer
NAME _ 、 LongBuffer
NAME _ 、 FloatBuffer
NAME _ および DoubleBuffer
NAME _ )javax.swing.GroupLayout.Group#addComponent()
Java.lang.Appendable
のすべての実装Java.util.stream.Stream.Builder
Java.util.Calendar#getInstance()
Java.util.ResourceBundle#getBundle()
Java.text.NumberFormat#getInstance()
Java.nio.charset.Charset#forName()
Java.net.URLStreamHandlerFactory#createURLStreamHandler(String)
(プロトコルごとにシングルトンオブジェクトを返します)Java.util.EnumSet#of()
javax.xml.bind.JAXBContext#createMarshaller()
および他の同様のメソッドJava.lang.Object#clone()
(クラスは実装する必要があります Java.lang.Cloneable
)Java.util.Arrays#asList()
Java.util.Collections#list()
Java.util.Collections#enumeration()
Java.io.InputStreamReader(InputStream)
(Reader
name__を返します)Java.io.OutputStreamWriter(OutputStream)
(Writer
name__を返します)javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
および #unmarshal()
new LinkedHashMap(LinkedHashSet<K>, List<V>)
で、これはアイテムを複製しないが変更不可能なリンクされたマップを返しますが、はを使用します。ただし、 Java.util.Collections#newSetFromMap()
および singletonXXX()
メソッドは近くなります。Java.awt.Container#add(Component)
(実際にはSwing全体にわたって)javax.faces.component.UIComponent#getChildren()
(事実上、JSF UI全体にわたって)Java.io.InputStream
、 OutputStream
NAME _ 、 Reader
NAME _ および Writer
NAME _ のすべてのサブクラス同じ型のインスタンスを取るコンストラクターがあります。Java.util.Collections
、 checkedXXX()
、 synchronizedXXX()
、および unmodifiableXXX()
メソッド。javax.servlet.http.HttpServletRequestWrapper
および HttpServletResponseWrapper
NAME _javax.swing.JScrollPane
javax.faces.context.FacesContext
、特に抽象/インターフェイスタイプを内部的に使用します LifeCycle
NAME _ 、 ViewHandler
NAME _ 、 NavigationHandler
NAME _ など、エンドユーザーが心配する必要はありません(ただし、インジェクションによってオーバーライドできます)。javax.faces.context.ExternalContext
、これは内部的に ServletContext
NAME _ 、 HttpSession
NAME _ 、 HttpServletRequest
NAME _ を使用します、 HttpServletResponse
NAME _ など.Java.lang.Integer#valueOf(int)
( Boolean
NAME _ 、 Byte
NAME _ 、 Character
NAME _ 、 Short
NAME _ 、 Long
NAME _ および BigDecimal
NAME _ )Java.lang.reflect.Proxy
Java.rmi.*
javax.ejb.EJB
( 説明はこちら )javax.inject.Inject
( 説明はこちら )javax.persistence.PersistenceContext
Java.lang.Runnable
のすべての実装javax.swing.Action
のすべての実装Java.util.Pattern
Java.text.Normalizer
Java.text.Format
のすべてのサブクラスjavax.el.ELResolver
のすべてのサブクラスJava.util.Iterator
のすべての実装(特に Java.util.Scanner
!)。Java.util.Enumeration
のすべての実装Java.util.Timer
(すべてのscheduleXXX()
メソッド)Java.util.concurrent.Executor#execute()
Java.util.concurrent.ExecutorService
(invokeXXX()
およびsubmit()
メソッド)Java.util.concurrent.ScheduledExecutorService
(すべてのscheduleXXX()
メソッド)Java.lang.reflect.Method#invoke()
Java.util.Date
(セッターメソッドはそれを行います。Date
name__は内部的にlong
name__値で表されます)Java.io.Serializable
のすべての実装javax.faces.component.StateHolder
のすべての実装Java.util.Observer
/ Java.util.Observable
(ただし実際にはほとんど使用されません)Java.util.EventListener
のすべての実装(実際にはSwing全体にわたって)javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
javax.faces.lifecycle.LifeCycle#execute()
( FacesServlet
NAME _ で制御され、動作はJSFライフサイクルの現在のフェーズ(状態)に依存します)Java.util.Comparator#compare()
、とりわけCollections#sort()
によって実行されます。javax.servlet.http.HttpServlet
、service()
およびすべてのdoXXX()
メソッドはHttpServletRequest
name__およびHttpServletResponse
name__を取り、実装者はそれらを処理する必要があります(それらをインスタンス変数として保持しないでください!)。javax.servlet.Filter#doFilter()
Java.io.InputStream
、 Java.io.OutputStream
、 Java.io.Reader
および Java.io.Writer
。Java.util.AbstractList
、 Java.util.AbstractSet
、および Java.util.AbstractMap
のすべての非抽象メソッド。javax.servlet.http.HttpServlet
、すべてのdoXXX()
メソッドは、デフォルトでHTTP 405「Method Not Allowed」エラーを応答に送信します。あなたはそれらをどれも実装しなくても、どれでも自由に実装できます。javax.lang.model.element.AnnotationValue
および AnnotationValueVisitor
NAME _javax.lang.model.element.Element
および ElementVisitor
NAME _javax.lang.model.type.TypeMirror
および TypeVisitor
NAME _Java.nio.file.FileVisitor
および SimpleFileVisitor
NAME _javax.faces.component.visit.VisitContext
および VisitCallback
NAME _Observable
、Observer
)ContainerAdapter
、ComponentAdapter
、FocusAdapter
、KeyAdapter
、MouseAdapter
は not adaptersです。それらは実際にはNULLオブジェクトです。 Sunによる不適切な命名の選択.BufferedInputStream
はFilterInputStream
のような他のストリームを装飾することができます)Java.lang.Runtime#getRuntime()
はシングルトンですButtonGroup
Action
、AbstractAction
は、同じコードを実行するために異なる視覚的表現に使用できます - >コマンドパターンそしてもっとたくさん
clone()
メソッドがこの目的のために使用できると思う。RMIはプロキシに基づいています。
GoFの23のパターンのほとんどについて1つを挙げることが可能であるべきです:
私は23のうち10のJavaの例を考えることはできませんが、私は明日より良いことができるかどうか見ます。それがeditの目的です。
Abstract Factoryパターンはさまざまな場所で使用されています。例:DatagramSocketImplFactory
、PreferencesFactory
。もっとたくさんあります---名前に "Factory"という単語を含むインターフェースをJavadocで検索してください。
Factoryパターンの実例もかなりあります。
私はこれとはちょっと壊れた時計のようですが、Java XML APIはFactoryをよく使用します。これを見ているだけです。
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);
...などなど.
さらに、さまざまなバッファ(StringBuffer、ByteBuffer、StringBuilder)がBuilderを使用しています。
Java.util.Collection#イテレータはファクトリメソッドの良い例です。使用しているCollectionの具象サブクラスに応じて、Iterator実装が作成されます。 Factoryスーパークラス(Collection)と作成されたIteratorはどちらもインタフェースであるため、AbstractFactoryと混同されることがあります。受け入れられた答え(BalusC)のAbstractFactoryの例のほとんどは Factory の例です。これはFactory Methodの簡易版で、元のGoFパターンの一部ではありません。 Facoryでは、Factoryクラスの階層は折りたたまれており、ファクトリは他の方法で返品する商品を選択します。
抽象ファクトリには複数のファクトリメソッドがあり、それぞれが異なる製品を作成します。 1つの工場で生産された製品は、一緒に使用することを目的としています(プリンタとカートリッジは同じ(抽象的な)工場から入手することをお勧めします)。上記の回答で述べたように、プラットフォームごとに異なるAWT GUIコンポーネントのファミリーはその一例です(ただし、その実装はGofで説明されている構造とは異なります)。