in reply to Constructor/Factory Orthodoxy

If I have read you right then your base class has foreknowledge of your subclasses. The reason being you can either instantiate the sub class or pass a parameter to the base class and it decides what class to give you.

Assuming this is correct:

This would be my reason why you should avoid putting your base class and your factory in the same class. The purpose of a class hierarchy, in my opinion, is that if you were to line them up (single level for simplicity):
A (base) | B inherits | C inherits
Then as you go down the chain, you should be adding functionality and your classes become more *specific*.

Each class should have knowledge of its parent(s) but surely have none of its children? Your structure requires that the base class has knowledge of all classes that inherit from it (and possibly, its deepest descendants <-- though I doubt it).

I would argue that you need to think deeper regarding why you would want to merge a factory and your base class together. IMHO its better to have a separate factory that has 'knowledge' of the chain in question and can 'do the right thing'.

Of course, YMMV as it depends on your class hierarchy. I've only done horizontal class factories:
A | +---+--+---+---+ B C D E <---------- Factory picks b,c,d or e
Whereas yours looks like:
A (base) | B -+ | | C |-- Factory can handle the chain (only B and C shown) -+
But thats another story ;).

Replies are listed 'Best First'.
Re: Re: Constructor/Factory Orthodoxy
by dws (Chancellor) on Feb 26, 2003 at 00:57 UTC
    Your structure requires that the base class has knowledge of all classes that inherit from it (and possibly, its deepest descendants <-- though I doubt it).

    The way around this is to have subclasses register with their parent class. Then, the parent consults a registry before instantiation a class, rather than hard-coding knowledge of the class hierarchy.

      Hmmm. I can see the technique but frankly I'd have to see some good uses of it before being convinced. Have you put this concept to use (or at least seen it done well)?

      Given your technique I'd be just as inclined to say you could do the same with a factory class and keep the two apart.

      What is your opinion of the two?
        I can see the technique but frankly I'd have to see some good uses of it before being convinced. Have you put this concept to use (or at least seen it done well)?

        I first saw this technique used to handle multiple "look and feels" when drawing widgets. You would ask the factory for a new scrollbar, it would consult a policy object, which would tell it what (available) class to use, and the factory would hand back a new instance of whatever type the policy object said to use.

        I've also used a similar technique when building "plugin" mechanisms. At startup, the application reads and initializes a set of plugins, each of which inherits from Plugin. At initialization time, each plugin registers itself with Plugin. Plugin provides factory methods, a query method that hands back the names of all registered plugins, and a mapping of plugin name to plugin instance.

      Why not have the Factory maintain the registry and keep the two separate? The programmer who comes after you will bless you continuously. (If you don't, expect curses.)

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        This is what you were referring to earlier by Manifest, correct?

        Matt

Re: Re: Constructor/Factory Orthodoxy
by mojotoad (Monsignor) on Feb 26, 2003 at 05:23 UTC
    Your assumptions were indeed correct (I updated the root node in an attempt to clarify). :)

    Your explanation of why Base classes should know nothing about their subclasses is convincing -- this has a ring of clarity and simplification to it that sounds compelling.

    As others have mentioned elsewhere in this thread, there seems to be room here for a registry or manifest for children classes -- I think this is also an interesting approach that does not bleed knowledge of subclasses into their respective base classes, so long as the interface for the subclasses are the same.

    BTW, the factories I had in mind were "horizontal" as you describe them (Gump and Wump were sibling subclasses of Bubba).

    Thanks for your informative response,
    Matt

Re: Re: Constructor/Factory Orthodoxy
by steves (Curate) on Feb 27, 2003 at 06:12 UTC

    The parent/child knowledge issue sometimes is worth violating IMO -- again in conflict with standard OO. This may not have any bearing on this particular problem but one instance where I found it fits perfectly:

    • I have a set of file classes all derived from a common base class. Each file class represents a file accessed via some different transport (e.g., ftp, http, rsh, ssh).
    • Each file class in turn has a directory class. A directory is just a special type of that file, so it has all the file methods plus some add-ons only directories can do.
    • At construction time, all the caller knows is the file name. It's during construction, when the actual filesystem (or whatever) is consulted that knowledge of a directory arises.
    • If a file does find out it's a directory during construction, it simply morphs itself into its directory subclass by re-blessing itself into that class.

    I like Perl's ability to elegantly address that pattern when it makes sense.

      I had a think about your example and I think that its reasonable to do something like that. I think I'd probably do the same.

      However, I have been trying to think about how to get around your problem without doing this (purely for academic purposes) and the only thing I could think of was a variation on the Decorator pattern? Even then I'm not sure ;)

      Its nice that Perl has this flexibility, I am curious as to how this would be done in a statically typed language such as Java or if you wanted to practise a 'purer' OO approach.

      Again, purely for academic reasons.

      SP
      re-blessing doesn't mean you violate parent-knowledge behavior. In fact, Policy, Manifest, and/or Factory classes would be a better way of doing this.
      1. Create a file object.
      2. The file object, during construction, finds out it's a directory.
      3. The file object will then either:
        • Ask the Factory to for the classname to rebless to
        • Give itself to the Factory and asks to be reblessed
      The factory or policy or manifest should be the one that maintains that knowledge and how to transform.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.