Showing posts with label rules. Show all posts
Showing posts with label rules. Show all posts

Saturday, January 19, 2008

Random Thoughts and Questions

Some random thoughts and questions....

If two objects of the same class have different rules, how did they get those different rules? Was there some object factory that gave them different rules? If other objects modify an object's rules, is that a violation of encapsulation? If an object is the only entity allowed to modify its rules, that means that it must know about all possible rules it can have within the domain. For some domain types (e.g. account types) where there is a closed set of kinds, this might not be a bad idea. For open ended domain types (e.g. widgets) this could not possibly work.

In the case of the Customer class, what would be involved when giving a Customer a discount? We certainly need to specify and store the amount of the discount. But do we also add a rule to the class? Or was the rule there all along waiting for a discount attribute to be set? Since rules may operate on attributes, it's important to keep them in sync. If you have a rule that expects a discount attribute but no discount attribute is in your object's Description Object, your rule will fail or misbehave.

Also it seems like a Description Object might encounter name collision issues. Perhaps there should be namespaces within a Description Object?

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...