Example 3 adds a nonsense method, EmailUser#send_to_feed. What does that mean? Email users don't have feeds. If we're going to evangelize OO purity, let's do it right. class Post def created user.post_created(self) end def send_to_feed(feed) feed.send(contents) end end class TwitterUser def post_created(post) post.send_to_feed(twitter) end end class EmailUser def post_created(post) # no-op. end end The post merely te…
This is all nonsense anyway. There's no such thing as a TwitterUser or an EmailUser. You just have users, some of whom use Twitter, some use email (and may have multiple addresses), and some use both, and they can edit their settings to add and remove accounts and change notification preferences. So it's really has-a rather than is-a. Adding unnecessary inheritance is far worse than the original problem.
In my experience observing (pragmatically, never dogmatically) OO principles like SOLID reduces entropy. Thus are worth applying.
Personally I prefer polymorphism and null object pattern over conditionals to deal with edge cases, though if you have a leaky abstraction in the first place no principle or pattern is going to save you!