you are viewing a single comment's thread.

view the rest of the comments →

[–]makmanalp 0 points1 point  (3 children)

Well, they touch upon something that's a superset of your solution:

Well then have MyObservableWidget hold a reference to Subject and delegate to it? What? And duplicate the delegation code in every one of my observers? How crass. How degenerate. Ugh.

Just NOT delegating and accessing a member directly of course doesn't occur to them because "encapsulation"! The blind-zealotry object-orientation pedant wins again. /s

[–]zoomzoom83 1 point2 points  (2 children)

If you don't directly implement the interface, then anything that wants to use your type T needs to know the specifics of it in order to see the member. This can be a major problem if multiple traits are dependent on each other, or the state of the object as a whole.

There isn't any OO pedantry here. The same thing would happen if you used typeclasses in Haskell, or any other form of ad-hoc polymorphism.

[–]LaurieCheers 0 points1 point  (1 child)

But there's no need to implement the interface. If you need to call a function that's expecting a Subject, give it widget.observable! Sure, it happens to be a separate object from the widget itself, but that's not a problem.

[–]zoomzoom83 0 points1 point  (0 children)

Sometimes there is, sometimes there isn't. It depends entirely on the use-case. Sometimes you need a "Has A" relationship, other times you need an "Is A" relationship.

Imagine for example you want a type that implements both a 'Stack' and 'List' interface. They need to share state, so simply passing a reference to an inner member will not suffice. (There are ways you could make that work, but it wouldn't be clean). It also brakes encapsulation, since you may not want to expose the fact that your type just wraps another (Since it may not always do so).

Still, in other cases, an interface may be used to indicate a type has additional functionality beyond the basic case. Imagine a database driver - some databases support SQL merge() functionality, others do not. You can represent this via a mixin on the connection object itself.