3

I'm writing a database interface in PHP and I have a base dbTables class, as well as a base dbTableFields class.

dbTables has a function, getFields(), that instantiates dbTableFields objects, each of which carries essential data on each table field, and puts it into dbTableFields->fields=array();

dbTables has several children.

Now I've realized that the children need to use different versions of getFields(). But they only differ in one place: they need to instantiate dbTableFields children, rather than dbTableFields objects.

I've solved this problem. I took advantage of PHP's ability to use variables to represent class names. All I had to do was, in dbTables->getFields() replace:

$this->fields = new dbTableFields();

with

$this->fields = new self::$field_model();

Where self::$field_model = 'dbTableFields'; // string value for class

Now, in the child classes, I just have to override the $field_model property with the name of the appropriate dbTableFields descendents.

Is this parallel inheritance scheme good form? Or am I creating an uncompromising mess? Is there some more-elegant and more maintainable method for achieving the same effect?

3
  • 2
    My spider sense is tingling, but I can't pinpoint what's wrong here. You should post your full code on Code Review Stack Exchange, our sister site for peer reviews of working code, to get the full Stack Exchange experience ;)
    – yannis
    May 5, 2012 at 12:35
  • @YannisRizos Calling functions/classes by way of stored name like that isn't a good thing, without very strict guidelines. Some of my co-workers tried it out a several years ago before I started there, and that section of our system has become a horrible mess of spaghetti code that they no longer understand. I spent months figuring it out and am now slowly converting it to something more sane.
    – Izkata
    May 6, 2012 at 0:24
  • 1
    After working on this code for a few more months, I have to say that I agree with @Izkata. That part of the system is very fragile. Rather than refactor it, I've ended up creating new classes to handle the same data, and left the old ones in place for use in the scripts that already work. Aug 13, 2012 at 7:58

2 Answers 2

3

The principle you want is to "favor composition over inheritance." This is a fairly classic example of where the strategy pattern would be useful: separate your "getFields" logic into several FieldStrategy objects, and reference the appropriate one for your parent and your children.

I'm not explaining this very well, but please google "strategy pattern" and play with it.

2
  • Would you suggest a FieldStrategy class, where the __construct() takes arguments that set the field strategy? And then each class that needs a FieldStrategy can set its own version of the class? Aug 13, 2012 at 8:02
  • Yes, that sounds right. Aug 13, 2012 at 11:41
1

NO, usually.

Parallel inheritance hierarchies are bad smell in code.

I have heard that Martin Fowler indicated this as a code smell in his famous book "Refactoring : Improving the Design of Existing Code".

However, it is not something absolute. Sometimes parallel inheritance hierarchy may be the best design among the alternatives your team could come up with.

Google with "Parallel inheritance hierarchy". Who knows better design may pop-out!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.