Which is better?

Sorin
Swift sections
Published in
2 min readNov 27, 2019

--

An API class that supports N optional client delegates (based on segregated protocols) or one that supports one delegate with N optional methods — i.e. functions with empty default protocol implementations?

Although I know theoretical guidelines state differently (balancing towards interface segregation), in my opinion the answer would rather depend on the situation and it may be in the middle!

Here is a small example I can think of. A class manages timeline items and allows its client class to execute custom actions when certain operations are done: when an item is added or removed to the internal collection, when the time interval associated to an item changes or when an item’s type is changed from or to “milestone”. And let’s assume we want different handlers for “will” and “did” moments. Moreover, the item manager wants to allow the client to respond to “create new item” requests, i.e. accepting an optional “factory”.

Going with full segregation it means that we’d need 9 protocols:

  • WillAddItemHandler, WillRemoveItemHandler;
  • WillChangeItemTimeHandler, WillChangeItemTypeHandler;
  • DidAddItemHandler, DidRemoveItemHandler;
  • DidChangeItemTimeHandler, DidChangeItemTypeHandler;
  • and ItemProvider.

The class instance would then define (and internally use) 9 weak member vars, one for each of these types. And its client can then implement 0–9 protocols and set itself as a delegate on 0–9 of those fields, accordingly. Not to mention that each protocol would then (strangely?) define only one method.

(Sure, in this case a higher level solution would be to generalize most of the above using an event pattern — since all are events passed to the client — but what if you don’t want too much generics, e.g. if the situations are very custom and you want only will or only did for some actions, and/or the event arguments are totally different and you’d want to avoid having types for each of them, and/or you need several other delegates that are not event-like, nor provider-like?

Another possible remark is to pass closures rather than delegates. But I simply don’t like them, myself, at least not when doing Swift API development; I explained here why, under Functional programming.)

I’d argue that one would better define a few protocols to handle groups of situations, based on some usage assumptions to avoid the need of such a high number of protocols and delegates (reducing complexity), but to be able to also permit full optionality he or she must still define empty default implementations for their methods — at least on protocols that define more than one function:

  • CollectionChangeHandler (for will/did add/remove item);
  • ItemChangeHandler (for will/did time/type changes);
  • and ItemProvider (for createNewItem).

--

--

Sorin
Swift sections

Software Developer • Rust, Swift, WPF, Web • MacBook enthusiast • fashion design • EDM • absurdism • writing from Cluj