Hi Igor,

Thanks for taking the time to write such a long answer.

I think you misunderstood my point :). I simply said that the two examples
are not the same (and I can add now that "Butter subclass: #Fridge" is as
bad as "Shampoo subclass: #Shower", but they are both different from
"Announcer subclass: #MyDomainConcept").

As I understand, you conceded the point that inheriting from Object has
reuse reasons, but that it is so because Object provides generic mechanisms
that everyone wants. I can imagine scenarios where I want a different
reflection support. All of a sudden the generic mechanism is not so generic
anymore, and you get in the same situation as the one of wanting a
different Announcer kind. Does it mean that inheriting from Object is a bad
thing? No. It is a great good enough compromise for 99.9% of the cases.

Then you say that Announcer is not in the Object protocol as if this would
be necessarily a good thing. I can argue that every Object should have
announcer capabilities just like it has exception handling capabilities,
but then we would go even further away from the main point :).

Inheritance as reuse is definitely to be avoided, and indeed the principle
of Least Authority (or more known as Principle of Least Privilege) is a
relevant point (I concede that :)). However, I guess you agree that having
#class defined in Object is not a horrible (it can be better, but it is not
horrible) thing even if most objects do not need this information.

Another principle that might be more useful when thinking about inheritance
is the Liskov Substitution Principle. From this point of view, as long as
MyDomainConcept does not redefine the meaning of Announcer, it is not
unreasonable to have it inherit from Announcer.

I stop now. You can continue to shoot :).


Cheers,
Doru



On Fri, Jul 19, 2013 at 4:54 PM, Igor Stasenko <siguc...@gmail.com> wrote:

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


-- 
www.tudorgirba.com

"Every thing has its own flow"

Reply via email to