From: Thomas Kowalski on
Hallo Rick,
thanks for your answer!

> Might I suggest a little ooa/d before you go into technical
> refactoring like this ?

Yes, you might :) Although I am programming already quite long, I never
really tried to explore the concepts of OO enough it seems. Most of my
code looks like ugly c-style code. Therefore I am trying now to grasp
as much of the "real" OO as possible with the goal to make my code more
easy to understand.

> If you have huge classes probably your problem
> domain is insufficiently analysed and their is not sufficient "domain
> language" to talk about different use case realizations of your
> software. In code that shows like a few monsterous classes or like
> a few monsterous classes delegating everything out( facades).

Well, the software I am currently working on is settled in computer
graphics. It's a high performance calculation software. Therefore some
concepts of business OOA/D are difficult to apply for me.
Basicly I am working on the assumption that an object encapsulates the
methodes to manipulate itself, with might be not really right on second
thought.

> You might miss the whole point about inheritance/delegation.

I guess you are right. I treat inheritance like a way to add
functionality to a class and "group" it this way.

> Instead try to concentrate on behavior first( or as you call it functionality)
> Attributes/aspects should not drive design but should be encapsulated
> , and that encapsulation is a driving force of your design.

The way I understand this is: Instead of (over)-using inheritance and
delegation rather try to create a seperate class managing the
additional functionality. Is that correct?

> Mixins is a nice implementation certainly when you have clients who
> only receive one of the mixins instead of the whole monster.

Basicly I want to use it to provide a way to safe memory ressources in
case application that base on a similar datastructure are merged to one
application. This way "customized" classes can be created and "boxed"
on the former border between the two applications.

Regards,
Thomas Kowalski

From: H. S. Lahman on
Responding to Kowalski...

> recently I was thinking about the concepts of delegation and
> inheritance.
> My idea was to simplify huge classes by dividing them in a base class
> and additional class that provide other attributes / aspects /
> functionality. This way it would be possible to create small
> customizable classes easily and reduce complexity. Since I am using C++
> most of the time multiple inheritance is no problem and different
> "mixes" of aspects could be realized.

While inheritance and delegation are often used together, such as in
most of the GoF Design patterns, they are quite different things.

Inheritance is simply a <rather simple> set of rules for determining
what properties a particular member of the root class actually has.
That is very handy for generalization/specialization where the same
basic entity can come in different flavors that have a few unique
properties. OO subclassing and inheritance are defined in a manner that
also allows polymorphic access of the /common/ properties. However, a
member of every leaf subclass is always a member of the root superclass,
hence the appellation is-a.

Delegation, OTOH, is used to decompose a complex problem space entity
into multiple distinct component entities. The component entities are
identifiable in their own right because they exist at a lower level of
abstraction than the original entity. Thus the notion of a Car can be
decomposed into components like Wheel, Body, Drive Train, etc. that are
not cars.

Thus when one looks at a pattern like Strategy,

* R1 1
[Context] ------------------ [Strategy]
A
| R2
+--------------+-------....
| |
[StrategyA] [StrategyB]

The delegation lies in the fact that a Strategy was decomposed from
Context so that it is a standalone entity related to the original
Context through a simple association. (If [Strategy] were not
subclassed, one would still have delegation at this point.) One then
subclasses [Strategy] to provide somewhat different behavior
implementations in different situations. (I.e., the GoF pattern is
solving a more complex problem of dynamic differences based on run-time
situation.) Inheritance and polymorphism then allow those behaviors to
be accessed the same way, regardless of which implementation of the
behavior is relevant in a given situation.

In this case the same basic behavior is always accessed; only the
implementations change. So that behavior is a common property of all
[Strategy] members. That is quite different than using subclassing
directly to define disparate components of [Context].

IOW, the acid test of any subclassing relation is that it should be
quite clear a member of any leaf subclass is a member of the root class
(e.g., a StrategyB is a Strategy). However, the delegatee (Strategy) is
not a delegator (Context) because the level of abstraction has changed
where we view what a Context is; Context is now essentially a conceptual
container of standalone components.

>
> Is such a concept basicly a "good" idea? If yes, should it be realized
> using delegation or inheritance? I have already read about the LSP, but
> are there any other guidelines then to use inheritance and then
> delegation? Last one is really tedious to implement and don't
> necessarily reduce complexity (since the methode stubs are still part
> of the code). On the other hand inheritance is a pretty strong
> relationship.

Whether it is good or bad depends upon whether delegation is being
/combined/ with subclassing. If so, it is bad; if not, it is just
subclassing. (As Freud said, sometimes a cigar is just a cigar.)

LSP is really an issue for polymorphic dispatch. In the OO context one
can provide different implementations for the same superclass property
semantics. If one accesses the superclass property, one needs to ensure
that those implementations are acceptable to the client's expectations
for the superclass property semantics across all subclasses. (Note that
if one only accesses leaf subclass members via direct relationships,
then LSP does not matter because one always goes directly to the
implementation the client expects.)

>
> Another occurance that let me thing about that problem is corba, there
> two different approaches are used to create proxy objects (tie =
> delegation and interfaces = inheritance). Is there any reason to use
> ties, beside the fact that java doens't support multiple inheritance?

I don't want to go here because it ("canned" interoperability and
layered model infrastructures) is a controversial topic in OO; I
consider many of then to be object-based, not object-oriented.

[I am going on vacation so if you respond to this my response will be a
tad tardy.]


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: Daniel T. on
In article <1154599408.592501.29750(a)b28g2000cwb.googlegroups.com>,
"Thomas Kowalski" <th-ko(a)gmx.de> wrote:

> recently I was thinking about the concepts of delegation and
> inheritance.

In a statically typed language, like C++, public inheritance does double
duty. It is used to share implementation and it is used to statically
determine if types are substitutable.

When we actually *use* public inheritance for both jobs, we can have
conflicts. For example, in the engine I'm using right now the Graphic
class has something like 80 bytes of data that must be maintained. It is
often the case that such data ends up being redundant because it must
also also held in some delegate that my sub-class contains. However, I
must inherit from Graphic and I can't remove the member-variables in
question. This is a poor design, but one I think shows up often in C++
programs.

> My idea was to simplify huge classes by dividing them in a base class
> and additional class that provide other attributes / aspects /
> functionality. This way it would be possible to create small
> customizable classes easily and reduce complexity. Since I am using C++
> most of the time multiple inheritance is no problem and different
> "mixes" of aspects could be realized.
>
> Is such a concept basicly a "good" idea? If yes, should it be realized
> using delegation or inheritance?

Yes, I think it's basically a good idea. When you have a class with
non-communicating behavior, you should break it up into delegate classes
that each do a more refined job. IMHO, despite the inevitable delegation
involved, this will simplify the design.

As to your second question, things are a bit tougher on C++ developers
because of the double duty issue I mentioned above. Much depends on how
reusable the code you're working on needs to be. The more extensively it
is used, the more likely the implementation/interface split will cause
problems.

One heuristic I use is that if a class is being derived from, it should
contain no data. This way, my objects don't need to lug around a bunch
of data they never use. So how do I remove duplication? That's where
delegates come in...

> I have already read about the LSP, but
> are there any other guidelines then to use inheritance and then
> delegation? Last one is really tedious to implement and don't
> necessarily reduce complexity (since the methode stubs are still part
> of the code). On the other hand inheritance is a pretty strong
> relationship.

All the delegation that goes on in OO code does take a bit of getting
used to. As I recall, Martin Fowler once said something about people new
to OO complaining that nothing seems to ever do the job, most functions
just seem to delegate the job to some other function.

I think all the delegation does reduce complexity, because (assuming the
member-functions are named well) you don't have to trace down the
delegation hierarchy to "figure out what the function does." But yes, it
tends to be tedious to implement. Indirection in general is tedious to
implement, but that's what we need to do to gain flexibility.
From: Sasa on
Thomas Kowalski wrote:
> Hi Sasa,
> thanks for your reply! Maybe you can eleborate the answers a little bit
> more?

You're welcome. I'll try, and if it's still not enough, don't hesitate
to ask.

>>a) Is there a code which works with base class interface?
>
>
> If the dividing in base and derived class simplifies the understanding
> of the concept the class represents, when why not using it?

You also have delegation at your disposal. Consider following situation:
- class A has set of methods S1
- class B derives from A and adds its own set of methods S2

Now B offers all methods. However, if interface of A changes, then it
might introduce breaking changes to the clients of B.

IMHO if one wants to create class with big interface, then it amounts to
Facade pattern - make one class with all methods relevant to the
interested clients. Make it delegate to each class. The fact that the
work is subdivided in classes is implementation detail.

One should IMHO avoid classes with big interfaces. Small classes with
small interfaces should usually suffice.

>>b) Can that code work with my derived class?
>
>
> This is basicly the LSP, isn't it?
>
>
>>c) Can my derived class work with base class methods? I.e. if I invoke base
>>class method, will something unexpected happen because my derived class
>>doesn't count with it.
>
>
> Seems to be something like LSP, too.

The way I understand LSP, a/b/c cover it, maybe a most of all.

>>d) Did I override anything in derived class?
>
>
> Why this is important? If you just add functionallity, doesn't it
> justify the use of inheritence?

To restate the issue raised earlier - when you inherit, you get a whole
lot, maybe even too much. You receive the entire interface of the base
class, and access to its protected members. The question is - do the
clients of your new class really want that?

Another issue: if you add functionality via inheritance, the added
functionality applies only to the derived class. But since you are not
overriding, you really don't change the behavior of the base class, you
only add new features. However, even though your code might work for all
instances of base class, you miss this opportunity if you use
inheritance (because everyone who want's to use new feature might derive).

Example:
In .NET WinForms you have the TextBox class which represents simple edit
box control. Now let's assume that I must add feature that every time I
enter a character a beep must be heard.
One way could be to implement BeepableTextBox by deriving from TextBox.
However, if I do that, every user which wants to have this feature must
use BeepableTextBox.
But what if I have another derivate - MaskedTextBox which accepts some
kind of masked input? How can I make MaskedTextBox beepable? How can I
make BeepableTextBox masked (considering that multiple inheritance is
not supported)?


To generalize: let us say you wan't to extend the class A with some
behavior (and not change the behavior of the class A). You can do following:

a) Static helper method - the method which takes the instance of the
class A, and additional arguments, and performs operation on the base class.

b) Holding the instance of the class A in your wrapper (adapter) and
making your implementation delegate to the instance of A.

>>...you have more access to class members.
>>However, this has its darks side - the clients of my (derived) class are
>>completely unshielded from the specifics of the base class.
>
>
> Not if you declare the members private instead of protected. Which
> might be most usefull if just few or none members of the class is
> overridden.

I agree that visibility should be as minimal as possible, ideally
private (another one of many of my sins was making members protected,
because "some derivate might want to access them someday" - looking back
on that, all I can say is: LOL)

However, I was making general point. E.g. if I inherit from the TextBox
class (which I didn't write, and have no access to its source code), I
will receive protected members.

>>Nowadays, I am more fan of the delegation approach, even if it is somewhat
>>tedious.
>
>
> What caused the shift in attitude?

The example I gave above is simplification of the real situation my team
had. We had couple of features which we added via inheritance, and it
seemed cool, we were inheriting, and inheritance is very OO. At the end
when we had to combine those features, we ended up having inheritance
level of about 7-8 (!), it was very hard to maintain, analyze and debug.
The paradox is that most of the clients needed only couple of those
features (i.e. only subset, but different clients would require
different subsets).

But it is not just one example. Many times have I inherited to add
functionality (and not to override, which is actually changing the
implementation). And looking back on that code (which I do every now and
then), it really seems clumsy to say the least.

>>I regard inheritance vs. delegation as having two different purposes: in
>>inheritance, we reuse the interface and provide our own implementation, in
>>delegation we provide our own interface and reuse implementation.
>
>
> I really like this explaination! That really seems to bring it to the
> point :)

I read it somewhere (probably not those exact words, only the overall
meaning), but it's hard to keep track of who sad what, so if anyone
knows the source, feel free to cite.

Sasa
From: adaworks on

"Thomas Kowalski" <th-ko(a)gmx.de> wrote in message
news:1154599408.592501.29750(a)b28g2000cwb.googlegroups.com...
> Hi everybody,
>
> recently I was thinking about the concepts of delegation and
> inheritance.
>
This would be a good opportunity for some of the experts in this
forum to elucidate on delegation versus inheritance. At the
theoretical level, we can model it. How is it actually implemented
in languages that don't explicitly support it? C++? Eiffel? Ada?
Smalltalk (well that one is easy, I guess). Java?

Richard Riehle