A beautifully written piece with lovely images. At some stage in my (ongoing) OO enlightenment, I got to appreciate that in a healthy OO codebase, there should be constant refactoring and code movement in order to adapt to small and large changes (and that there is a lot of judgement in when to opt for a big change when requirements are only incrementally arriving.)
While I agree with much of the sentiment about clear naming, I think that many languages with OO capabilities fail to provide easy to use role based composition at their peril. It is a big challenge to do wrestle real code and we need all the tools we can get.
Here's how it could look with roles at a coarse grain level:
---
role Breedable { ... }
role Feedable { method eat-carrot { ... } }
role Trainable { ... }
class Horse does Breedable does Feedable does Trainable { has $.sound = 'neigh'; ... }
class Donkey does Breedable does Feedable does Trainable { has $.sound = 'heehaw'; ... }
my $h = Horse.new(); $h.eat-carrot();
---
The benefit of roles is that they let you apply your human language skills (English, French, etc) to combine words as in natural languages - so roles are akin to Adjectives and classes to Nouns, and method names to Verbs.
With roles, you can avoid the temptation to hardwire inheritance:
---
class Donkey is Horse { ... }
---
And it leaves open the option for layers of specialization of roles like this:
---
role DonkeyTrainable does Trainable { ... }
class Donkey does Breedable does Feedable does DonkeyTrainable { ... }
---
And you can use inheritance and role composition side by side:
---
class Beast Breedable does Feedable does Trainable { ... }
class Horse is Beast { ... }
class Donkey is Beast { ... }
---
Here's what it says in the docs:
_Roles are a collection of attributes and methods; however, unlike classes, roles are meant for describing only parts of an object's behavior; this is why, in general, roles are intended to be mixed in classes and objects. In general, classes are meant for managing objects and roles are meant for managing behavior and code reuse within objects._
While I agree with much of the sentiment about clear naming, I think that many languages with OO capabilities fail to provide easy to use role based composition at their peril. It is a big challenge to do wrestle real code and we need all the tools we can get.
Here's how it could look with roles at a coarse grain level:
---
role Breedable { ... }
role Feedable { method eat-carrot { ... } }
role Trainable { ... }
class Horse does Breedable does Feedable does Trainable { has $.sound = 'neigh'; ... }
class Donkey does Breedable does Feedable does Trainable { has $.sound = 'heehaw'; ... }
my $h = Horse.new(); $h.eat-carrot();
---
The benefit of roles is that they let you apply your human language skills (English, French, etc) to combine words as in natural languages - so roles are akin to Adjectives and classes to Nouns, and method names to Verbs.
With roles, you can avoid the temptation to hardwire inheritance:
---
class Donkey is Horse { ... }
---
And it leaves open the option for layers of specialization of roles like this:
---
role DonkeyTrainable does Trainable { ... }
class Donkey does Breedable does Feedable does DonkeyTrainable { ... }
---
And you can use inheritance and role composition side by side:
---
class Beast Breedable does Feedable does Trainable { ... }
class Horse is Beast { ... }
class Donkey is Beast { ... }
---
Here's what it says in the docs: _Roles are a collection of attributes and methods; however, unlike classes, roles are meant for describing only parts of an object's behavior; this is why, in general, roles are intended to be mixed in classes and objects. In general, classes are meant for managing objects and roles are meant for managing behavior and code reuse within objects._
btw these examples are in raku ... https://docs.raku.org/language/objects#Roles