我正在学习GoF Java设计模式,我想看看它们的一些真实例子.Java核心库中这些设计模式的一些很好的例子是什么?
您可以在维基百科中找到许多设计模式的概述.它还提到了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
,ShortBuffer
,IntBuffer
,LongBuffer
,FloatBuffer
和DoubleBuffer
)
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.lang.Runtime#getRuntime()
java.awt.Desktop#getDesktop()
java.lang.System#getSecurityManager()
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()
没有想到的.一个虚构的例子是new LinkedHashMap(LinkedHashSet
返回一个不可修改的链接映射,它不会克隆项目,而是使用它们.然而java.util.Collections#newSetFromMap()
,singletonXXX()
方法和方法很接近.
java.awt.Container#add(Component)
(几乎所有的Swing因此)
javax.faces.component.UIComponent#getChildren()
(几乎遍布JSF UI)
All subclasses of java.io.InputStream
, OutputStream
, Reader
and Writer
have a constructor taking an instance of same type.
java.util.Collections
, the checkedXXX()
, synchronizedXXX()
and unmodifiableXXX()
methods.
javax.servlet.http.HttpServletRequestWrapper
and HttpServletResponseWrapper
javax.swing.JScrollPane
javax.faces.context.FacesContext
, it internally uses among others the abstract/interface types LifeCycle
, 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 uses ServletContext
, HttpSession
, HttpServletRequest
, HttpServletResponse
, etc.
java.lang.Integer#valueOf(int)
(also on Boolean
, Byte
, Character
, Short
, Long
and BigDecimal
)
java.lang.reflect.Proxy
java.rmi.*
javax.ejb.EJB
(explanation here)
javax.inject.Inject
(explanation here)
javax.persistence.PersistenceContext
java.util.logging.Logger#log()
javax.servlet.Filter#doFilter()
All implementations of java.lang.Runnable
All implementations of javax.swing.Action
java.util.Pattern
java.text.Normalizer
All subclasses of java.text.Format
All subclasses of javax.el.ELResolver
All implementations of java.util.Iterator
(thus among others also java.util.Scanner
!).
All implementations of java.util.Enumeration
java.util.Timer
(all scheduleXXX()
methods)
java.util.concurrent.Executor#execute()
java.util.concurrent.ExecutorService
(the invokeXXX()
and submit()
methods)
java.util.concurrent.ScheduledExecutorService
(all scheduleXXX()
methods)
java.lang.reflect.Method#invoke()
java.util.Date
(the setter methods do that, Date
is internally represented by a long
value)
All implementations of java.io.Serializable
All implementations of javax.faces.component.StateHolder
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
整个摆动的观察者模式(Observable
,Observer
)
MVC也在摇摆
适配器模式:InputStreamReader和OutputStreamWriter注:ContainerAdapter
,ComponentAdapter
,FocusAdapter
,KeyAdapter
,MouseAdapter
是不适配器; 它们实际上是Null Objects.Sun的命名选择不佳.
装饰模式(BufferedInputStream
可以装饰其他流等FilterInputStream
)
AWT Toolkit和Swing可插入外观类的AbstractFactory Pattern
java.lang.Runtime#getRuntime()
是辛格尔顿
ButtonGroup
对于Mediator模式
Action
,AbstractAction
可用于不同的可视化表示来执行相同的代码 - >命令模式
用于Flyweight模式的JTable中的Interned Strings或CellRender(还要考虑各种池 - 线程池,连接池,EJB对象池 - Flyweight实际上是关于共享资源的管理)
Java 1.0事件模型是责任链的一个示例,Servlet过滤器也是如此.
集合框架中的迭代器模式
AWT/Swing中的嵌套容器使用Composite模式
AWT/Swing中的布局管理器就是战略的一个例子
还有更多我猜
Flyweight与Byte,Short,Integer,Long和String的某些值一起使用.
Facade在很多地方使用,但最明显的是Scripting接口.
Singleton - java.lang.Runtime浮现在脑海中.
抽象工厂 - 还有脚本和JDBC API.
命令 - TextComponent的撤消/重做.
解释器 - RegEx(java.util.regex.)和SQL(java.sql.)API.
原型 - 不是100%肯定如果这个计数,但我认为clone()
方法可以用于此目的.
RMI基于代理.
对于GoF中的23种模式中的大多数,应该可以引用一种:
抽象工厂:java.sql接口在注册驱动程序时从JDBC JAR获取具体实现.
Builder:java.lang.StringBuilder.
工厂方法:XML工厂等.
原型:也许克隆(),但我不确定我是买它.
Singleton:java.lang.System
适配器:java.awt.event中的适配器类,例如WindowAdapter.
Bridge:java.util中的集合类.由ArrayList实现的列表.
复合:java.awt.java.awt.Component + java.awt.Container
装饰者:遍布java.io包.
Facade:ExternalContext表现为执行cookie,会话范围和类似操作的外观.
Flyweight:整数,字符等
代理:java.rmi包
责任链:Servlet过滤器
命令:Swing菜单项
解释器:不直接在JDK中,但JavaCC肯定使用它.
Iterator:java.util.Iterator接口; 不能比那更清楚.
调解员:JMS?
纪念品:
观察者:java.util.Observer/Observable(虽然做得不好)
州:
战略:
模板:
游客:
我不能想到23个中有10个用Java的例子,但我会明白我明天能不能做得更好.这就是编辑的目的.
抽象工厂模式用于各种地方.例如DatagramSocketImplFactory
,PreferencesFactory
.还有更多---在Javadoc中搜索名称中带有"Factory"字样的接口.
此外,还有很多工厂模式的实例.
即使我有一个破坏时钟,Java XML API使用Factory很多.我的意思是看看这个:
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);
...等等等等.
另外,各种Buffers(StringBuffer,ByteBuffer,StringBuilder)使用Builder.
工厂方法
java.util.Collection #teterator是Factory方法的一个很好的例子.根据您使用的Collection的具体子类,它将创建一个Iterator实现.因为Factory超类(Collection)和Iterator都是接口,所以它有时会与AbstractFactory混淆.在接受的答案(BalusC)中,AbstractFactory的大多数示例都是Factory的示例,它是Factory Method的简化版本,它不是原始GoF模式的一部分.在Facory中,工厂类层次结构已折叠,工厂使用其他方法选择要返回的产品.
抽象工厂
抽象工厂有多种工厂方法,每种方法都可以创建不同的产品.一家工厂生产的产品可以一起使用(您的打印机和墨盒最好来自同一个(抽象)工厂).正如上面的答案中所提到的,不同平台的AWT GUI组件系列就是一个例子(虽然它的实现与Gof中描述的结构不同).