我正在学习GoF Java设计模式,我想看到一些现实生活中的例子。Java核心库中有哪些设计模式的好例子?


当前回答

Flyweight用于字节,短,整数,长和字符串的一些值。 Facade被用在很多地方,但最明显的是脚本接口。 单例-想到java.lang.Runtime。 抽象工厂-也脚本和JDBC API。 命令- TextComponent的撤销/重做。 解释器- RegEx (java.util.regex.)和SQL (java.sql.)API。 原型-不是100%确定这是否算数,但我认为clone()方法可以用于此目的。

其他回答

Flyweight用于字节,短,整数,长和字符串的一些值。 Facade被用在很多地方,但最明显的是脚本接口。 单例-想到java.lang.Runtime。 抽象工厂-也脚本和JDBC API。 命令- TextComponent的撤销/重做。 解释器- RegEx (java.util.regex.)和SQL (java.sql.)API。 原型-不是100%确定这是否算数,但我认为clone()方法可以用于此目的。

尽管我对这一点有点不熟悉,但Java XML API经常使用Factory。我是说看看这个:

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);

...诸如此类。

此外,各种缓冲区(StringBuffer, ByteBuffer, StringBuilder)使用Builder。

你可以在维基百科上找到很多设计模式的概述。它还提到了GoF提到的模式。我将在这里总结它们,并尝试分配尽可能多的模式实现,这些实现在Java SE和Java EE api中都可以找到。


创建型模式

抽象工厂(可通过创建方法识别,返回工厂本身,从而可以用于创建另一个抽象/接口类型)

javax . xml parsers DocumentBuilderFactory # newInstance()。 javax . xml 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 () charset # forName () urlstreamhandlerfactory(返回每个协议的单个对象) java.util.EnumSet # () jaxbcontext #createMarshaller()和其他类似的方法

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

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

单例(可通过创建方法每次返回相同的实例(通常是其本身)来识别)

朗。java Runtime # getRuntime () # getDesktop桌面java . awt。() 朗。系统/ getSecurityManager (java)


结构模式

适配器(可通过创建方法识别,该方法采用不同抽象/接口类型的实例,并返回自己/另一个抽象/接口类型的实现,该实现装饰/覆盖给定实例)

java.util.Arrays # asList () java.util.Collections #列表() java.util.Collections #枚举() java.io.InputStreamReader(返回一个Reader) java.io.OutputStreamWriter(OutputStream)(返回写入器) javax.xml.bind.annotation.adapters.XmlAdapter#marshal()和#unmarshal()

桥接(可通过创建方法识别,该方法获取不同抽象/接口类型的实例,并返回自己的抽象/接口类型的实现,该实现委托/使用给定实例)

现在还想不起来。一个虚构的例子是new LinkedHashMap(LinkedHashSet<K>, List<V>),它返回一个不可修改的链接映射,它不克隆项目,而是使用它们。然而,java.util.Collections#newSetFromMap()和singletonXXX()方法非常接近。

复合(可通过行为方法将相同抽象/接口类型的实例放入树结构中进行识别)

container #add(组件)(几乎在整个Swing中) uicomponent #getChildren()(实际上是整个JSF UI)

装饰器(可以通过采用相同抽象/接口类型实例的创建方法来识别,这增加了额外的行为)

java.io的所有子类。InputStream、OutputStream、Reader和Writer都有一个构造函数,该构造函数采用相同类型的实例。 java.util。集合,checkedXXX(), synchronizedXXX()和unmodifiableXXX()方法。 java .servlet.http. httpservletrequestwrapper和HttpServletResponseWrapper javax.swing.JScrollPane

外观(可通过行为方法识别,它在内部使用不同独立抽象/接口类型的实例)

javax.faces.context。FacesContext,它在内部使用其他抽象/接口类型LifeCycle, ViewHandler, NavigationHandler等,而最终用户不必担心它(然而,这些是可以通过注入重写的)。 javax.faces.context。ExternalContext,它在内部使用ServletContext、HttpSession、HttpServletRequest、HttpServletResponse等。

Flyweight(可以通过创建方法返回一个缓存实例来识别,有点“多吨”的想法)

java.lang.Integer#valueOf(int)(也适用于布尔值,字节,字符,短,长和BigDecimal)

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

java.lang.reflect.Proxy java.rmi。* ejb(此处解释) inject(此处解释) javax.persistence.PersistenceContext


行为模式

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

java.util.logging.logger#log() javax.servlet.Filter#doFilter()

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

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的所有实现

中介(可以通过行为方法识别,它采用不同抽象/接口类型的实例(通常使用命令模式),委托/使用给定实例)

timer(所有scheduleXXX()方法) java.util.concurrent.Executor # execute () concurrent. executorservice (invokeXXX()和submit()方法) concurrent. scheduledexecutorservice(所有scheduleXXX()方法) java.lang.reflect.Method # invoke ()

纪念品(可通过行为方法识别,在内部改变整个实例的状态)

Date (setter方法可以做到这一点,Date在内部由一个长值表示) java.io.Serializable的所有实现 javax.faces.component.StateHolder的所有实现

观察者(或发布/订阅)(可由行为方法识别,它调用另一个抽象/接口类型实例上的方法,这取决于自己的状态)

java.util.Observer / java.util。可观察的(但在现实世界中很少使用) java.util.EventListener的所有实现(实际上是Swing中的所有实现) javax.servlet.http.HttpSessionBindingListener javax.servlet.http.HttpSessionAttributeListener javax.faces.event.PhaseListener

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

#execute()(由FacesServlet控制,行为取决于JSF生命周期的当前阶段(状态))

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

java.util.Comparator#compare(),由Collections#sort()执行。 javax.servlet.http。HttpServlet, service()和所有doXXX()方法接受HttpServletRequest和HttpServletResponse,实施者必须处理它们(而不是将它们作为实例变量!) doFilter () javax.servlet.Filter #

模板方法(可以通过已经具有抽象类型定义的“默认”行为的行为方法识别)

java.io的所有非抽象方法。InputStream, io。OutputStream, java.io.Reader和java.io.Writer。 java.util的所有非抽象方法。java.util.AbstractSet和java.util.AbstractMap。 javax.servlet.http。在HttpServlet中,所有doXXX()方法默认向响应发送一个HTTP 405“Method Not Allowed”错误。您可以自由地实现其中任何一个或任何一个。

访问者(可由两种不同的抽象/接口类型识别,其中定义了各自接受另一种抽象/接口类型的方法;一个实际调用另一个的方法,另一个在它上面执行所需的策略)

annotation value和AnnotationValueVisitor lang.model.element. element和ElementVisitor java .lang.model.type. typemirror和TypeVisitor java.nio.file.FileVisitor和SimpleFileVisitor javax。faces。component。visit。visitcontext和VisitCallback

工厂方法

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.

抽象工厂

抽象工厂有多个工厂方法,每个方法创建一个不同的产品。一家工厂生产的产品是为了一起使用(您的打印机和墨盒最好来自同一家(抽象)工厂)。正如上面的回答中提到的,不同平台的AWT GUI组件家族就是一个例子(尽管它的实现与Gof中描述的结构不同)。

抽象工厂模式被用在很多地方。 例如,DatagramSocketImplFactory, PreferencesFactory。还有很多——在Javadoc中搜索名称中包含“Factory”的接口。

同样,工厂模式也有相当多的实例。