问题

我正在学习GoF Java设计模式,我想看看它们的一些真实例子。 Java核心库中这些设计模式的一些很好的例子是什么?


#1 热门回答(2815 赞)

你可以在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()(synchronized)
  • 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()和其他类似的方法

Prototype(可通过创建方法识别,返回具有相同属性的自身的不同实例)

  • java.lang.Object#clone()(该类必须实现java.lang.Cloneable)

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(通过创建方法识别,采用不同的抽象/接口类型的实例并返回委托/使用给定实例的自己的抽象/接口类型的实现)

  • 没有想到的。一个虚构的例子是新的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.Integer #valueOf(int)(也在布尔,字节,字符,短,长和BigDecimal上)

###代理(可通过创建方法识别,返回给定抽象/接口类型的实现,后者依次委托/使用给定抽象/接口类型的不同实现)

  • java.lang.reflect.Proxy
  • java.rmi。*
  • javax.ejb.EJB(这里有解释)
  • javax.inject.Inject(这里的解释)
  • javax.persistence.PersistenceContext

##行为模式

###责任链(可通过行为方法识别,这些方法(间接地)在队列中的相同抽象/接口类型的另一个实现中调用相同的方法)

  • java.util.logging.Logger中的#日志()
  • javax.servlet.Filter #doFilter()

###命令(可通过抽象/接口类型中的行为方法识别,该类型调用在创建期间由命令实现封装的不同抽象/接口类型的实现中的方法)

  • java.lang.Runnable的所有实现
  • javax.swing.Action的所有实现

Interpreter(可通过行为方法识别,返回给定实例/类型的结构上不同的实例/类型;请注意,解析/格式化不是模式的一部分,确定模式以及如何应用它)

  • java.util.Pattern
  • java.text.Normalizer
  • java.text.Format的所有子类
  • javax.el.E​​LResolver的所有子类

Iterator(可通过行为方法识别,从队列中顺序返回不同类型的实例)

  • 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

###状态(可通过行为方法识别,根据实例的状态改变其行为,可以从外部控制)

  • javax.faces.lifecycle.LifeCycle #cute()(由FacesServlet控制,行为取决于JSF生命周期的当前阶段(状态))

###策略(可通过抽象/接口类型中的行为方法识别,该类型调用不同抽象/接口类型的实现中的方法,该方法已作为方法参数传入策略实现中)

  • java.util.Comparator#compare(),由其他集合执行#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

#2 热门回答(95 赞)

  • 整个挥杆过程中的观察者模式(Observable,Observer)
  • MVC也在摇摆
  • 适配器模式:InputStreamReader和OutputStreamWriter注意:ContainerAdapter,ComponentAdapter,FocusAdapter,KeyAdapter,MouseAdapter不是适配器;它们实际上是Null Objects。 Sun的命名选择不佳。
  • Decorator模式(BufferedInputStream可以装饰其他流,如FilterInputStream)
  • 用于AWT Toolkit和Swing可插入外观类的AbstractFactory Pattern
  • java.lang.Runtime#getRuntime()是Singleton
  • 用于Mediator模式的ButtonGroup
  • Action,AbstractAction可以用于不同的可视化表示来执行相同的代码 - >命令模式
  • 用于Flyweight模式的JTable中的Interned Strings或CellRender(还要考虑各种池 - 线程池,连接池,EJB对象池 - Flyweight实际上是关于共享资源的管理)
  • Java 1.0事件模型是一个责任链的例子,Servlet过滤器也是如此。
  • 集合框架中的迭代器模式
  • AWT / Swing中的嵌套容器使用Composite模式
  • AWT / Swing中的布局管理器是战略的一个例子

还有更多我猜


#3 热门回答(47 赞)

  • Flyweight与Byte,Short,Integer,Long和String的某些值一起使用。
  • Facade在很多地方使用,但最明显的是Scripting接口。
  • 想到Singleton - java.lang.Runtime。
  • 抽象工厂 - 还有脚本和JDBC API。
  • 命令 - TextComponent的撤消/重做。
  • 解释器 - RegEx(java.util.regex。)和SQL(java.sql。)API。
  • 原型 - 不是100%肯定,如果这个计数,但我认为克隆()方法可以用于此目的。

原文链接