The Source for Java Technology Collaboration
User: Password:



Laird Nelson's Blog

Programming Archives


Seventeenth century object design

Posted by ljnelson on September 02, 2004 at 08:10 AM | Permalink | Comments (16)

Hello, first of all. It's an honor to be part of the java.net weblogging community.

A discussion concerning component reuse brought me back to my philosophy major days in college. Who knew British empiricism could help you with object design?

The discussion was (is) about, loosely, how best to design an object or a component for reuse. You want to get the hypothetical object down to what's important across domains, to trim away the fat, but, as a competing concern, to make it rich enough that people won't have to reinvent the wheel. Slimming down your object also provides incentive for someone else to use it, provided you don't slim it down so far that it's impractical.

What is this "fat" we're talking about? In general, it's concerns or aspects or facets of the real-world thing that our object is modeling. There are many facets about a hypothetical and reusable Person object (and the set of all persons that it models), for example, that could be included, ranging from names to measurements to relationships with others. Which of these groups of attributes is necessary for a Person to be a Person? Which is superfluous? What is the Person apart from these groups of attributes?

John Locke examined these issues in An Essay Concerning Human Understanding. Ruthlessly paraphrased, and butchered somewhat for this weblog's purposes, he argues that when you hear someone mention a person, you frame a "complication or collection" of "simple ideas" in your mind that "go constantly together", such as height, weight, general shape, etc. In Locke's view we humans in the normal unexamined course of our lives don't imagine these ideas simply existing on their own, so we subconsciously posit the existence of a "substratum" that they bind to, although strictly speaking we never entirely know what we're talking about. Locke calls this substratum substance, and, believe it or not, it's one way of thinking about object reuse, whether it exists or not.

A couple of choice quotes from Locke on this whole subject:

If any one should be asked, what is the subject wherein colour or weight inheres, he would have nothing to say, but the solid extended parts; and if he were demanded, what is it that solidity and extension adhere in, he would... [answer] SOMETHING, HE KNEW NOT WHAT.
...[O]ur...ideas of substances...have always the confused idea of something to which they belong...and therefore when we speak of any sort of substance, we say it is a thing having such or such qualities; as body is a thing that is extended, figured, and capable of motion; spirit, a thing capable of thinking; and so hardness, friability, and power to draw iron, we say, are qualities to be found in a loadstone. These...intimate that the substance is supposed always SOMETHING BESIDES the extension, figure, solidity, motion, thinking, or other observable ideas, though we know not what it is.

Let's apply Locke to object design and see where it leads. Suppose he's right: a person is simply a collection of related attributes or facets that adhere to some substratum. Let's model this explicitly.

Backing up for a second for contrast, the normal way you would design a domain-independent Person object, assuming for the moment you could, would be to pick some attributes that you thought were sufficiently general and important to be included in this superclass (and here's where you run into problems). Here, for the sake of brevity, is my silly offering:

public class Person {
  
  // My selection for an attribute that is important enough to
  // be included in this reusable class.  Yours could be different.
  // Of course that means we'll probably end up not reusing each other's
  // classes.  Hmm.
  private String name;

  public Person() {
    super();
  }

  public String getName() {
    return this.name;
  }

  public void setName(final String name) {
    this.name = name;
  }

  // etc.

}

Of course, picking what those attributes are is what makes reusable object design so tough.

Locke, if he were an object designer, would be a rebel. He would probably start with the attributes--the collections of simple ideas--and graft them on to some simple "substance" object that would be deliberately designed to be more or less inscrutable. As it turns out, this is a much better way to achieve object reuse across domains. Maybe an extreme version of his code would look something like this:

public interface IKnowNotWhat {
  // If only we knew what it was!
}

public class Person implements IKnowNotWhat {

  public Person() {
    super();
  }

}

public abstract class CollectionOfSimpleIdeas {
    
  protected final IKnowNotWhat substance;

  public CollectionOfSimpleIdeas(final IKnowNotWhat substance) {
    super();
    this.substance = substance;
    if (substance == null) {
      throw new BritishEmpiricismMisunderstoodException();
    }
  }

  public IKnowNotWhat getSubstance() {
    return substance;
  }

}

public class PersonNames extends CollectionOfSimpleIdeas {
  
  private String familiarName;

  public PersonNames(final IKnowNotWhat substance) {
    super(substance);
  }

  public String getFamiliarName() {
    return this.familiarName;
  }

  public void setFamiliarName(final String familiarName) {
    this.familiarName = familiarName;
  }

  // etc.

}

public class PersonMeasurements extends CollectionOfSimpleIdeas {
    
  private int heightInInches;

  public PersonMeasurements(final IKnowNotWhat substance) {
    super(substance);
  }

  public int getHeight() {
    return this.heightInInches;
  }

  public void setHeight(final int height) {
    this.heightInInches = height;
  }

  // etc.

}

The key insight here is that people aren't interested in a reusable Person object at all. They are interested in different combinations of facets that all concern a person in a particular domain. A financial services programmer doesn't care about a person's weight, but that might be very important to the programmer of an insurance system. Explicitly modeling a person this way--inside out--lets each domain of attributes stand alone, but also lets them play nicely together when bound together. What's important is that the attributes are reused, not the substratum.

All of this philosophy has made my brain hurt. I'm going to go get some lunch (although I know not what).





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds