The Source for Java Technology Collaboration
User: Password:



Laird Nelson

Laird Nelson's Blog

Seventeenth century object design

Posted by ljnelson on September 02, 2004 at 08:10 AM | 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).


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Easy to use little things?
    Hi Laird,

    Have you tried facet-based code like this? How'd it go?

    Do you think this is a case of small things being easier to reuse than big things? (But harder to find, track and market...)

    Or is it something deeper -- Class hierarchies not really matching the problems we hit for data representation?

    Dave


    protected Chef[] expandEmpire()
    {
    try
    {
    SomePlace somePlace = pickSomePlace();
    somePlace.mispronounceName();
    colonize(somePlace);
    excerciseConflictingIdeals();
    }
    catch(BritishEmpiricismMisunderstoodException beme)
    {
    //todo Should we abandon the ideals of the empire, or give up on it.
    //Wow, this empty catch block has been here a long time. Has anyone called this code since 1948?
    }
    finally
    {
    Chef[] expatChefs = temptGoodCooks(londonRestaurantScene);
    return expatChefs;
    }
    }

    Posted by: dwalend on September 02, 2004 at 07:53 PM

  • Empiricism is not imperialism
    Just a small point, I don't think the author was talking about British colonisation of the world, but a particular type of gaining knowledge through experimentation.

    Posted by: ricky_clarkson on September 03, 2004 at 06:57 AM

  • Easy to use little things?
    I've used this on a couple of projects now. It actually isn't that different
    from "regular" OO programming, with the exception that the "substance" is passed
    in to your object instead of created by it.

    Where things get even more metaphysically interesting is when you start
    thinking about the computer equivalent of taking up time and space. That is,
    there are many things that are attached to David Walend, but many, if not all,
    of those things can change. What doesn't change is that David Walend is at a
    particular point in space at a particular time (objections about death, living
    on in memory, fictional characters etc. cheerfully ignored). The computer
    analog of this is something like an ID in a database, or an address in memory.
    That's the "I know not what" that you pass in in this style of programming;
    that's the substratum to which attributes adhere.

    The difficulty, as you quite rightly point out, is that your facets become
    hard to manage because there are a lot of them. I've found, though, that on a
    given project, in that project's name- or package-space, there aren't
    that many. And this kind of programming (facet-oriented programming?) is
    a good way to start migrating duplicated code from, say, two separate
    departments in a big company into a common repository. Turn each department's
    Person object into something named a bit more facet-like, and
    modify their constructors to take in something that those facets are
    going to bind to. Now migrate the common stuff that they share up to a common
    facet superclass, or, perhaps, to a common facet that also contains the same
    substratum. You haven't really changed anyone's code, but you've altered
    the underpinnings it's based on so that the whole shooting match is a bit more
    centralized.

    Incidentally, this is the same principle that RDF is founded on. For example, here's a bit
    of RDF taken from the primer:


    August 16, 1999


    Note that the description (a facet) is "about" a substratum (in this case,
    whatever the thing is--I know not what--that is pointed to by the url
    http://www.example.org/index.html).

    Posted by: ljnelson on September 03, 2004 at 07:29 AM

  • Reusing objects
    So, what you say is : one must define first if you want a new kind of object-person which has new attributes or if you want just to handle in a different way the attributes already defined for the already existent object-person.

    Right?

    Posted by: yuriha on September 03, 2004 at 11:21 AM

  • Mixins
    It sounds like you want mixins.

    Ruby anyone? :-)

    Posted by: scott_sauyet on September 03, 2004 at 12:39 PM

  • Reusing objects
    Well, more like this: don't worry about the definition of Person so much, becuase no one will be able to agree what should be in it. Worry instead about the definition of PersonNames (or whatever you want to call it), PersonMeasurements, PersonRelationships, PersonBankAccountInformation, etc.

    Posted by: ljnelson on September 04, 2004 at 09:54 AM

  • Mixins
    No, not really, because in such a case my Person object would still have to inherit from/include any facet mixins I might define. If you do it "backwards" instead, and have the facet pull in the Person, then you don't need mixins at all.

    (The tricky problem is, as Dave points out below, if you're armed with, say, a PersonMeasurements object that attaches to a particular Person substrate, how do you figure out what other facets that Person is associated with? This is not insoluble, just tricky.)

    Posted by: ljnelson on September 07, 2004 at 08:40 AM

  • Easy to use little things?
    This blog entry sounded intriguing in the beginning but I was lost completely when I started reading about the substrates, substances and metaphysics. What is the author trying to do and what is its relation to reuse here?

    I find this "talking in abstract sense" thing just as amusing as the nexy guy. Even I used to do the same during my initial days of experimentation with the idea that "OO is natural to humans." Once, after a full night of discussion with friends and coworkers, I even gave some enlightening statements such as "A pen is a pen with or without a cap."

    The statement was just an "enlightening thing." That's what it is. Nothing more nothing less. These sort of discussions only caused slippage of schedules and running projects over budgets or only to find ourselves coding a piece of very badly designed object models.

    I STILL see so many people talk in that "abstract" sense in a serious design session as well. The way I see this type of talk/literature is that it is the inefficiency of not being able to relate things in the problem domain or solution domain on hand or in the real software development world. Software Engineering in the enterprise has matured enough and no longer qualifies for an art form.

    So, anyways, after spending about 30 minutes on this entry, I am neither able to understand the problem that the author is taking about nor the solution he is suggesting.

    In Java or any OO language please....

    Anyone?

    Posted by: javampire on September 14, 2004 at 05:16 PM

  • Easy to use little things?
    First of all, my apologies for failing you. Obviously I was not as clear as
    I should have been. Thanks for the feedback.

    In an effort to be more clear, let's start with your "A pen is a pen with or
    without a cap" statement, which is enlightening. Let's follow where that
    leads.

    Suppose you have as your goal to design a Pen object that will
    be used by hundreds of companies worldwide. So let's say you do something like
    this:


    public class Pen {

    public void write(final String message) {
    //...
    }

    public Cap getCap() {
    //...
    }
    public float getInkCapacity() {

    }
    public boolean hasShirtClip() {

    }
    public Color getInkColor() {

    }
    public float getInkRemaining() {

    }
    public boolean isDisposable() {

    }
    }

    (This, in case you can't tell, is a very contrived example, but roll with me for
    a bit.) So I come along, looking for an already-built Pen object I
    can use. I see this one, which seems to have rather a lot of methods on it.
    "Gee," I think, "this feels a little heavyweight. I wish it were pared down so
    it better plugs in to my problem." So I call you up, and we agree that maybe we
    can remove some of the properties of your Pen object to make it
    feel less heavyweight, and make it less tied to the domain of Pens That Have
    Shirt Clips and Ink, and more generic (and hence more usable across
    domains).

    First, we remove the getCap() method, because a pen is a pen
    without a cap. Then we remove the ink methods, because not all pens have ink
    (feather pens come to mind, as do calligraphy nibs). Finally, exposing some
    features on the Pen object as booleans is a little overkill,
    because where do you stop (should you add methods like
    isMadeInFrance()? So why encode disposability as a
    boolean)?

    So now we're left with this:

    public class Pen {
    public void write(final String message) {
    //...
    }
    }

    "Great," I think, "now I have my reusable Pen object. I'll just
    subclass it and add in the collections of attributes that I need. As it turns
    out, hmm, I actually do need ink-related attribtues [let's say] so I'll
    just subclass the thing." So I do this:

    public class InkContainingPen extends Pen {
    public Color getInkColor() {
    //...
    }
    public float getInkRemaining() {
    //...
    }
    public float getInkCapacity() {
    //...
    }
    }

    Now I decide that my domain requires that Pen objects in it need to
    be able to answer questions about their price. So...hmm. So I do some more
    subclassing, beginning to get that bad feeling like maybe composition somehow is
    a better approach, but not yet doing anything about it:

    public class PrestigiousPen extends InkContainingPen {
    public Money getPrice() {
    //...
    }
    // And no prestigious pen is capless...so we'll just throw that in here
    // too. Hmm. This is getting messy.
    public Cap getCap() {
    //...
    }
    }

    Now that I've created this mess, I step back and pause for a minute, because I
    know I've done something bad. I decide to spend some time thinking abstractly,
    as ill-advised as that may be. :-) What I recognize is that really
    the only "necessary" property of a pen is that it is able to write. And, now
    that I have destroyed my own self confidence by creating this evil inheritance
    hierarchy, maybe I'm not even so sure about that. Gee, figuring out what
    properties are necessary for a pen to be a pen turns out to be kind of
    difficult.

    Now I've really done it. Now I don't know what I know any more.
    Abstract thought sure does get you into some nasty situations! Well, one thing
    I do know is that the ink-related methods seem to go together in some
    sort of fundamental way. They are kind of a collection of related properties,
    if you will. And the money related methods (OK, there's only one in this
    ridiculous example; pretend there are many) go together as well. Another
    collection of attributes.

    Hey, what if a pen in any given domain is simply a collection of these
    collections of attributes, and nothing else? Hey, then I could use composition
    instead of inheritance, and as my poor, feeble brain comes up with new
    attributes that Just Have to Belong to a Pen I can graft them on after the fact
    instead of having to refactor, or rejigger inheritance hierarchies.

    So I do something like this instead:

    public class InkFacet {
    public InkFacet(final Pen pen) {
    super();
    //...
    }
    public Pen getPen() {
    //...
    }
    public Color getInkColor() {
    //...
    }
    public float getInkRemaining() {
    //...
    }
    public float getInkCapacity() {
    //...
    }
    }

    ...and this:

    public class PrestigeFacet {
    public PrestigeFacet(final Pen pen) {
    super();
    //...
    }
    public Pen getPen() {
    //...
    }
    public Money getPrice() {
    //...
    }
    }

    public class CapFacet {
    public CapFacet(final Pen pen) {
    super();
    //...
    }
    public Pen getPen() {
    //...
    }
    public Cap getCap() {
    //...
    }
    }


    Now whatever you do to your Pen object I don't care about because I
    can just graft on my facets as I need them.

    Actually, I come to realize, these facets don't have anything to do with pens
    at all, necessarily. They're just collections of attributes, after all, and
    they could be part of the total description of any sort of object. So:

    public class PrestigeFacet {
    public PrestigeFacet(final Object substrate) {
    super();
    //...
    }
    public Object getTheThingThisCollectionOfAttributesIsAbout() {
    //...
    }
    }

    ...or, perhaps a little more concisely:

    public class PrestigeFacet {
    public PrestigeFacet(final Object substrate) {
    super();
    //...
    }
    public Object getSubstrate() {
    // replaces the getTheThingThisCollection... method
    }
    }

    Now I realize that these facets actually have nothing intrinsically to do with
    my domain at all. That is, they aren't trade secrets, they don't necessarily
    describe pens (the InkFacet could describe bottles of ink, or a
    warehouse that sells boxes of ink, or a printer. A CapFacet could
    describe a baseball player. So why are they in my codebase, and not
    yours (where "you" are the Place Where Reusable Software Comes From)? So I call
    you up and I say, hey, I have these collections of attributes that can describe
    lots of things. How about putting them in your codebase? And you do, and my
    code now becomes much more about reusing your stuff than it is about my
    stuff.

    The fun (for me, anyway) part of this insight is realizing how much in common
    it has with philosophy and metaphysics. Hence the John Locke reference; I loved
    the fact that this brilliant man was reduced to calling
    the-thing-that-attributes-stick-to an "I Know Not What". Java would call that
    an Object. What do they have in common? If you read more of
    Locke, he will tell you that substrates--the things attributes stick to that you
    can't describe--are basically all characterized by taking up space at a
    particular set of moments in time. That, of course, is exactly what an
    Object does as well.

    Posted by: ljnelson on September 15, 2004 at 09:44 AM

  • I Know Not What?
    ljnelson, No apologies, Sir. Rather I should apologize because my words were
    a little bit harsh as they came out of frustration to understand the gist
    of this article. No hard feelings. And by the way, nice touch with the "Pen"
    :-)
    Back to the "facets" now. Facets are needed when we need to modify or
    control the behavior of an object. Facets always expose a "subset" of
    the actual object (to continue speaking "abstractly" lets refer to this as
    IKnowNotWhatObject). The fundamental rule of Facets is that they are
    independent on their own. Meaning, they don't know anything about the actual
    object. So, the meaning of IKnowNotWhatObject basically from the Facet's
    perspective - a facet does not know and does not care what object has this
    facet.
    Applying facets to achieve "composition" in the unnatural way seems to be
    pretty much like an antipattern. I disagree with the implementation
    choice of passing the IKnowNotWhatObject to the Facet's constructor. That
    it goes against the nature's way which is a Pen has Ink, Cap etc. The
    examples above reflect the exact opposite -- the cap has a Pen! So a pen MUST
    know about what facets it has. Otherwise it is not usable in the first place.
    Facets employ the principle of least authority via interface oriented
    programming to promote the "capability" oriented frameworks. So they are found
    in implementations of aspects like security, persistence, auditing etc. It is
    unfortunate that we don't come across them not as frequently as we should.
    Also from my personal experience that data representation centric
    reuseability is much less frequent and doesn't add much value when compared
    to reusing the behavior. More over it adds more than many layers to access
    the data and results in IKnowNotWhat style code.

    OO Father, forgive them for they know not what they do
    For, disregarding what is "I Know Not What", loving meaningless composition
    instead of you.

    So, facets need to be like this.


    public interface Facet1{ void foo();}
    public interface Facet1{ void bar(Blah blah);}
    public interface Facet1{ Yada fubar();}

    public interface ActualInterface extends Facet1, Facet2, Facet3 { Something someFunctionalityOfItsOwn();}

    Posted by: javampire on September 16, 2004 at 09:19 PM

  • Easy to use little things?
    ljnelson, No apologies, Sir. Rather I should apologize
    because my words were a little bit harsh as they came out
    of frustration to understand the gist of this article. No
    hard feelings. And by the way, nice touch with the "Pen"
    :-)
    Back to the "facets" now. Facets are needed when we need
    to modify or control the behavior of an object. Facets
    always expose a "subset" of the actual object (to continue
    speaking "abstractly" lets refer to this as
    IKnowNotWhatObject). The fundamental rule of Facets is that
    they are independent on their own. Meaning, they don't know
    anything about the actual object. So, the meaning of
    IKnowNotWhatObject basically from the Facet's perspective -
    a facet does not know and does not care what object has
    this facet.
    Applying facets to achieve "composition" in the
    unnatural way seems to be pretty much like an antipattern.
    I disagree with the implementation choice of passing the
    IKnowNotWhatObject to the Facet's constructor. That it goes
    against the nature's way which is a Pen has Ink, Cap etc.
    The examples above reflect the exact opposite -- the cap
    has a Pen! So a pen MUST know about what facets it has.
    Otherwise it is not usable in the first place. Facets
    employ the principle of least authority via interface
    oriented programming to promote the "capability" oriented
    frameworks. So they are found in implementations of aspects
    like security, persistence, auditing etc. It is unfortunate
    that we don't come across them not as frequently as we
    should. Also from my personal experience that data
    representation centric reuseability is much less frequent
    and doesn't add much value when compared to reusing the
    behavior. More over it adds more than many layers to access
    the data and results in IKnowNotWhat style code.
    OO Father, forgive them for they know not what
    they do
    For, disregarding what is "I Know Not What", loving
    meaningless composition instead of you.

    So, facets need to be implemented like this:

    public interface Facet1{ void foo();}
    public interface Facet2{ void bar(Blah blah);}
    public interface Facet3{ Yada fubar();}

    public interface ActualInterface extends Facet1, Facet2, Facet3 { Something someFunctionalityOfItsOwn();}

    Posted by: javampire on September 16, 2004 at 09:32 PM

  • :-D
    that's a very interesting idea! i think i'm starting to get some picture of how to make use of that. Still need some more time to make it clear, though. Thanks anyway :-D a very nice way of viewing object and managing its attributes to improve code reusing.

    Posted by: maowmaow on September 19, 2004 at 11:10 AM

  • Easy to use little things?
    I'm going to gently disagree with you on several counts.

    You write:

    The fundamental rule of Facets is that they are independent on their
    own. Meaning, they don't know anything about the actual object.

    That isn't really the fundamental rule. The fundamental rule is more like this:
    a particular facet is simply those attributes that your application needs to
    work with; no more and no fewer.

    Next, you write:

    I disagree with the implementation choice of passing the
    IKnowNotWhatObject to the Facet's constructor. That it goes against
    the nature's way which is a Pen has Ink, Cap etc. The examples above reflect the
    exact opposite -- the cap has a Pen! So a pen MUST know about what facets it
    has. Otherwise it is not usable in the first place.

    Why does a Pen need to know what its facets are? If your
    application is all about Caps, then write your application in terms
    of Caps. If you need to instantiate a, say,
    Measurements facet, just construct one, and pass the (more or less
    opaque) Pen object to its constructor.

    Next, you write:

    Facets employ the principle of least authority via interface
    oriented programming to promote the "capability" oriented frameworks. So they
    are found in implementations of aspects like security, persistence, auditing
    etc. So, facets need to be implemented like this:
    public interface Facet1{ void foo();}
    public interface Facet2{ void bar(Blah blah);}
    public interface Facet3{ Yada fubar();}
    public interface ActualInterface
    extends Facet1, Facet2, Facet3 {
    Something someFunctionalityOfItsOwn();}

    I'm not sure what you mean, but facets as I have loosely backed into defining
    them are simply collections of attributes that are usable in a given domain by a
    given application. If you want to make them interfaces, you certainly can. But
    you are not obligated to.

    Posted by: ljnelson on September 20, 2004 at 08:11 AM

  • Easy to use little things?
    You are correct. Facet's fundamental rule is: a
    particular facet is simply those attributes that your
    application needs to work with; no more and no fewer.
    And therefore, a Facet doesn't really care about which
    object has that facet. As the user of facet, an application
    object, is only interested what the functionality of facet
    is about.
    Here are couple of lines that may make my point clear.
    The very fact that you are passing the
    IKnowNotWhatObject to the facet constructor, makes the facet
    *aware* of it. And if the application is all about Caps
    then we don't have to think about an object called Pen.
    That is what makes this "abstract" talk a big no-no in
    general application design discussions as it completely
    ignores the problem-on-hand. Take the example for instance,
    we started with "Pen" and now we say we don't have to work
    with pen.Don't get me wrong, you probably are talking about
    another application that only deals with Caps. But that
    application is something that probably *uses* a Cap (or a
    Facet) and doesn't really care about how it is
    constructed.
    If we are really planning to make the *data representation*
    generic, we could program with an object that has only
    a java.util.Map and not worry about Facets either? But, doing so is not prudent.
    So, I just put a couple of templates to make it more reusable. But,
    the real question is what value these *reusable* objects bring
    to an application? Now, one may say, it is a pattern and we cannot
    generalize it like that and it is the *design* that is the reusable
    solution. If so, I agree.

    public interface IProperty <T>{
    public String getName();
    public void setName(String name);
    public T getValue();
    public void setValue(T value);
    }

    public class Property<T> implements IProperty<T> {
    private String name;
    private T value;

    public String getName() {
    return name;
    }

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

    public T getValue() {
    return this.value;
    }

    public void setValue(T value) {
    this.value = value;
    }
    }

    public interface IFacet<S extends ISubstrate> {
    public S about();
    public Collection<? extends IProperty> getProperties();
    public void setProperties(Collection<? extends IProperty> properties);
    }

    public class Facet <S extends ISubstrate> implements IFacet <S> {
    private S substrate;
    private Collection<? extends IProperty> properties;

    public Facet(S substrate, Collection<? extends IProperty> properties){
    this.substrate = substrate;
    this.properties = properties;
    }

    public Collection<? extends IProperty> getProperties() {
    return properties;
    }

    public void setProperties(Collection<? extends IProperty> properties) {
    this.properties = properties;
    }

    public S about(){
    return this.substrate;
    }
    }

    public interface ISubstrate<T> {
    public T self();
    }


    For more information on facets, refer to this
    Wonderful Resource.

    Posted by: javampire on September 20, 2004 at 07:06 PM

  • Easy to use little things?
    Ah; learn something new every day. I see what the source of our misunderstanding is. There is a page on the c2 wiki that is devoted to a Facet pattern. I had no idea (but should have suspected) that someone else had defined the term already. Suffice it to say what Ward and company call a Facet is not what I am defining here.

    Posted by: ljnelson on September 21, 2004 at 05:13 AM

  • Very interesting thread, probably dead now, but I wanted to add my 2c worth.
    If you consider the problem of 'perception' or 're-cognition' along with the facet concept that you outline above, then you have a potentially powerful model.
    Imagine the paradigm (or Universal) symbol for a pen, i.e. what is the general set of qualities that allow us to categorise something as a pen? Plato has the concept of the 'ideal form' of which the earthly concrete items are an imperfect reflection. The key thing here, and where I feel it ties in with your facets approach, is that the universal need not exist in reality, yet can be exemplified by the combination of facets.
    If the facets are arranged into substrates the 'pen' concept becomes the collection of facets (as you say). Perception of a 'Pen' as opposed to a 'Pencil' then becomes the collection of a marginally different collection of facets. As Cognitive Psychology studies have shown, the perception is highly influenced by language and some cultures may not have a word (or different categorisation) of Pen and Pencil (or indeed any notion of either!).
    This is obviously a huge topic, but I'd be more than happy to discuss it at length if anyone's interested. My final year thesis in my Computing degree in '88 was along these lines, but I never found anyone who quite 'got' what I was talking about.

    Posted by: pjardine on April 21, 2005 at 03:54 AM





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