Abstracting usage | CodeGuru

Abstracting usage

Bruce Eckel’s Thinking in Java Contents | Prev | Next With creation out of the way, it’s time to tackle the remainder of the design: where the classes are used. Since it’s the act of sorting into bins that’s particularly ugly and exposed, why not take that process and hide it inside a class? This […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 1, 2001
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

With


creation out of the way, it’s time to tackle the remainder of the design:


where the classes are used. Since it’s the act of sorting into bins


that’s particularly ugly and exposed, why not take that process and hide


it inside a class? This is the principle of “If you must do something


ugly, at least localize the ugliness inside a class.” It looks like this:

The


TrashSorter

object initialization must now be changed whenever a new type of


Trash

is added to the model. You could imagine that the


TrashSorter

class might look something like this:

class TrashSorter extends Vector {
  void sort(Trash t) { /* ... */ }
}

That


is,


TrashSorter

is a


Vector

of handles to


Vector

s


of


Trash

handles, and with


addElement( )

you can install another one, like so:

TrashSorter
ts = new TrashSorter();

ts.addElement(new
Vector());

Now,


however,


sort( )

becomes a problem. How does the statically-coded method deal with the fact that


a new type has been added? To solve this, the type information must be removed


from


sort( )

so that all it needs to do is call a generic method that takes care of the


details of type. This, of course, is another way to describe a


dynamically-bound method. So


sort( )

will simply move through the sequence and call a dynamically-bound method for


each


Vector

.


Since the job of this method is to grab the pieces of trash it is interested


in, it’s called


grab(Trash)

.


The structure now looks like:

TrashSorter

needs to call each


grab( )

method and get a different result depending on what type of


Trash

the current


Vector

is holding. That is, each


Vector

must be aware of the type it holds. The classic approach to this problem is to


create a base “


Trash

bin” class and inherit a new derived class for each different type you


want to hold. If Java had a parameterized type mechanism that would probably be


the most straightforward approach. But rather than hand-coding all the classes


that such a mechanism should be building for us, further observation can


produce a better approach.

A


basic OOP design principle is “Use data members for variation in state,


use

polymorphism
for variation in behavior.” Your first thought might be that the
grab( )
method certainly behaves differently for a
Vector
that holds
Paper
than for one that holds
Glass.
But what it does is strictly dependent on the type, and nothing else. This
could be interpreted as a different state, and since Java has a class to
represent type (
Class)
this can be used to determine the type of
Trash
a particular
Tbin
will hold.

The


constructor for this


Tbin

requires


that you hand it the


Class

of your choice. This tells the


Vector

what type it is supposed to hold. Then the


grab( )

method uses


Class
BinType

and RTTI to see if the


Trash

object you’ve handed it matches the type it’s supposed to grab.

Here


is the whole program. The commented numbers (e.g. (*1*) ) mark sections that


will be described following the code.

//: RecycleB.java
// Adding more objects to the recycling problem
package c16.recycleb;
import c16.trash.*;
import java.util.*;
 
// A vector that admits only the right type:
class Tbin extends Vector {
  Class binType;
  Tbin(Class binType) {
    this.binType = binType;
  }
  boolean grab(Trash t) {
    // Comparing class types:
    if(t.getClass().equals(binType)) {
      addElement(t);
      return true; // Object grabbed
    }
    return false; // Object not grabbed
  }
}
 
class TbinList extends Vector { //(*1*)
  boolean sort(Trash t) {
    Enumeration e = elements();
    while(e.hasMoreElements()) {
      Tbin bin = (Tbin)e.nextElement();
      if(bin.grab(t)) return true;
    }
    return false; // bin not found for t
  }
  void sortBin(Tbin bin) { // (*2*)
    Enumeration e = bin.elements();
    while(e.hasMoreElements())
      if(!sort((Trash)e.nextElement()))
        System.out.println("Bin not found");
  }
}
 
public class RecycleB {
  static Tbin bin = new Tbin(Trash.class);
  public static void main(String[] args) {
    // Fill up the Trash bin:
    ParseTrash.fillBin("Trash.dat", bin);
 
    TbinList trashBins = new TbinList();
    trashBins.addElement(
      new Tbin(Aluminum.class));
    trashBins.addElement(
      new Tbin(Paper.class));
    trashBins.addElement(
      new Tbin(Glass.class));
    // add one line here: (*3*)
    trashBins.addElement(
      new Tbin(Cardboard.class));
 
    trashBins.sortBin(bin); // (*4*)
 
    Enumeration e = trashBins.elements();
    while(e.hasMoreElements()) {
      Tbin b = (Tbin)e.nextElement();
      Trash.sumValue(b);
    }
    Trash.sumValue(bin);
  }
} ///:~ 
  1. TbinList
    holds a set of
    Tbin
    handles, so that
    sort( )
    can iterate through the
    Tbins
    when it’s looking for a match for the
    Trash
    object you’ve handed it.
  2. sortBin( )
    allows you to pass an entire
    Tbin
    in, and it moves through the
    Tbin,
    picks out each piece of
    Trash,
    and sorts it into the appropriate specific
    Tbin.
    Notice the genericity of this code: it doesn’t change at all if new types
    are added. If the bulk of your code doesn’t need changing when a new type
    is added (or some other change occurs) then you have an easily-extensible system.
  3. Now
    you can see how easy it is to add a new type. Few lines must be changed to
    support the addition. If it’s really important, you can squeeze out even
    more by further manipulating the design.
  4. One
    method call causes the contents of
    bin
    to be sorted into the respective specifically-typed bins.
Contents

|

Prev

|

Next
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.