📄 tij0180.html
字号:
types have been created in a different subdirectory. The new
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
data file is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>VTrash.dat</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and looks like this:
</FONT><P></DIV>
<font color="#990000"><PRE>c16.TrashVisitor.VGlass:54
c16.TrashVisitor.VPaper:22
c16.TrashVisitor.VPaper:11
c16.TrashVisitor.VGlass:17
c16.TrashVisitor.VAluminum:89
c16.TrashVisitor.VPaper:88
c16.TrashVisitor.VAluminum:76
c16.TrashVisitor.VCardboard:96
c16.TrashVisitor.VAluminum:25
c16.TrashVisitor.VAluminum:34
c16.TrashVisitor.VGlass:11
c16.TrashVisitor.VGlass:68
c16.TrashVisitor.VGlass:43
c16.TrashVisitor.VAluminum:27
c16.TrashVisitor.VCardboard:44
c16.TrashVisitor.VAluminum:18
c16.TrashVisitor.VPaper:91
c16.TrashVisitor.VGlass:63
c16.TrashVisitor.VGlass:50
c16.TrashVisitor.VGlass:80
c16.TrashVisitor.VAluminum:81
c16.TrashVisitor.VCardboard:12
c16.TrashVisitor.VGlass:12
c16.TrashVisitor.VGlass:54
c16.TrashVisitor.VAluminum:36
c16.TrashVisitor.VAluminum:93
c16.TrashVisitor.VGlass:93
c16.TrashVisitor.VPaper:80
c16.TrashVisitor.VGlass:36
c16.TrashVisitor.VGlass:12
c16.TrashVisitor.VGlass:60
c16.TrashVisitor.VPaper:66
c16.TrashVisitor.VAluminum:36
c16.TrashVisitor.VCardboard:22</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
rest of the program creates specific
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Visitor</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
types and sends them through a single list of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: TrashVisitor.java </font>
<font color="#009900">// The "visitor" pattern</font>
<font color="#0000ff">package</font> c16.trashvisitor;
<font color="#0000ff">import</font> c16.trash.*;
<font color="#0000ff">import</font> java.util.*;
<font color="#009900">// Specific group of algorithms packaged</font>
<font color="#009900">// in each implementation of Visitor:</font>
<font color="#0000ff">class</font> PriceVisitor <font color="#0000ff">implements</font> Visitor {
<font color="#0000ff">private</font> <font color="#0000ff">double</font> alSum; <font color="#009900">// Aluminum</font>
<font color="#0000ff">private</font> <font color="#0000ff">double</font> pSum; <font color="#009900">// Paper</font>
<font color="#0000ff">private</font> <font color="#0000ff">double</font> gSum; <font color="#009900">// Glass</font>
<font color="#0000ff">private</font> <font color="#0000ff">double</font> cSum; <font color="#009900">// Cardboard</font>
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VAluminum al) {
<font color="#0000ff">double</font> v = al.weight() * al.value();
System.out.println(
"value of Aluminum= " + v);
alSum += v;
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VPaper p) {
<font color="#0000ff">double</font> v = p.weight() * p.value();
System.out.println(
"value of Paper= " + v);
pSum += v;
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VGlass g) {
<font color="#0000ff">double</font> v = g.weight() * g.value();
System.out.println(
"value of Glass= " + v);
gSum += v;
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VCardboard c) {
<font color="#0000ff">double</font> v = c.weight() * c.value();
System.out.println(
"value of Cardboard = " + v);
cSum += v;
}
<font color="#0000ff">void</font> total() {
System.out.println(
"Total Aluminum: $" + alSum + "\n" +
"Total Paper: $" + pSum + "\n" +
"Total Glass: $" + gSum + "\n" +
"Total Cardboard: $" + cSum);
}
}
<font color="#0000ff">class</font> WeightVisitor <font color="#0000ff">implements</font> Visitor {
<font color="#0000ff">private</font> <font color="#0000ff">double</font> alSum; <font color="#009900">// Aluminum</font>
<font color="#0000ff">private</font> <font color="#0000ff">double</font> pSum; <font color="#009900">// Paper</font>
<font color="#0000ff">private</font> <font color="#0000ff">double</font> gSum; <font color="#009900">// Glass</font>
<font color="#0000ff">private</font> <font color="#0000ff">double</font> cSum; <font color="#009900">// Cardboard</font>
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VAluminum al) {
alSum += al.weight();
System.out.println("weight of Aluminum = "
+ al.weight());
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VPaper p) {
pSum += p.weight();
System.out.println("weight of Paper = "
+ p.weight());
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VGlass g) {
gSum += g.weight();
System.out.println("weight of Glass = "
+ g.weight());
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> visit(VCardboard c) {
cSum += c.weight();
System.out.println("weight of Cardboard = "
+ c.weight());
}
<font color="#0000ff">void</font> total() {
System.out.println("Total weight Aluminum:"
+ alSum);
System.out.println("Total weight Paper:"
+ pSum);
System.out.println("Total weight Glass:"
+ gSum);
System.out.println("Total weight Cardboard:"
+ cSum);
}
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> TrashVisitor {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
Vector bin = <font color="#0000ff">new</font> Vector();
<font color="#009900">// ParseTrash still works, without changes:</font>
ParseTrash.fillBin("VTrash.dat", bin);
<font color="#009900">// You could even iterate through</font>
<font color="#009900">// a list of visitors!</font>
PriceVisitor pv = <font color="#0000ff">new</font> PriceVisitor();
WeightVisitor wv = <font color="#0000ff">new</font> WeightVisitor();
Enumeration it = bin.elements();
<font color="#0000ff">while</font>(it.hasMoreElements()) {
Visitable v = (Visitable)it.nextElement();
v.accept(pv);
v.accept(wv);
}
pv.total();
wv.total();
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Note
that the shape of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has changed again. Now there’s only a single
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
bin. The two
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Visitor</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects are accepted into every element in the sequence, and they perform their
operations. The visitors keep their own internal data to tally the total
weights and prices.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Finally,
there’s no run-time type identification other than the inevitable cast to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
when pulling things out of the sequence. This, too, could be eliminated with
the implementation of parameterized types in Java.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
way you can distinguish this solution from the double dispatching solution
described previously is to note that, in the double dispatching solution, only
one of the overloaded methods,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>add( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
was overridden when each subclass was created, while here
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>each</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
one of the overloaded
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>visit( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods is overridden in every subclass of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Visitor</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV>
<A NAME="Heading567"></A><H3 ALIGN=LEFT>
More
coupling?
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There’s
a lot more code here, and there’s definite coupling between the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
hierarchy and the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Visitor</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
hierarchy. However, there’s also high cohesion within the respective sets
of classes: they each do only one thing (
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">describes
Trash, while
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Visitor
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">describes
actions performed on
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">),
which is an indicator of a good design. Of course, in this case it works well
only if you’re adding new
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Visitor</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s,
but it gets in the way when you add new types of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Low
coupling between classes and high cohesion within a class is definitely an
important design goal. Applied mindlessly, though, it can prevent you from
achieving a more elegant design. It seems that some classes inevitably have a
certain intimacy with each other. These often occur in pairs that could perhaps
be called <A NAME="Index3003"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>couplets</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
for example, collections and iterators (
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Enumeration</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s).
The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash-Visitor</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
pair above appears to be another such couplet.
</FONT><a name="_Toc408018806"></a><a name="_Toc375545419"></a><P></DIV>
<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0179.html">Prev</a> | <a href="tij0181.html">Next</a>
</div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -