天天看点

如何学习JDK里的设计模式

最近在看jdk源码,想在毕业前再好好提高一下写代码的能力,jdk是个优秀的源码阅读范本(spring的源码也不错)。jdk目录下的src.zip里可以直接获得源码,我也push到了我github的一个repo里。

网上搜了jdk设计模式,coolshell里也有一篇,不过我还是参照了stackoverflow(原文链接)上的一个“examples of gof design

patterns”的答复,详细列举了jdk里具体对应的类和函数,并结合了wiki上的许多整理好的优秀词条内容。放到这个博客上,也方便自己深入学习,好好体会下设计模式内涵,光看书也会很枯燥,况且纸质的代码看起来也不舒服。

you can find an overview of a lot of design patterns in wikipedia.

it also mentions which patterns are mentioned by gof. i'll sum them up here and try to assign as much as possible pattern implementations found in both the java se and java ee api's.

<code>javax.xml.parsers.documentbuilderfactory#newinstance()</code>

<code>javax.xml.transform.transformerfactory#newinstance()</code>

<code>javax.xml.xpath.xpathfactory#newinstance()</code>

<code>java.lang.stringbuilder#append()</code> (unsynchronized)

<code>java.lang.stringbuffer#append()</code> (synchronized)

<code>java.nio.bytebuffer#put()</code> (also

on <code>charbuffer</code>, <code>shortbuffer</code>, <code>intbuffer</code>, <code>longbuffer</code>,<code>floatbuffer</code> and <code>doublebuffer</code>)

<code>javax.swing.grouplayout.group#addcomponent()</code>

all implementations of <code>java.lang.appendable</code>

<code>java.util.calendar#getinstance()</code>

<code>java.util.resourcebundle#getbundle()</code>

<code>java.text.numberformat#getinstance()</code>

<code>java.nio.charset.charset#forname()</code>

<code>java.net.urlstreamhandlerfactory#createurlstreamhandler(string)</code> (returns

singleton object per protocol)

<code>java.lang.object#clone()</code> (the

class has to implement <code>java.lang.cloneable</code>)

<code>java.lang.runtime#getruntime()</code>

<code>java.awt.desktop#getdesktop()</code>

<code>java.util.arrays#aslist()</code>

<code>java.io.inputstreamreader(inputstream)</code> (returns

a <code>reader</code>)

<code>java.io.outputstreamwriter(outputstream)</code> (returns

a <code>writer</code>)

<code>javax.xml.bind.annotation.adapters.xmladapter#marshal()</code> and <code>#unmarshal()</code>

none comes to mind yet. a fictive example would be <code>new linkedhashmap(linkedhashset&lt;k&gt;, list&lt;v&gt;)</code> which returns an unmodifiable linked map which doesn't clone the items, but uses them. the <code>java.util.collections#newsetfrommap()</code> and <code>singletonxxx()</code> methods

however comes close.

<code>java.awt.container#add(component)</code> (practically

all over swing thus)

<code>javax.faces.component.uicomponent#getchildren()</code> (practically

all over jsf ui thus)

all subclasses of <code>java.io.inputstream</code>, <code>outputstream</code>, <code>reader</code> and <code>writer</code> have

a constructor taking an instance of same type.

<code>java.util.collections</code>,

the <code>checkedxxx()</code>, <code>synchronizedxxx()</code> and <code>unmodifiablexxx()</code>methods.

<code>javax.servlet.http.httpservletrequestwrapper</code> and <code>httpservletresponsewrapper</code>

<code>javax.faces.context.facescontext</code>,

it internally uses among others the abstract/interface types <code>lifecycle</code>, <code>viewhandler</code>, <code>navigationhandler</code> and

many more without that the enduser has to worry about it (which are however overrideable by injection).

<code>javax.faces.context.externalcontext</code>,

which internally uses <code>servletcontext</code>,<code>httpsession</code>, <code>httpservletrequest</code>, <code>httpservletresponse</code>,

etc.

<code>java.lang.integer#valueof(int)</code> (also

on <code>boolean</code>, <code>byte</code>, <code>character</code>, <code>short</code> and <code>long</code>)

<code>java.lang.reflect.proxy</code>

<code>java.rmi.*</code>,

the whole api actually.

the

wikipedia example is imho a bit poor, lazy loading has actually completely nothing to do with the proxy pattern at all.

<code>java.util.logging.logger#log()</code>

<code>javax.servlet.filter#dofilter()</code>

all implementations of <code>java.lang.runnable</code>

all implementations of <code>javax.swing.action</code>

<code>java.util.pattern</code>

<code>java.text.normalizer</code>

all subclasses of <code>java.text.format</code>

all subclasses of <code>javax.el.elresolver</code>

all implementations of <code>java.util.iterator</code> (thus

among others also <code>java.util.scanner</code>!).

all implementations of <code>java.util.enumeration</code>

<code>java.util.timer</code> (all <code>schedulexxx()</code> methods)

<code>java.util.concurrent.executor#execute()</code>

<code>java.util.concurrent.executorservice</code> (the <code>invokexxx()</code> and <code>submit()</code> methods)

<code>java.util.concurrent.scheduledexecutorservice</code> (all <code>schedulexxx()</code> methods)

<code>java.lang.reflect.method#invoke()</code>

<code>java.util.date</code> (the

setter methods do that, <code>date</code> is

internally represented by a <code>long</code> value)

all implementations of <code>java.io.serializable</code>

all implementations of <code>javax.faces.component.stateholder</code>

<code>java.util.observer</code>/<code>java.util.observable</code> (rarely

used in real world though)

all implementations of <code>java.util.eventlistener</code> (practically

<code>javax.servlet.http.httpsessionbindinglistener</code>

<code>javax.servlet.http.httpsessionattributelistener</code>

<code>javax.faces.event.phaselistener</code>

<code>javax.faces.lifecycle.lifecycle#execute()</code> (controlled

by <code>facesservlet</code>,

the behaviour is dependent on current phase (state) of jsf lifecycle)

<code>java.util.comparator#compare()</code>,

executed by among others <code>collections#sort()</code>.

<code>javax.servlet.http.httpservlet</code>,

the <code>service()</code> and

all <code>doxxx()</code> methods

take<code>httpservletrequest</code> and <code>httpservletresponse</code> and

the implementor has to process them (and not to get hold of them as instance variables!).

all non-abstract methods of <code>java.io.inputstream</code>, <code>java.io.outputstream</code>, <code>java.io.reader</code>and <code>java.io.writer</code>.

all non-abstract methods of <code>java.util.abstractlist</code>, <code>java.util.abstractset</code> and<code>java.util.abstractmap</code>.

all the <code>doxxx()</code> methods

by default sends a http 405 "method not allowed" error to the response. you're free to implement none or any of them.

<code>javax.lang.model.element.annotationvalue</code> and <code>annotationvaluevisitor</code>

<code>javax.lang.model.element.element</code> and <code>elementvisitor</code>

<code>javax.lang.model.type.typemirror</code> and <code>typevisitor</code>

(全文完)