天天看點

如何學習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>

(全文完)