Re: Self-containment in OO



Daniel T. wrote:
Garrett Smith <dhtmlkitchen@xxxxxxxxx> wrote:
Daniel T. wrote:
Vladimir Jovic <vladaspams@xxxxxxxxx> wrote:

Do you recommend Riel's book to improve OO design? I found this on
the net:
http://lcm.csa.iisc.ernet.in/soft_arch/OO_Design_Heuristic.htm
(summary of OO design from Riel)
Yes, I recommend it highly.
I see:

| 2. Users of a class must be dependent on its public interface, but a
| class should not be dependent on its users.

What about IoC? What is wrong with depending on abstractions.

From the book:

If a contained object is dependent on the class that contains it,
then it is not reusable. If the card reader of an automatic teller
machine has knowledge that it is contained in an ATM, then it cannot
be taken out of the ATM and used to build a security door...



Thanks you for the clarification and elaboration.

Is the conclusion in the first sentence is strongly supported by the rest of the paragraph?

The rest of the paragraph misses a more obvious point: Why paint yourself into a corner with tangled design as tight coupling?

Arguments about the security door are going to seem like far fetched theoretical paranoia to a project manager who is commissioned to a project regarding ATM cards and won't likely have much influence.

The Card's implementation details depending will result in confusing code in the Card. Such coupling might cause problems when a new ATM vendor comes on the market (different host environment). Addressing those problems is going to cost money and having everybody in a mad scramble trying to make things work in the new version or make of the ATM when it is released.

This sort of thing is unfortunately too common with javascript for the web. Programs are often tied to proprietary (mis)features of a particular host environment (browser).

Then when "it doesn't work", you end up seeing code like:

| <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" >

The sad thing is that most of the "cross browser" javascript libraries that you'll see suffer from these avoidable problems.

Implementation code is also often tied with details of a javascript library. The jQuery javascript library, for exmaple, provides methods that are very complicated and loosely defined. When they change, it tends to "not work" for the user going through an upgrade.

When a contained object must send a message to its containing class,
then the containing class should be made more general through
judicious use of inheritance. In this way, the contained object does
not depend on the containing class, only on its base class. It is
easier to require a reuser to inherit from some abstract class than
to use a particular class (effectively ruining any chance of reuse
outside of the original domain).

OK.

In other words, there is nothing wrong with depending on abstractions, there is something wrong with depending on concrete types.


Right.

| 18. Eliminate irrelevant classes from your design.

Only classes? What about methods or even statements?

Dead code makes the code harder to read and hides bugs.

The heuristic that covers methods is: "Do not clutter the public interface of a class with things that users of that class are not able to use or are not interested in using."


Right.

As for statements, the book is
aimed at Object-Oriented heuristics, not general programming heuristics.


OK.

Now you might wonder why two different heuristics? The answer is due to the difference in granularity and reusability. In order for a class to be reusable, it often must provide methods that not all users use. (For example, there are many methods on your typical container class that may never be used in any one particular context, or even in an entire
program, but they are used by some of their clients.)

Sounds cluttered.

I try to get maximum reuse out of each module. Who wants to use a module that is largely irrelevant? Regarding code that must be downloaded before being interpreted, certainly the user does not!

However, an
"irrelevant class" is defined in the book as a class that has only the standard complement of methods that all classes are expected to implement (as per heuristic 4: "Implement a minimal public interface that all classes understand.") Such classes have (almost literally) no functionality within any system.


I see. But what if someone *is* genuinely interested in using that interface? What if, for example, an interface is defined and then an implementation implements all of those methods in a specific way such that other implementations would find irrelevant? What about State or Strategy, for that matter?

For example, an interface with a "blendTo" method that acts as a strategy. Color transition is implemented in a way that would make no sense to the transition for length, yet ColorTransition and LengthTransition have identical interfaces, making them both redundant.

| 37. Derived classes must have knowledge of their base class by
| definition, but base classes should not know anything about their
| derived classes

NO abstract classes? If an abstract class has two methods, m1 and m2,
m1 calls m2, and m2 is abstract then it must be implemented by the
subclass. That seems to violate this principle.

Here there is some confusion about what the "knowing something about" means:

If base classes have knowledge of their derived classes, then it is
implied that if a new derived class is added to a base class, the
code of the base class will need modification.
Riel goes on to specifically address the use of polymorphism to avoid these sorts of issues. In other words, your example does not violate this heuristic, rather it is a method for avoiding the violation of this heuristic.


I see. I think the problem is his terminology "no knowledge". Obviously, a superclass that is designed to be such knows that it has a subclass (a subclass has knowledge of its superclass should go without saying).

Reil is not capable of describing exactly what it is that is a problem from which he has derived his badly written principle.

A more suitable principle, IMHO:

Do not rely on implementation details or other side effects of an object - code to the interface (as above).

More concretely:

class Base {
virtual void foo() = 0;
public:
void bar() {
foo();
}
};

The class above depends only on its own interface, it does not depend on the interface, or implementation of any derived class.


Right. *That* makes sense.

I agree with a lot of what is written, though it seems a bit rough.

The heuristics alone as a bald list do seem a bit rough, but you have to remember there is an almost 400 page book that goes along with them. Also, keep in mind, the book was written in 1996 when people were new to OO. Now, some of the heuristics are things that are an ingrained part of the community.

Ah, if only it were true with javascript community. Take a look at, for example, Dojo or MooTools.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
.



Relevant Pages

  • Re: Self-containment in OO
    ... | class should not be dependent on its users. ... When a contained object must send a message to its containing class, ... not depend on the containing class, only on its base class. ... aimed at Object-Oriented heuristics, not general programming heuristics. ...
    (comp.object)
  • Re: Unification of Methods and Functions
    ... I am suggesting that we write factory methods using classmethod to give ... my classes all implement an interface which I'll call 'shape ... Rectangle and Ellipse have a common base class, ...
    (comp.lang.python)
  • Re: Alternative to Interface?
    ... >> this method to the interface and all involved classes. ... > implementation provided by the base class itself. ... > declare it as Overridable instead of MustOverride, ... that functionality will instead be placed into an existing method. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Dynamic type convertion..
    ... common interface (or abstract methods/properties), ... implemented in the base class or as separate interface. ... you can cast to that base class or interface. ... you can access these methods/properties directly. ...
    (microsoft.public.dotnet.framework.remoting)
  • Re: Abstract class or interface?
    ... I try to make the decision based on the relationship of the derived class to the base class. ... If the derived class "can act like" the type of the base class, I'd lean towards an interface. ... I understand the abstract class can have implementation in its methods and derived classes can only inherit one abstract class. ...
    (microsoft.public.dotnet.languages.csharp)