📄 tij0174.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0173.html">Prev</a> | <a href="tij0175.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
The
pattern concept
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Initially,
you can think of a pattern as an especially clever and insightful way of
solving a particular class of problems. That is, it looks like a lot of people
have worked out all the angles of a problem and have come up with the most
general, flexible solution for it. The problem could be one you have seen and
solved before, but your solution probably didn’t have the kind of
completeness you’ll see embodied in a pattern.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Although
they’re called “design patterns,” they really aren’t
tied to the realm of design. A pattern seems to stand apart from the
traditional way of thinking about analysis, design, and implementation.
Instead, a pattern embodies a complete idea within a program, and thus it can
sometimes appear at the analysis phase or high-level design phase. This is
interesting because a pattern has a direct implementation in code and so you
might not expect it to show up before low-level design or implementation (and
in fact you might not realize that you need a particular pattern until you get
to those phases).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
basic concept of a pattern can also be seen as the basic concept of program
design: adding a layer of <A NAME="Index2914"></A><A NAME="Index2915"></A>abstraction.
Whenever you abstract something you’re isolating particular details, and
one of the most compelling motivations behind this is to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>separate
things that change from things that stay the same
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Another way to put this is that once you find some part of your program
that’s likely to change for one reason or another, you’ll want to
keep those changes from propagating other changes throughout your code. Not
only does this make the code much cheaper to maintain, but it also turns out
that it is usually simpler to understand (which results in lowered costs).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Often,
the most difficult part of developing an elegant and cheap-to-maintain design
is in discovering what I call “the <A NAME="Index2916"></A><A NAME="Index2917"></A><A NAME="Index2918"></A>vector
of change.” (Here, “vector” refers to the maximum gradient
and not a collection class.) This means finding the most important thing that
changes in your system, or put another way, discovering where your greatest
cost is. Once you discover the vector of change, you have the focal point
around which to structure your design.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">So
the goal of design patterns is to isolate changes in your code. If you look at
it this way, you’ve been seeing some design patterns already in this
book. For example, <A NAME="Index2919"></A>inheritance
can be thought of as a design pattern (albeit one implemented by the compiler).
It allows you to express differences in behavior (that’s the thing that
changes) in objects that all have the same interface (that’s what stays
the same). <A NAME="Index2920"></A>Composition
can also be considered a pattern, since it allows you to change –
dynamically or statically – the objects that implement your class, and
thus the way that class works.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You’ve
also already seen another pattern that appears in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>Design
Patterns
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
the <A NAME="Index2921"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>iterator</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(Java 1.0<A NAME="Index2922"></A>
and 1.1 capriciously calls it the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Enumeration</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">;
Java 1.2<A NAME="Index2923"></A>
collections use “iterator”
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This hides the particular implementation of the collection as you’re
stepping through and selecting the elements one by one. The iterator allows you
to write generic code that performs an operation on all of the elements in a
sequence without regard to the way that sequence is built. Thus your generic
code can be used with any collection that can produce an iterator.
</FONT><a name="_Toc408018795"></a><P></DIV>
<A NAME="Heading553"></A><H3 ALIGN=LEFT>
The
singleton
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Possibly
the simplest design pattern is the <A NAME="Index2924"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>singleton</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which is a way to provide one and only one instance of an object. This is used
in the Java libraries, but here’s a more direct example:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: SingletonPattern.java</font>
<font color="#009900">// The Singleton design pattern: you can</font>
<font color="#009900">// never instantiate more than one.</font>
<font color="#0000ff">package</font> c16;
<font color="#009900">// Since this isn't inherited from a Cloneable</font>
<font color="#009900">// base class and cloneability isn't added,</font>
<font color="#009900">// making it final prevents cloneability from</font>
<font color="#009900">// being added in any derived classes:</font>
<font color="#0000ff">final</font> <font color="#0000ff">class</font> Singleton {
<font color="#0000ff">private</font> <font color="#0000ff">static</font> Singleton s = <font color="#0000ff">new</font> Singleton(47);
<font color="#0000ff">private</font> <font color="#0000ff">int</font> i;
<font color="#0000ff">private</font> Singleton(<font color="#0000ff">int</font> x) { i = x; }
<font color="#0000ff">public</font> <font color="#0000ff">static</font> Singleton getHandle() {
<font color="#0000ff">return</font> s;
}
<font color="#0000ff">public</font> <font color="#0000ff">int</font> getValue() { <font color="#0000ff">return</font> i; }
<font color="#0000ff">public</font> <font color="#0000ff">void</font> setValue(<font color="#0000ff">int</font> x) { i = x; }
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> SingletonPattern {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
Singleton s = Singleton.getHandle();
System.out.println(s.getValue());
Singleton s2 = Singleton.getHandle();
s2.setValue(9);
System.out.println(s.getValue());
<font color="#0000ff">try</font> {
<font color="#009900">// Can't do this: compile-time error.</font>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -