Downsizing the delegate/composition pattern ceremony
Nir Lisker
nlisker at gmail.com
Wed Aug 5 22:18:31 UTC 2020
Hi Remi,
You want something like in Kotlin,
> class MapWrapper(map: Map) : Map by map
>
> One of the worst thing of the inheritance is the coupling between the
> subclass and the super-class because in the subclass you can not choose
> what methods you want to pick up from the super class so when the super
> class evolves, it can destroy the semantics of the subclass. Basically, the
> subclass doesn't have a stable API.
>
> You are proposing exactly that with the delegation, it's a giant step
> backward in my opinion.
Actually, I was not proposing any specific solution (and I'm not familiar
with Kotlin features). I intentionally didn't suggest what might be the
"obvious" choice of writing something like `class MapWrapper<K, V> delegate
Map<K, V>` because it seems too blunt to me.
We also spend some times on having a simpler syntax for delegation
> class MapWrapper {
> private final Map map = ...
>
public void put(K key, V value) = map::put;
> public void remove(K key, V value) = map::remove;
> }
> Here at least, the API is stable. This feature is part of the feature
> named "concise method" in the mailing list.
This is already nicer, but when there are enough methods, it can be error
prone:
class MapWrapper {
private final Map map = ...
public void put(K key, V value) = map::put;
public void remove(Object key, Object value) = map::remove;
public void remove(Object key) = map::remove;
public void containsKey(Object key) = map::containsKey;
public void containsValue(Object value) = map::containsKey;
public void clear() = map::clear;
public void isEmpty() = map:: isEmpty;
}
Can you spot the bug?
Ideally, I would like something I can look at and think "I know what this
does" and know it is done correctly. Not sure how feasible that would be,
though.
On Thu, Aug 6, 2020 at 12:35 AM Remi Forax <forax at univ-mlv.fr> wrote:
>
>
> ----- Mail original -----
> > De: "Nir Lisker"
> > À: "amber-dev"
> > Envoyé: Mercredi 5 Août 2020 23:11:36
> > Objet: Downsizing the delegate/composition pattern ceremony
>
> > Hi,
> >
> > An alternative to inheritance is the delegate pattern in which our class
> > holds an instance as a field and delegates its method calls to the field.
> > In many cases, we should prefer composition over inheritance (item 18 in
> > Effective Java 3rd ed.). However, the language doesn't let us do this
> > without pain. While with inheritance everything comes wired for us using
> > one `extends` word, with composition we need to rewrite method by method.
> > What's more, the methods' implementation is trivial and uninteresting:
> >
> > class MapWrapper {
> >
> > private final Map map = ...
> >
> > public void put(K key, V value) {
> > map.put(k, v);
> > }
> >
> > public void remove(K key, V value) {
> > map.remove(k, v);
> > }
> >
> > // etc.
> > }
> >
> > This results in a lot of code which doesn't tell us much. Lombok has
> > the @Delegate annotation that can really help in some cases, but like
> with
> > most Amber features, we prefer something that lets us express our
> intention
> > more than something that just generates the boilerplate for us.
> >
> > Are there any plans or discussions concerning this ?
>
> You want something like in Kotlin,
> class MapWrapper(map: Map) : Map by map
>
> One of the worst thing of the inheritance is the coupling between the
> subclass and the super-class because in the subclass you can not choose
> what methods you want to pick up from the super class so when the super
> class evolves, it can destroy the semantics of the subclass. Basically, the
> subclass doesn't have a stable API.
>
> You are proposing exactly that with the delegation, it's a giant step
> backward in my opinion.
>
>
> We also spend some times on having a simpler syntax for delegation
> class MapWrapper {
> private final Map map = ...
>
> public void put(K key, V value) = map::put;
> public void remove(K key, V value) = map::remove;
> }
>
> Here at least, the API is stable. This feature is part of the feature
> named "concise method" in the mailing list.
>
> >
> > - Nir
>
> Rémi
>
More information about the amber-dev
mailing list