Saturday, January 19, 2008

Rules vs. Overriding

In "Object Thinking" by David West, it appears that there are two main ways of making two different objects that respond to the same message react differently to those messages.

The first is using polymorphism but that necessitates two different classes. The other is making sure that the two objects will execute different rules when responding to the message.

There is a third way that I'm not going to go over in this post; it's when two different objects have different state and react differently because of their differing state.

The author discusses good and bad specialization on page 79. I can't say that I am sure I know what the author is talking about. If I take his words in their most literal sense, I get the following statements.

1. Any time one class derives from another, it is assumed that the subclass is a specialization of the superclass.

2. Specializing by extension means only adding methods but never overriding methods. This is the good kind of specialization because it preserves the substitutability of subclasses for superclasses.

3. Specializing by constraint (overriding a superclass' method) almost always results in a "bad" object because now you have to be concerned about how an object does something not just what it does.

4. The exception in the footnote is that there will be some methods introduced high in the inheritance hierarchy that are designed to be overridden by subclasses and how the method does what it does is unimportant.

Given that there are two ways of making two different objects react differently to a message, how do you pick between the two ways? Is one way preferred in general?

Let's say I'm doing some Object Discovery and definition of a Customer class. From the domain experts I've found that there are two kinds of customers customers with discounts and customers without discounts. Having a discount makes the payment calculation different but no additional behavior is added (for argument's sake). If a Customer object can be given a discount or their discount can be revoked, then modifying the Customer's rules would be better than recreating the Customer as a CustomerWithDiscount or vice versa. Perhaps the GoF's State Pattern would also be a good solution here.

Let's say that I'm doing some Object Discovery and definition on some classes that represent various shapes in a drawing software package. In this case it seems most fitting to use polymorphism for differing the way that the shapes draw themselves. The reason it fits better sounds a lot like the exception listed in the author's foot note.

Perhaps the reason that rules sound more natural for the Customer object is because it avoids us creating a subclass for every different kind of payment calculation (e.g. CustomerWithDiscountAndGoldMembershipAndOutstandingBalance). In this case the rules approach is superior to even the State Pattern because you'd have to have a separate state class for each different method of payment.

It looks like I need to read up on the author's thoughts on inheritance...

No comments: