Java 核心库中的 GoF 设计模式示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1673841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Examples of GoF Design Patterns in Java's core libraries
提问by unj2
I am learning GoF Java Design Patterns and I want to see some real life examples of them. What are some good examples of these Design Patterns in Java's core libraries?
我正在学习 GoF Java 设计模式,我想看看它们的一些真实例子。Java 核心库中这些设计模式的一些很好的例子是什么?
采纳答案by BalusC
You can find an overview of a lot of design patterns in Wikipedia. It also mentions which patterns are mentioned by GoF. I'll sum them up here and try to assign as many pattern implementations as possible, found in both the Java SE and Java EE APIs.
您可以在Wikipedia 中找到许多设计模式的概述。它还提到了 GoF 提到了哪些模式。我将在这里总结它们并尝试分配尽可能多的模式实现,这些实现在 Java SE 和 Java EE API 中都可以找到。
Creational patterns
创作模式
Abstract factory(recognizeable by creational methods returning the factory itself which in turn can be used to create another abstract/interface type)
抽象工厂(可通过返回工厂本身的创建方法识别,工厂本身又可用于创建另一个抽象/接口类型)
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance()
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance()
Builder(recognizeable by creational methods returning the instance itself)
Builder (可通过返回实例本身的创建方法识别)
java.lang.StringBuilder#append()
(unsynchronized)java.lang.StringBuffer#append()
(synchronized)java.nio.ByteBuffer#put()
(also onCharBuffer
,ShortBuffer
,IntBuffer
,LongBuffer
,FloatBuffer
andDoubleBuffer
)javax.swing.GroupLayout.Group#addComponent()
- All implementations of
java.lang.Appendable
java.util.stream.Stream.Builder
java.lang.StringBuilder#append()
(不同步)java.lang.StringBuffer#append()
(同步)java.nio.ByteBuffer#put()
(也在CharBuffer
,ShortBuffer
,IntBuffer
,LongBuffer
,FloatBuffer
和 上DoubleBuffer
)javax.swing.GroupLayout.Group#addComponent()
- 的所有实现
java.lang.Appendable
java.util.stream.Stream.Builder
Factory method(recognizeable by creational methods returning an implementation of an abstract/interface type)
工厂方法(可通过返回抽象/接口类型实现的创建方法识别)
java.util.Calendar#getInstance()
java.util.ResourceBundle#getBundle()
java.text.NumberFormat#getInstance()
java.nio.charset.Charset#forName()
java.net.URLStreamHandlerFactory#createURLStreamHandler(String)
(Returns singleton object per protocol)java.util.EnumSet#of()
javax.xml.bind.JAXBContext#createMarshaller()
and other similar methods
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()
和其他类似的方法
Prototype(recognizeable by creational methods returning a differentinstance of itself with the same properties)
原型(可通过创建方法识别,返回具有相同属性的不同实例)
java.lang.Object#clone()
(the class has to implementjava.lang.Cloneable
)
Singleton(recognizeable by creational methods returning the sameinstance (usually of itself) everytime)
单例(可通过每次返回相同实例(通常是其自身)的创建方法识别)
Structural patterns
结构模式
Adapter(recognizeable by creational methods taking an instance of differentabstract/interface type and returning an implementation of own/another abstract/interface type which decorates/overridesthe given instance)
适配器(可通过采用不同抽象/接口类型的实例并返回装饰/覆盖给定实例的自己/另一个抽象/接口类型的实现的创建方法识别)
java.util.Arrays#asList()
java.util.Collections#list()
java.util.Collections#enumeration()
java.io.InputStreamReader(InputStream)
(returns aReader
)java.io.OutputStreamWriter(OutputStream)
(returns aWriter
)javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
and#unmarshal()
java.util.Arrays#asList()
java.util.Collections#list()
java.util.Collections#enumeration()
java.io.InputStreamReader(InputStream)
(返回一个Reader
)java.io.OutputStreamWriter(OutputStream)
(返回一个Writer
)javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
和#unmarshal()
Bridge(recognizeable by creational methods taking an instance of differentabstract/interface type and returning an implementation of own abstract/interface type which delegates/usesthe given instance)
Bridge (可通过创建方法识别,采用不同抽象/接口类型的实例并返回委托/使用给定实例的自己的抽象/接口类型的实现)
- None comes to mind yet. A fictive example would be
new LinkedHashMap(LinkedHashSet<K>, List<V>)
which returns an unmodifiable linked map which doesn't clone the items, but usesthem. Thejava.util.Collections#newSetFromMap()
andsingletonXXX()
methods however comes close.
- 还没有想到。一个虚构的例子是
new LinkedHashMap(LinkedHashSet<K>, List<V>)
返回一个不可修改的链接映射,它不克隆项目,但使用它们。然而,java.util.Collections#newSetFromMap()
和singletonXXX()
方法很接近。
Composite(recognizeable by behavioral methods taking an instance of sameabstract/interface type into a tree structure)
复合(可通过行为方法识别,将相同抽象/接口类型的实例放入树结构中)
java.awt.Container#add(Component)
(practically all over Swing thus)javax.faces.component.UIComponent#getChildren()
(practically all over JSF UI thus)
java.awt.Container#add(Component)
(因此实际上在 Swing 上)javax.faces.component.UIComponent#getChildren()
(因此几乎遍布 JSF UI)
Decorator(recognizeable by creational methods taking an instance of sameabstract/interface type which adds additional behaviour)
装饰器(可以通过采用相同抽象/接口类型的实例的创建方法识别,这增加了额外的行为)
- All subclasses of
java.io.InputStream
,OutputStream
,Reader
andWriter
have a constructor taking an instance of same type. java.util.Collections
, thecheckedXXX()
,synchronizedXXX()
andunmodifiableXXX()
methods.javax.servlet.http.HttpServletRequestWrapper
andHttpServletResponseWrapper
javax.swing.JScrollPane
- 所有子类
java.io.InputStream
,OutputStream
,Reader
并Writer
有一个构造函数取相同类型的实例。 java.util.Collections
的checkedXXX()
,synchronizedXXX()
和unmodifiableXXX()
方法。javax.servlet.http.HttpServletRequestWrapper
和HttpServletResponseWrapper
javax.swing.JScrollPane
Facade(recognizeable by behavioral methods which internally uses instances of differentindependent abstract/interface types)
Facade (可通过行为方法识别,其内部使用不同独立抽象/接口类型的实例)
javax.faces.context.FacesContext
, it internally uses among others the abstract/interface typesLifeCycle
,ViewHandler
,NavigationHandler
and many more without that the enduser has to worry about it (which are however overrideable by injection).javax.faces.context.ExternalContext
, which internally usesServletContext
,HttpSession
,HttpServletRequest
,HttpServletResponse
, etc.
javax.faces.context.FacesContext
,它在内部等使用抽象/接口类型LifeCycle
,ViewHandler
,NavigationHandler
等等而没有终端用户具有至约它的担心(其然而覆写投放通过注射)。javax.faces.context.ExternalContext
,其在内部使用ServletContext
,HttpSession
,HttpServletRequest
,HttpServletResponse
,等。
Flyweight(recognizeable by creational methods returning a cached instance, a bit the "multiton" idea)
Flyweight (可以通过返回缓存实例的创建方法识别,有点“multiton”的想法)
java.lang.Integer#valueOf(int)
(also onBoolean
,Byte
,Character
,Short
,Long
andBigDecimal
)
Proxy(recognizeable by creational methods which returns an implementation of given abstract/interface type which in turn delegates/usesa differentimplementation of given abstract/interface type)
代理(可通过创建方法识别,该方法返回给定抽象/接口类型的实现,而该实现又委托/使用给定抽象/接口类型的不同实现)
java.lang.reflect.Proxy
java.rmi.*
javax.ejb.EJB
(explanation here)javax.inject.Inject
(explanation here)javax.persistence.PersistenceContext
java.lang.reflect.Proxy
java.rmi.*
javax.ejb.EJB
(这里解释)javax.inject.Inject
(这里解释)javax.persistence.PersistenceContext
Behavioral patterns
行为模式
Chain of responsibility(recognizeable by behavioral methods which (indirectly) invokes the same method in anotherimplementation of sameabstract/interface type in a queue)
责任链(可通过行为方法识别,这些方法(间接)在队列中相同抽象/接口类型的另一个实现中调用相同的方法)
Command(recognizeable by behavioral methods in an abstract/interface type which invokes a method in an implementation of a differentabstract/interface type which has been encapsulatedby the command implementation during its creation)
命令(可由抽象/接口类型中的行为方法识别,该类型调用不同抽象/接口类型的实现中的方法,该抽象/接口类型在其创建期间已被命令实现封装)
- All implementations of
java.lang.Runnable
- All implementations of
javax.swing.Action
- 的所有实现
java.lang.Runnable
- 的所有实现
javax.swing.Action
Interpreter(recognizeable by behavioral methods returning a structurallydifferent instance/type of the given instance/type; note that parsing/formatting is not part of the pattern, determining the pattern and how to apply it is)
解释器(可通过行为方法识别,返回给定实例/类型在结构上不同的实例/类型;注意解析/格式化不是模式的一部分,确定模式以及如何应用它是)
java.util.Pattern
java.text.Normalizer
- All subclasses of
java.text.Format
- All subclasses of
javax.el.ELResolver
Iterator(recognizeable by behavioral methods sequentially returning instances of a differenttype from a queue)
迭代器(可通过行为方法识别,从队列中依次返回不同类型的实例)
- All implementations of
java.util.Iterator
(thus among others alsojava.util.Scanner
!). - All implementations of
java.util.Enumeration
- 的所有实现
java.util.Iterator
(因此也是java.util.Scanner
!)。 - 的所有实现
java.util.Enumeration
Mediator(recognizeable by behavioral methods taking an instance of different abstract/interface type (usually using the command pattern) which delegates/uses the given instance)
中介器(可通过行为方法识别,采用委托/使用给定实例的不同抽象/接口类型(通常使用命令模式)的实例)
java.util.Timer
(allscheduleXXX()
methods)java.util.concurrent.Executor#execute()
java.util.concurrent.ExecutorService
(theinvokeXXX()
andsubmit()
methods)java.util.concurrent.ScheduledExecutorService
(allscheduleXXX()
methods)java.lang.reflect.Method#invoke()
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()
Memento(recognizeable by behavioral methods which internally changes the state of the wholeinstance)
纪念品(可通过行为方法识别,在内部改变整个实例的状态)
java.util.Date
(the setter methods do that,Date
is internally represented by along
value)- All implementations of
java.io.Serializable
- All implementations of
javax.faces.component.StateHolder
java.util.Date
(setter 方法这样做,Date
在内部由一个long
值表示)- 的所有实现
java.io.Serializable
- 的所有实现
javax.faces.component.StateHolder
Observer (or Publish/Subscribe)(recognizeable by behavioral methods which invokes a method on an instance of anotherabstract/interface type, depending on own state)
观察者(或发布/订阅)(可通过行为方法识别,该方法在另一个抽象/接口类型的实例上调用方法,具体取决于自己的状态)
java.util.Observer
/java.util.Observable
(rarely used in real world though)- All implementations of
java.util.EventListener
(practically all over Swing thus) javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
java.util.Observer
/java.util.Observable
(虽然在现实世界中很少使用)- 的所有实现
java.util.EventListener
(因此实际上遍及 Swing) javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
State(recognizeable by behavioral methods which changes its behaviour depending on the instance's state which can be controlled externally)
状态(可通过行为方法识别,该方法根据可以从外部控制的实例状态改变其行为)
javax.faces.lifecycle.LifeCycle#execute()
(controlled byFacesServlet
, the behaviour is dependent on current phase (state) of JSF lifecycle)
javax.faces.lifecycle.LifeCycle#execute()
(由 控制FacesServlet
,行为取决于 JSF 生命周期的当前阶段(状态))
Strategy(recognizeable by behavioral methods in an abstract/interface type which invokes a method in an implementation of a differentabstract/interface type which has been passed-inas method argument into the strategy implementation)
策略(通过在抽象/接口类型行为方法recognizeable它调用一个方法中的实施方案不同,其已被抽象/接口类型传入的作为方法参数到策略执行)
java.util.Comparator#compare()
, executed by among othersCollections#sort()
.javax.servlet.http.HttpServlet
, theservice()
and alldoXXX()
methods takeHttpServletRequest
andHttpServletResponse
and the implementor has to process them (and not to get hold of them as instance variables!).javax.servlet.Filter#doFilter()
java.util.Comparator#compare()
,由其他人执行Collections#sort()
。javax.servlet.http.HttpServlet
, theservice()
和 alldoXXX()
方法采用HttpServletRequest
andHttpServletResponse
并且实现者必须处理它们(而不是将它们作为实例变量!)。javax.servlet.Filter#doFilter()
Template method(recognizeable by behavioral methods which already have a "default" behaviour defined by an abstract type)
模板方法(可通过已经具有由抽象类型定义的“默认”行为的行为方法识别)
- All non-abstract methods of
java.io.InputStream
,java.io.OutputStream
,java.io.Reader
andjava.io.Writer
. - All non-abstract methods of
java.util.AbstractList
,java.util.AbstractSet
andjava.util.AbstractMap
. javax.servlet.http.HttpServlet
, all thedoXXX()
methods by default sends a HTTP 405 "Method Not Allowed" error to the response. You're free to implement none or any of them.
- 所有非抽象方法
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" 错误。您可以自由实现一个或任何一个。
Visitor(recognizeable by two differentabstract/interface types which has methods defined which takes each the otherabstract/interface type; the one actually calls the method of the other and the other executes the desired strategy on it)
访问者(可通过两种不同的抽象/接口类型识别,这些类型定义了相互采用其他抽象/接口类型的方法;一个实际调用另一个的方法,另一个在其上执行所需的策略)
回答by jitter
- Observer pattern throughout whole swing (
Observable
,Observer
) - MVC also in swing
- Adapter pattern: InputStreamReader and OutputStreamWriter
NOTE:
ContainerAdapter
,ComponentAdapter
,FocusAdapter
,KeyAdapter
,MouseAdapter
are notadapters; they are actually Null Objects. Poor naming choice by Sun. - Decorator pattern (
BufferedInputStream
can decorate other streams such asFilterInputStream
) - AbstractFactory Pattern for the AWT Toolkit and the Swing pluggable look-and-feel classes
java.lang.Runtime#getRuntime()
is SingletonButtonGroup
for Mediator patternAction
,AbstractAction
may be used for different visual representations to execute same code -> Command pattern- Interned Strings or CellRender in JTable for Flyweight Pattern (Also think about various pools - Thread pools, connection pools, EJB object pools - Flyweight is really about management of shared resources)
- The Java 1.0 event model is an example of Chain of Responsibility, as are Servlet Filters.
- Iterator pattern in Collections Framework
- Nested containers in AWT/Swing use the Composite pattern
- Layout Managers in AWT/Swing are an example of Strategy
- 整个挥杆过程中的观察者模式 (
Observable
,Observer
) - MVC 也在摇摆不定
- 适配器模式:InputStreamReader和OutputStreamWriter注:
ContainerAdapter
,ComponentAdapter
,FocusAdapter
,KeyAdapter
,MouseAdapter
是不适配器; 它们实际上是空对象。Sun 的命名选择不当。 - 装饰器模式(
BufferedInputStream
可以装饰其他流如FilterInputStream
) - AWT Toolkit 和 Swing 可插入外观类的 AbstractFactory 模式
java.lang.Runtime#getRuntime()
是单例ButtonGroup
对于中介模式Action
,AbstractAction
可用于不同的视觉表示以执行相同的代码 -> 命令模式- 享元模式的 JTable 中的 Interned Strings 或 CellRender(还要考虑各种池 - 线程池、连接池、EJB 对象池 - Flyweight 实际上是关于共享资源的管理)
- Java 1.0 事件模型是责任链的一个示例,Servlet 过滤器也是如此。
- 集合框架中的迭代器模式
- AWT/Swing 中的嵌套容器使用复合模式
- AWT/Swing 中的布局管理器是策略的一个例子
and many more I guess
还有更多我猜
回答by uckelman
The Abstract Factory pattern is used in various places.
E.g., DatagramSocketImplFactory
, PreferencesFactory
. There are many more---search the Javadoc for interfaces which have the word "Factory" in their name.
抽象工厂模式用在很多地方。例如DatagramSocketImplFactory
,,PreferencesFactory
。还有更多 --- 在 Javadoc 中搜索名称中带有“Factory”一词的接口。
Also there are quite a few instances of the Factory pattern, too.
还有很多工厂模式的实例。
回答by Esko
Even though I'm sort of a broken clock with this one, Java XML API uses Factory a lot. I mean just look at this:
尽管我对这个时钟有点崩溃,但 Java XML API 经常使用 Factory。我的意思是看看这个:
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);
...and so on and so forth.
...等等等等。
Additionally various Buffers (StringBuffer, ByteBuffer, StringBuilder) use Builder.
此外,各种缓冲区(StringBuffer、ByteBuffer、StringBuilder)都使用 Builder。
回答by NawaMan
- Flyweightis used with some values of Byte, Short, Integer, Long and String.
- Facadeis used in many place but the most obvious is Scripting interfaces.
- Singleton- java.lang.Runtime comes to mind.
- Abstract Factory- Also Scripting and JDBC API.
- Command- TextComponent's Undo/Redo.
- Interpreter- RegEx (java.util.regex.) and SQL (java.sql.) API.
- Prototype- Not 100% sure if this count, but I thinkg
clone()
method can be used for this purpose.
- Flyweight与 Byte、Short、Integer、Long 和 String 的一些值一起使用。
- Facade用在很多地方,但最明显的是脚本接口。
- 单例- java.lang.Runtime 浮现在脑海中。
- 抽象工厂- 还有脚本和 JDBC API。
- 命令- TextComponent 的撤消/重做。
- 解释器- RegEx (java.util.regex. ) 和 SQL (java.sql.) API。
- 原型- 不是 100% 确定这是否计数,但我认为
clone()
可以将方法用于此目的。
回答by duffymo
RMI is based on Proxy.
RMI 基于代理。
Should be possible to cite one for most of the 23 patterns in GoF:
应该可以为 GoF 中的 23 个模式中的大多数引用一个:
- Abstract Factory: java.sql interfaces all get their concrete implementations from JDBC JAR when driver is registered.
- Builder: java.lang.StringBuilder.
- Factory Method: XML factories, among others.
- Prototype: Maybe clone(), but I'm not sure I'm buying that.
- Singleton: java.lang.System
- Adapter: Adapter classes in java.awt.event, e.g., WindowAdapter.
- Bridge: Collection classes in java.util. List implemented by ArrayList.
- Composite: java.awt. java.awt.Component + java.awt.Container
- Decorator: All over the java.io package.
- Facade: ExternalContextbehaves as a facade for performing cookie, session scope and similar operations.
- Flyweight: Integer, Character, etc.
- Proxy: java.rmi package
- Chain of Responsibility: Servlet filters
- Command: Swing menu items
- Interpreter: No directly in JDK, but JavaCC certainly uses this.
- Iterator: java.util.Iterator interface; can't be clearer than that.
- Mediator: JMS?
- Memento:
- Observer: java.util.Observer/Observable (badly done, though)
- State:
- Strategy:
- Template:
- Visitor:
- 抽象工厂:java.sql 接口都在注册驱动程序时从 JDBC JAR 中获取其具体实现。
- 生成器:java.lang.StringBuilder。
- 工厂方法:XML 工厂等。
- 原型:也许是 clone(),但我不确定我是否会购买它。
- 单例:java.lang.System
- Adapter:java.awt.event 中的适配器类,例如WindowAdapter。
- Bridge:java.util 中的集合类。由 ArrayList 实现的列表。
- 复合:java.awt。java.awt.Component + java.awt.Container
- 装饰器:遍布 java.io 包。
- Facade:ExternalContext充当执行 cookie、会话范围和类似操作的 Facade。
- Flyweight:整数、字符等。
- 代理:java.rmi 包
- 责任链:Servlet 过滤器
- 命令:Swing 菜单项
- 解释器:没有直接在JDK中,但JavaCC肯定会使用这个。
- 迭代器:java.util.Iterator 接口;再清楚不过了。
- 调解员:JMS?
- 纪念:
- 观察者:java.util.Observer/Observable(虽然做得不好)
- 状态:
- 战略:
- 模板:
- 游客:
I can't think of examples in Java for 10 out of the 23, but I'll see if I can do better tomorrow. That's what edit is for.
23 个中的 10 个我想不出 Java 中的示例,但我会看看明天是否可以做得更好。这就是编辑的目的。
回答by Catweazle
java.util.Collection#Iterator is a good example of a Factory Method. Depending on the concrete subclass of Collection you use, it will create an Iterator implementation. Because both the Factory superclass (Collection) and the Iterator created are interfaces, it is sometimes confused with AbstractFactory. Most of the examples for AbstractFactory in the the accepted answer (BalusC) are examples of Factory, a simplified version of Factory Method, which is not part of the original GoF patterns. In Facory the Factory class hierarchy is collapsed and the factory uses other means to choose the product to be returned.
java.util.Collection#Iterator 是工厂方法的一个很好的例子。根据您使用的 Collection 的具体子类,它将创建一个 Iterator 实现。因为 Factory 超类(Collection)和创建的 Iterator 都是接口,所以有时会与 AbstractFactory 混淆。接受的答案 (BalusC) 中的大多数 AbstractFactory 示例都是Factory 的示例,它是 Factory Method 的简化版本,它不是原始 GoF 模式的一部分。在工厂中,工厂类层次结构被折叠起来,工厂使用其他方式来选择要退回的产品。
- Abstract Factory
- 抽象工厂
An abstract factory has multiple factory methods, each creating a different product. The products produced by one factory are intended to be used together (your printer and cartridges better be from the same (abstract) factory). As mentioned in answers above the families of AWT GUI components, differing from platform to platform, are an example of this (although its implementation differs from the structure described in Gof).
一个抽象工厂有多个工厂方法,每个方法创建一个不同的产品。一个工厂生产的产品旨在一起使用(您的打印机和墨盒最好来自同一(抽象)工厂)。正如上面的答案中提到的,AWT GUI 组件系列(因平台而异)就是一个例子(尽管它的实现与 Gof 中描述的结构不同)。