⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij0177.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 4 页
字号:
method removes white space at both ends of a string.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">parser
is placed in a separate file since it will be reused throughout this chapter:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: ParseTrash.java </font>
<font color="#009900">// Open a file and parse its contents into</font>
<font color="#009900">// Trash objects, placing each into a Vector</font>
<font color="#0000ff">package</font> c16.trash;
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">import</font> java.io.*;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> ParseTrash {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> 
  fillBin(String filename, Fillable bin) {
    <font color="#0000ff">try</font> {
      BufferedReader data =
        <font color="#0000ff">new</font> BufferedReader(
          <font color="#0000ff">new</font> FileReader(filename));
      String buf;
      <font color="#0000ff">while</font>((buf = data.readLine())!= <font color="#0000ff">null</font>) {
        String type = buf.substring(0, 
          buf.indexOf(':')).trim();
        <font color="#0000ff">double</font> weight = Double.valueOf(
          buf.substring(buf.indexOf(':') + 1)
          .trim()).doubleValue();
        bin.addTrash(
          Trash.factory(
            <font color="#0000ff">new</font> Trash.Info(type, weight)));
      }
      data.close();
    } <font color="#0000ff">catch</font>(IOException e) {
      e.printStackTrace();
    } <font color="#0000ff">catch</font>(Exception e) {
      e.printStackTrace();
    }
  }
  <font color="#009900">// Special case to handle Vector:</font>
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> 
  fillBin(String filename, Vector bin) {
    fillBin(filename, <font color="#0000ff">new</font> FillableVector(bin));
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>RecycleA.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
was used to hold the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects. However, other types of collections can be used as well. To allow for
this, the first version of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
takes a handle to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Fillable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which is simply an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that supports a method called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addTrash(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Fillable.java </font>
<font color="#009900">// Any object that can be filled with Trash</font>
<font color="#0000ff">package</font> c16.trash;

<font color="#0000ff">public</font> <font color="#0000ff">interface</font> Fillable {
  <font color="#0000ff">void</font> addTrash(Trash t);
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Anything
that supports this interface can be used with 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Of course, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn&#8217;t implement 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Fillable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so it won&#8217;t work. Since 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is used in most of the examples, it makes sense to add a second overloaded 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method that takes a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can be used as a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Fillable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object using an adapter class:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: FillableVector.java </font>
<font color="#009900">// Adapter that makes a Vector Fillable</font>
<font color="#0000ff">package</font> c16.trash;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> FillableVector <font color="#0000ff">implements</font> Fillable {
  <font color="#0000ff">private</font> Vector v;
  <font color="#0000ff">public</font> FillableVector(Vector vv) { v = vv; }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> addTrash(Trash t) {
    v.addElement(t);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see that the only job of this class is to connect 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Fillable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;s
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addTrash(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;s
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addElement(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
With this class in hand, the overloaded 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method can be used with a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ParseTrash.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE>  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> 
  fillBin(String filename, Vector bin) {
    fillBin(filename, <font color="#0000ff">new</font> FillableVector(bin));
  } </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
approach works for any collection class that&#8217;s used frequently.
Alternatively, the collection class can provide its own adapter that implements 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Fillable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
(You&#8217;ll see this later, in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DynaTrash.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.)</FONT><P></DIV>
<A NAME="Heading562"></A><H4 ALIGN=LEFT>
Recycling
with prototyping
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
you can see the revised version of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>RecycleA.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
using the <A NAME="Index2986"></A><A NAME="Index2987"></A>prototyping
technique:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: RecycleAP.java </font>
<font color="#009900">// Recycling with RTTI and Prototypes</font>
<font color="#0000ff">package</font> c16.recycleap;
<font color="#0000ff">import</font> c16.trash.*;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> RecycleAP {
  <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">// Fill up the Trash bin:</font>
    ParseTrash.fillBin("Trash.dat", bin);
    Vector 
      glassBin = <font color="#0000ff">new</font> Vector(),
      paperBin = <font color="#0000ff">new</font> Vector(),
      alBin = <font color="#0000ff">new</font> Vector();
    Enumeration sorter = bin.elements();
    <font color="#009900">// Sort the Trash:</font>
    <font color="#0000ff">while</font>(sorter.hasMoreElements()) {
      Object t = sorter.nextElement();
      <font color="#009900">// RTTI to show class membership:</font>
      <font color="#0000ff">if</font>(t <font color="#0000ff">instanceof</font> Aluminum)
        alBin.addElement(t);
      <font color="#0000ff">if</font>(t <font color="#0000ff">instanceof</font> Paper)
        paperBin.addElement(t);
      <font color="#0000ff">if</font>(t <font color="#0000ff">instanceof</font> Glass)
        glassBin.addElement(t);
    }
    Trash.sumValue(alBin);
    Trash.sumValue(paperBin);
    Trash.sumValue(glassBin);
    Trash.sumValue(bin);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">All
of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects, as well as the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ParseTrash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and support classes, are now part of the package 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c16.trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
so they are simply imported.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
process of opening the data file containing 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
descriptions and the parsing of that file have been wrapped into the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ParseTrash.fillBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so now it&#8217;s no longer a part of our design focus. You will see that
throughout the rest of the chapter, no matter what new classes are added, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ParseTrash.fillBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
will continue to work without change, which indicates a good design.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
terms of object creation, this design does indeed severely localize the changes
you need to make to add a new type to the system. However, there&#8217;s a
significant problem in the use of RTTI that shows up clearly here. The program
seems to run fine, and yet it never detects any cardboard, even though there is
cardboard in the list! This happens 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>because</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
of the use of RTTI, which looks for only the types that you tell it to look
for. The clue that <A NAME="Index2988"></A>RTTI
is being misused is that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>every
type in the system 
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
being tested, rather than a single type or subset of types. As you will see
later, there are ways to use polymorphism instead when you&#8217;re testing for
every type. But if you use RTTI a lot in this fashion, and you add a new type
to your system, you can easily forget to make the necessary changes in your
program and produce a difficult-to-find bug. So it&#8217;s worth trying to
eliminate RTTI in this case, not just for aesthetic reasons &#8211; it produces
more maintainable code.
</FONT><a name="_Toc375545416"></a><a name="_Toc408018802"></a><P></DIV>

<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0176.html">Prev</a> | <a href="tij0178.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -