|
One of the things I dislike about the OO noun.verb() syntax is that frequently you have multiple nouns. For example in some graphics systems, you've got a canvas to draw on, a pen which knows styles for line thickness or dashes, a brush for how to fill, and a shape to be drawn. Who owns the verb? They kind of all do: canvas.draw(pen, brush, circle)
circle.draw(canvas, pen, brush)
... and so on
The other issue I have is in closed object systems where you can't add new methods to classes in the library. Say I want to add a new type of shape, maybe an emoji face composed of several circles. Depending which class owns the methods, my new smiley method stands out from the other shapes which are provided by the library, and I think the lack of symmetry is ugly: canvas.draw(pen, circle)
draw(canvas, pen, smiley)
For simple cases, inheritance solves this, but then you get into worse trouble when Alice builds a derived class to support smileys, and Bob builds a separate derived class to add stick figures. Which version of the canvas do I instantiate to support both? Maybe this implies the method should be on the shapes, but I can contrive other examples which break that too. (Another approach is monkey patching, which has it's own flaws, and so on.)There aren't many languages which support multimethods, but overloading functions is sufficient for statically typed cases, and it's appealing (for me) to have the same syntax for "builtin" methods and ones you add yourself: draw(canvas, pen, brush, circle)
draw(canvas, pen, brush, smiley)
Other people have mentioned languages with "uniform function call" syntax (where f(a) and a.f() are synonyms). I guess that's ok if you're in the "there's more than one way to do it" camp. I don't think that completely addresses the problem though. I could make more examples, but this post is getting long already.For what it's worth, I really dislike it when languages implement operator overloading for binary operators as methods on the first object without a way to dispatch to the second object. This makes it very difficult to have your new types play well with the builtin or library provided types. Binary operators really are functions with two arguments. |
OOP is not about nouns. It's about establishing protocols between subsystems. What you're describing are the typical fake "dilemmas" of someone coming from a static, class-oriented programming languages like Java.
Look up Class Responsibility Collaborator exercise.