On 19 July 2013 16:17, Tudor Girba <tu...@tudorgirba.com> wrote:
> Hi Igor,
>
> I love these discussions. I agree that abusing inheritance is
> counter-productive. Definitely, "Shampoo subclass: #Shower" does not match
> any mental model I can think of. But, I am not seeing "Announcer subclass:
> #MyDomainConcept" equally as an abuse.
>
> Here is why.
>
> When I say "Object subclass: #MyDomainConcept", my actual intention is not
> to reuse types necessarily, but rather the infrastructure needed for the
> Smalltalk runtime. From this point of view, it is an implementation
> inheritance. I could as well, inherit from ProtoObject, but I do not do it
> because Object gives me a bit more technical infrastructure.
>
> For me, Announcer is nothing but an Object that has an extra technical
> capability. Inheriting from Announcer rather than Object seems the same as
> inheriting from Object rather than ProtoObject.
>
> Now, you can shoot.
>

As i understood, you see nothing wrong in using inheritance as reuse,
while i do.
The argument with Object does not stands, to my thinking, because
it is most generic class, and protocols it implements used by various
parts of a system,
including reflection etc,
and those parts actually expecting that all objects they dealing with
is at least implementing Object protocol(s).
So, strictly speaking by inheriting from Object you may call it reuse,
but to my thinking it is more
about having a guarantee that your class will play well with the rest
of smalltalk ecosystem (even if it's not your direct concern).

While in case of inheriting from Announcer it is something different:
you already have specific behavior
which is non-universal for all objects in system (otherwise why not
implementing Announcer protocol in Object?).

Also, i am sure you aware, that by doing this, you introducing a
certain degree of rigidness in your model (every time you refer
directly to names instead of protocols, little kittie dies ;)

because if today, Announcer serves well for your needs, and all is happy..
but maybe tomorrow, one guy will make a better one AnnouncerOnSteroids..
and to reuse it , you will need to change the parent in all numerous
classes where you used Announcer
originally.
And to make it absolutely ridiculous, imagine how you will give user a
choice whether use one Announcer or AnnouncerOnSteroids? You will
recompile your classes each time? And what if parts of your model
insist on using just Announcer while others having no problem with
trying to play with AnnouncerOnSteroids?

Another aspect of such abuse is when you inherit, you are tempted to
use direct access to internal state and private methods, and that
leads to really strange and complex problems later..

Just giving you an example:

Suppose we have a class Butter, which implements #numberOfCalories and
#fatPercentage protocols..

Now we do it like that:

Butter subclass: #Fridge

and then, of course

fridge := Fridge new.

fridge fatPercentage

or:

fridge fatPercentage: 10.

^^^ just look at the above line, how much sense you think this piece
of code makes
for reader, who will try to reason what is happens in your code?

And why you think it is not the same story with Announcer?

Because by subclassing from it, you expose its protocol(s) in places
where it is not needed and
will cause problems and confusion.
Because when you inherit to reuse, not to specialize, then users of
such class in most cases won't use
full protocol of the superclass, nor require it.. and therefore by
providing more than necessary,
you are basically violating the principle of least authority.
To fix that, you will need to override certain methods in your
subclass to prevent exposing unwanted/low-level behavior to users. But
that's again wrong, because then your model now starting to know too
much about Announcer's internals, which should be an implementation
detail, and adds even more rigidness to your design.


-- 
Best regards,
Igor Stasenko.

Reply via email to