
The Sororicide Antipattern - ingve
https://glyph.twistedmatrix.com/2017/05/the-sororicide-antipattern.html
======
djur
This article seems to be criticizing _automatic delegation_, not
_composition_. Delegation is not necessary for every (or even most) instance
of composition. Beyond that, languages provide more narrowly-tailored forms of
delegation than "forward every method that the underlying object supports".

Furthermore, the criticism of inheritance that the article sets up isn't the
one that "composition over inheritance" is meant to address. Languages like
Java with access modifiers (public/private/protected) don't have the
accidental namespace collision issue the writer demonstrates, and yet
"composition over inheritance" is a popular concept in those languages, too.
The problem with inheritance is that the Liskov substitution principle is very
easy to accidentally violate, and those violations can lead to a brittle and
inflexible design over time. (See [https://en.wikipedia.org/wiki/Circle-
ellipse_problem](https://en.wikipedia.org/wiki/Circle-ellipse_problem))

Finally, I don't understand the relevance of the "sororicide" metaphor, nor
does the article describe anything identifiable as an antipattern.

------
porpoisemonkey
Two nitpicky comments.

> Even if, right now, we were to change it to _note2, the maintainer of A
> could, in any future release of A, add a new _note2 variable which conflicts
> with something B is using.

This is why Python offers actual namespacing of properties and methods in the
form of a double underscore (__). Double underscore prepends an underscore and
the class name to the private property name which prevents these sorts of
collisions.

    
    
      class Bprime(object):
         def __init__(self, a):
             for var in dir(a):
                setattr(self, var, getattr(a, var))
    

> Uh oh. Looks like composition is worse than inheritance.

This is not composition.

~~~
gipp
> This is not composition.

That's basically the author's point.

> Once I understood what they meant by “composition”, I was even more
> surprised to find that I agreed with this assertion.

~~~
porpoisemonkey
Good point - I think I misunderstood the purpose of the article. I'll leave
the original comment as a matter of record.

------
aetherson
His argument against inheritance seems based largely on Python's weak
implementation of private attributes. I mean, maybe he has an argument against
inheritance _in Python_ , or some versions of Python.

But if the only argument you have against inheritance is "private names may
collide," well, like, computer science has you covered, dude.

~~~
ubernostrum
_His argument against inheritance seems based largely on Python 's weak
implementation of private attributes._

No, it seems like a Python-based example of one of the well-known problems
with inheritance, which applies even in languages like Java and C++ with
explicit compiler-enforced visibility modifiers. Difficulty determining which
class in a hierarchy is responsible for a particular member is not only a
Python problem, or an "only languages without explicit
public/private/protected" problem. One reason why composition is favored --
and remember, "composition over inheritance" goes back to the GoF book and
earlier! -- is clearing this up.

Of course, blindly "composing" is also bad, which is what this post points
out.

~~~
pseudalopex
You're right that visibility modifiers don't solve the general problem, but
the author specifically says "Inheritance is bad... because it leaves each
layer nowhere to put its internal state".

------
overgard
Does anyone actually do that (for loop to assign a bunch of variables)? To me
that just looks like a really awkward way to fake inheritance. Whenever I see
the term "composition" used, at least in my experience, it was just about
embedding one object in another. For instance, in a game engine like unity
where you do things by composition and components, you would do something like
obj.GetComponent<Renderer>() or obj.AddComponent<Thing>() or whatnot.
"Composition" still kept the boundaries very well defined.

~~~
bjterry
People do a morally equivalent thing in Javascript, on occasion. You can use
Object.assign() to build an object's functionality from multiple unrelated
objects. For example, see the section on concatenative inheritance here:
[https://medium.com/javascript-scene/master-the-javascript-
in...](https://medium.com/javascript-scene/master-the-javascript-interview-
what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9)

------
arjie
What motivates the automatic-delegation-by-copying-attributes pattern
presented here? It seems like an implementation of inheritance by someone who
simply wanted to avoid the language's inheritance feature.

~~~
tomku
That's a pattern that I've seen a lot in Javascript, where it's usually called
a "mixin" and used as pseudo-inheritance. I'm not sure why you would do it in
Python.

------
mattxxx
I agree that inheritance is not preferred, but this post picks are weird
target for its attack: 1\. It's oddly specific to particulars on how _python_
implements inheritance 2\. It misses the main point that inheritance is bad
because it obfuscates the program's intention in both implementation and
invocation

------
cat199
But isn't the whole point of inheritance in python precisely _because_ the
namespaces collide?

You are taking advantage of this 'collision' in order to allow generic
operations to function at higher/lower levels of the system..

Yes, however in python, as others have pointed out here, this unfortunately
entails knowing what all the related layers are doing.. so it should be only
one tool in the toolchest depending on the problem at hand..

~~~
porpoisemonkey
> But isn't the whole point of inheritance in python precisely because the
> namespaces collide?

I think the point from the original post is that a collision of the _private_
namespaces of the parent and child class is a bad thing. Hence the calling out
of underscore in the variable names to indicate the values should be
considered private.

------
draw_down
I enjoyed this, and agree completely. I don't know if the pattern described
within should be called "composition", but I have seen this and similar
patterns. As the author says, it should be obvious which code owns which
attributes.

------
gweinberg
class Bprime(object):

    
    
         def __init__(self, a):
    
             for var in dir(a):
    
                setattr(self, var, getattr(a, var))
    
    

Has anyone ever done such a thing? Why?

~~~
thesmallestcat
It's blindingly wrong. It creates a mutable snapshot of the other object.
Depending on the size of `a` and how many instances are being wrapped in this
way, it could increase memory footprint substantially. I can't imagine a time
where you'd want to do this. This sort of effect is usually achieved by a
__getattribute__ that falls back to whichever object(s) are being shadowed.
Not that that's ideal, but weird to see somebody who knows Python so well
throw out such a useless example.

