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


当前回答

你可以在维基百科上找到很多设计模式的概述。它还提到了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

其他回答

Observer pattern throughout whole swing (Observable, Observer) MVC also in swing Adapter pattern: InputStreamReader and OutputStreamWriter NOTE: ContainerAdapter, ComponentAdapter, FocusAdapter, KeyAdapter, MouseAdapter are not adapters; they are actually Null Objects. Poor naming choice by Sun. Decorator pattern (BufferedInputStream can decorate other streams such as FilterInputStream) AbstractFactory Pattern for the AWT Toolkit and the Swing pluggable look-and-feel classes java.lang.Runtime#getRuntime() is Singleton ButtonGroup for Mediator pattern Action, 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

我猜还有更多

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

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

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

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

...诸如此类。

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

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

RMI是基于Proxy的。

应该可以为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: ExternalContext behaves 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:

在这23个例子中,我想不出10个是用Java写的,但我会看看明天是否能做得更好。这就是编辑的作用。