我正在学习GoF Java设计模式,我想看看它们的一些真实例子 . Java核心库中这些设计模式的一些很好的例子是什么?
整个秋千的观察者模式( Observable , Observer )
Observable
Observer
MVC也在摇摆
适配器模式:InputStreamReader和OutputStreamWriter注意: ContainerAdapter , ComponentAdapter , FocusAdapter , KeyAdapter , MouseAdapter 不是适配器;它们实际上是Null Objects . Sun的命名选择不佳 .
ContainerAdapter
ComponentAdapter
FocusAdapter
KeyAdapter
MouseAdapter
装饰器模式( BufferedInputStream 可以装饰其他流,如 FilterInputStream )
BufferedInputStream
FilterInputStream
用于AWT工具包和Swing可插入外观类的AbstractFactory模式
java.lang.Runtime#getRuntime() 是Singleton_ *** 9_ ButtonGroup for Mediator模式
java.lang.Runtime#getRuntime()
ButtonGroup
Action , AbstractAction 可用于不同的可视化表示来执行相同的代码 - >命令模式
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 在很多地方使用,但最明显的是脚本接口 .
Singleton - java.lang.Runtime浮现在脑海中 .
Abstract Factory - 还有脚本和JDBC API .
Command - TextComponent的撤消/重做 .
Interpreter - RegEx(java.util.regex . )和SQL(java.sql . )API .
Prototype - 不是100%肯定如果这个计数,但我认为 clone() 方法可以用于此目的 .
clone()
即使我用这个时钟来破坏时钟,Java XML API也会使用Factory . 我的意思是看看这个:
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);
...等等等等 .
另外,各种Buffers(StringBuffer,ByteBuffer,StringBuilder)使用Builder .
抽象工厂模式用于各种地方 . 例如, DatagramSocketImplFactory , PreferencesFactory . 还有更多---在Javadoc中搜索名称中包含单词"Factory"的接口 .
DatagramSocketImplFactory
PreferencesFactory
此外,还有很多工厂模式的实例 .
java.util.Collection #teterator是Factory方法的一个很好的例子 . 根据您使用的Collection的具体子类,它将创建一个Iterator实现 . 因为Factory超类(Collection)和Iterator都是接口,所以它有时会与AbstractFactory混淆 . 在接受的答案(BalusC)中,AbstractFactory的大多数示例都是Factory的示例,它是Factory Method的简化版本,它不是原始GoF模式的一部分 . 在Facory中,工厂类层次结构已折叠,工厂使用其他方法选择要返回的产品 .
抽象工厂有多种工厂方法,每种方法都可以创建不同的产品 . 一家工厂 生产环境 的产品可以一起使用(您的打印机和墨盒最好来自同一个(抽象)工厂) . 正如上面的答案中所提到的,不同平台的AWT GUI组件系列就是一个例子(虽然它的实现与Gof中描述的结构不同) .
您可以在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,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.awt.Desktop#getDesktop()
java.lang.System#getSecurityManager()
java.util.Arrays#asList()
java.util.Collections#list()
java.util.Collections#enumeration()
java.io.InputStreamReader(InputStream)(返回 Reader )
Reader
java.io.OutputStreamWriter(OutputStream)(返回 Writer )
Writer
javax.xml.bind.annotation.adapters.XmlAdapter#marshal()和#unmarshal()
new LinkedHashMap(LinkedHashSet<K>, List<V>)
java.awt.Container#add(Component)(因此几乎遍及Swing)
javax.faces.component.UIComponent#getChildren()(几乎遍及JSF UI)
java.io.InputStream,OutputStream,Reader和Writer的所有子类都有一个构造函数,它采用相同类型的实例 .
java.util.Collections,checkedXXX(),synchronizedXXX()和unmodifiableXXX()方法 .
javax.servlet.http.HttpServletRequestWrapper和HttpServletResponseWrapper
javax.swing.JScrollPane
javax.faces.context.FacesContext,它在内部使用了抽象/接口类型LifeCycle,ViewHandler,NavigationHandler以及更多,而最终用户不必担心它(但是可以通过注入覆盖) .
javax.faces.context.ExternalContext,内部使用ServletContext,HttpSession,HttpServletRequest,HttpServletResponse等 .
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()
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() 方法)
scheduleXXX()
java.util.concurrent.Executor#execute()
java.util.concurrent.ExecutorService( invokeXXX() 和 submit() 方法)
invokeXXX()
submit()
java.util.concurrent.ScheduledExecutorService(所有 scheduleXXX() 方法)
java.lang.reflect.Method#invoke()
java.util.Date(setter方法执行此操作, Date 内部由 long 值表示)
Date
long
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
java.util.Comparator#compare(),由 Collections#sort() 执行 .
Collections#sort()
javax.servlet.http.HttpServlet, service() 和所有 doXXX() 方法都需要 HttpServletRequest 和 HttpServletResponse ,并且实现者必须处理它们(而不是将它们作为实例变量来保存!) .
service()
doXXX()
HttpServletRequest
HttpServletResponse
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
javax.lang.model.element.Element和ElementVisitor
javax.lang.model.type.TypeMirror和TypeVisitor
java.nio.file.FileVisitor和SimpleFileVisitor
javax.faces.component.visit.VisitContext和VisitCallback
RMI基于代理 .
对于GoF中的23种模式中的大多数,应该可以引用一种:
Abstract Factory:java.sql接口在注册驱动程序时从JDBC JAR获取具体实现 .
Builder:java.lang.StringBuilder .
工厂方法:XML工厂等 .
原型:也许克隆(),但我'm not sure I'米买了 .
Singleton:java.lang.System
适配器:java.awt.event中的适配器类,例如WindowAdapter .
Bridge:java.util中的集合类 . 由ArrayList实现的列表 .
Composite:java.awt . java.awt.Component java.awt.Container
装饰器:遍布java.io包 .
Facade:ExternalContext表现为执行cookie,会话范围和类似操作的外观 .
Flyweight:整数,字符等
代理:java.rmi包
责任链:Servlet过滤器
命令:Swing菜单项
解释器:没有直接在JDK中,但JavaCC当然使用它 .
迭代器:java.util.Iterator接口;不能比那更清楚 .
调解员:JMS?
纪念品:
Observer:java.util.Observer/Observable(虽然做得不好)
州:
策略:
模板:
访客:
我想不出23个中有10个用Java的例子,但我明白我明天能不能做得更好 . 这就是编辑的目的 .
7 回答
整个秋千的观察者模式(
Observable
,Observer
)MVC也在摇摆
适配器模式:InputStreamReader和OutputStreamWriter注意:
ContainerAdapter
,ComponentAdapter
,FocusAdapter
,KeyAdapter
,MouseAdapter
不是适配器;它们实际上是Null Objects . Sun的命名选择不佳 .装饰器模式(
BufferedInputStream
可以装饰其他流,如FilterInputStream
)用于AWT工具包和Swing可插入外观类的AbstractFactory模式
java.lang.Runtime#getRuntime()
是Singleton_ *** 9_
ButtonGroup
for 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 在很多地方使用,但最明显的是脚本接口 .
Singleton - java.lang.Runtime浮现在脑海中 .
Abstract Factory - 还有脚本和JDBC API .
Command - TextComponent的撤消/重做 .
Interpreter - RegEx(java.util.regex . )和SQL(java.sql . )API .
Prototype - 不是100%肯定如果这个计数,但我认为
clone()
方法可以用于此目的 .即使我用这个时钟来破坏时钟,Java XML API也会使用Factory . 我的意思是看看这个:
...等等等等 .
另外,各种Buffers(StringBuffer,ByteBuffer,StringBuilder)使用Builder .
抽象工厂模式用于各种地方 . 例如,
DatagramSocketImplFactory
,PreferencesFactory
. 还有更多---在Javadoc中搜索名称中包含单词"Factory"的接口 .此外,还有很多工厂模式的实例 .
java.util.Collection #teterator是Factory方法的一个很好的例子 . 根据您使用的Collection的具体子类,它将创建一个Iterator实现 . 因为Factory超类(Collection)和Iterator都是接口,所以它有时会与AbstractFactory混淆 . 在接受的答案(BalusC)中,AbstractFactory的大多数示例都是Factory的示例,它是Factory Method的简化版本,它不是原始GoF模式的一部分 . 在Facory中,工厂类层次结构已折叠,工厂使用其他方法选择要返回的产品 .
抽象工厂有多种工厂方法,每种方法都可以创建不同的产品 . 一家工厂 生产环境 的产品可以一起使用(您的打印机和墨盒最好来自同一个(抽象)工厂) . 正如上面的答案中所提到的,不同平台的AWT GUI组件系列就是一个例子(虽然它的实现与Gof中描述的结构不同) .
您可以在Wikipedia中找到许多设计模式的概述 . 它还提到了GoF提到的模式 . 我将在这里总结它们并尝试在Java SE和Java EE API中分配尽可能多的模式实现 .
创作模式
抽象工厂(可通过创建方法识别返回工厂本身,而工厂本身又可用于创建另一个抽象/接口类型)
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance()
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
工厂方法(可通过创建方法识别,返回抽象/接口类型的实现)
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()等类似方法
原型(通过创建方法识别,返回具有相同属性的自身的不同实例)
Singleton(可通过创建方法识别返回相同的实例(通常是自身)每次)
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()
Bridge(通过创建方法识别,采用不同的抽象/接口类型的实例并返回委托/使用给定实例的自己的抽象/接口类型的实现)
new LinkedHashMap(LinkedHashSet<K>, List<V>)
,它返回一个不可修改的链接映射,它不会克隆项目,而是使用它们 . 然而,java.util.Collections#newSetFromMap()和singletonXXX()方法接近了 .Composite(通过将相同的抽象/接口类型的实例转换为树结构的行为方法可识别)
java.awt.Container#add(Component)(因此几乎遍及Swing)
javax.faces.component.UIComponent#getChildren()(几乎遍及JSF UI)
装饰器(通过创建方法识别,采用相同的抽象/接口类型的实例,增加了额外的行为)
java.io.InputStream,OutputStream,Reader和Writer的所有子类都有一个构造函数,它采用相同类型的实例 .
java.util.Collections,checkedXXX(),synchronizedXXX()和unmodifiableXXX()方法 .
javax.servlet.http.HttpServletRequestWrapper和HttpServletResponseWrapper
javax.swing.JScrollPane
Facade(可通过内部使用不同独立抽象/接口类型实例的行为方法识别)
javax.faces.context.FacesContext,它在内部使用了抽象/接口类型LifeCycle,ViewHandler,NavigationHandler以及更多,而最终用户不必担心它(但是可以通过注入覆盖) .
javax.faces.context.ExternalContext,内部使用ServletContext,HttpSession,HttpServletRequest,HttpServletResponse等 .
Flyweight(通过创建方法可以识别返回缓存实例,有点“multiton”想法)
代理(可通过创建方法识别,返回给定抽象/接口类型的实现,然后委托/使用给定抽象/接口类型的不同实现)
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()
命令(可通过抽象/接口类型中的行为方法识别,该类型调用在创建期间由命令实现封装的不同抽象/接口类型的实现中的方法)
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的所有实现
Mediator(通过行为方法识别,采用不同的抽象/接口类型的实例(通常使用命令模式)委托/使用给定的实例)
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(可通过内部改变整个实例状态的行为方法识别)
java.util.Date(setter方法执行此操作,
Date
内部由long
值表示)java.io.Serializable的所有实现
javax.faces.component.StateHolder的所有实现
Observer(或Publish / Subscribe)(可通过行为方法识别,根据自身状态调用另一个抽象/接口类型的实例上的方法)
java.util.Observer / java.util.Observable(虽然在现实世界中很少使用)
java.util.EventListener的所有实现(因此几乎遍及Swing)
javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
状态(可通过行为方法识别,根据实例的状态改变其行为,可以从外部控制)
战略(可以通过抽象/接口类型中的行为方法识别,该类型调用不同抽象/接口类型的实现中的方法,该方法已作为方法参数传入策略实现中)
java.util.Comparator#compare(),由
Collections#sort()
执行 .javax.servlet.http.HttpServlet,
service()
和所有doXXX()
方法都需要HttpServletRequest
和HttpServletResponse
,并且实现者必须处理它们(而不是将它们作为实例变量来保存!) .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
javax.lang.model.element.Element和ElementVisitor
javax.lang.model.type.TypeMirror和TypeVisitor
java.nio.file.FileVisitor和SimpleFileVisitor
javax.faces.component.visit.VisitContext和VisitCallback
RMI基于代理 .
对于GoF中的23种模式中的大多数,应该可以引用一种:
Abstract Factory:java.sql接口在注册驱动程序时从JDBC JAR获取具体实现 .
Builder:java.lang.StringBuilder .
工厂方法:XML工厂等 .
原型:也许克隆(),但我'm not sure I'米买了 .
Singleton:java.lang.System
适配器:java.awt.event中的适配器类,例如WindowAdapter .
Bridge:java.util中的集合类 . 由ArrayList实现的列表 .
Composite:java.awt . java.awt.Component java.awt.Container
装饰器:遍布java.io包 .
Facade:ExternalContext表现为执行cookie,会话范围和类似操作的外观 .
Flyweight:整数,字符等
代理:java.rmi包
责任链:Servlet过滤器
命令:Swing菜单项
解释器:没有直接在JDK中,但JavaCC当然使用它 .
迭代器:java.util.Iterator接口;不能比那更清楚 .
调解员:JMS?
纪念品:
Observer:java.util.Observer/Observable(虽然做得不好)
州:
策略:
模板:
访客:
我想不出23个中有10个用Java的例子,但我明白我明天能不能做得更好 . 这就是编辑的目的 .