最近在看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<k>, list<v>)</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>
(全文完)