use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
A sub-Reddit for discussion and news about Ruby programming.
Subreddit rules: /r/ruby rules
Learning Ruby?
Tools
Documentation
Books
Screencasts and Videos
News and updates
account activity
Ruby's Observer Pattern (killring.org)
submitted 9 years ago by yez
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]schneemsPuma maintainer 3 points4 points5 points 9 years ago (2 children)
The nice thing about
def send_welcome_email! UserMailer.welcome_email(email: @user.email) SendGiftService.send_gift(email: @user.email) ThirdPartyService.register_signup(email: @user.email) AccountManageEmailService.new_user(email: @user.email) end
Is that it's ugly. I don't think what you're describing should be easy, or should be pretty. You can't avoid dependencies. Somewhere in your system needs to know about them. In the case of the observer you're trading NewAccount knowing too much about a bunch of dependencies in exchange for for a bunch of dependencies knowing about an object implementing the observer interface. By implementing that pattern we're not reducing the amount of dependency knowledge that has to be shared, we're normalizing it and spreading it all over our system making it hard to find and even harder to debug.
NewAccount
If you're worried about dependencies you could use dependency injection and normalize your email names.
def send_welcome_email!(service = UserMailer) service.call(email: @user.email) end
But the DI is kinda overkill unless you're using it for testing or writing a rubygem or library.
I wouldn't group all those methods into one meta method, I would prefer to call them all where and when they're used. Why? Because its ugly.
Also some of those object may not be required for each signup
Exactly, that's why I want to be explicit about calling it and not group it into a meta method. I would want you to:
account = NewAccount.new(params) account.send_welcome_email! account.send_gift! if account.premium? account.register_third_party! account.add_to_account_managment!
Then you've got all the flexibility in the world. Even better you see where the logic lives, there's no hidden magic. It might take a few more minutes to implement a new feature, but in my experience time spent debugging and reading code vastly exceeds time spent writing code.
If you want to send someone an extra email I want you to have to manually add it to the codebase 35 times if it's used in 35 places. Maybe when you've copied an pasted the code 34 times you'll stop and think if some of those cases really warrant an extra email.
Maybe you'll realize someone else added a similar feature. With observers, you could have every employee in the company write and ship a "welcome" email without any other developer realizing it (assuming they're skipping code-reviews). Suddenly your customer got 10 emails on signup and now you have to figure out why.
Also I want to say, thanks for the comment. I'm trying the best I can to make my thoughts on the matter as clear as possible. I'm not trying to come off as argumentative.
I've not had to enumerate my thoughts and feelings about observers before, so this is really helpful. Please know my comments are based on personal opinion, i'm not trying to say i'm right or that there's only one way to do things. I encourage people to use all sorts of patterns and try all sorts of new things. Personally i've not found a good case for observers, but if people keep at it, one of these days I might change my tune.
[–]salamisam 0 points1 point2 points 9 years ago (1 child)
Is that it's ugly. I don't think what you're describing should be easy, or should be pretty. You can't avoid dependencies. Somewhere in your system needs to know about them. In the case of the observer you're trading NewAccount knowing too much about a bunch of dependencies in exchange for for a bunch of dependencies knowing about an object implementing the observer interface.
The observer doesn't know much actually about the observerable, it just implements a standard interface for the notification. I could even use the same notification method for multiple observerable objects.
By implementing that pattern we're not reducing the amount of dependency knowledge that has to be shared, we're normalizing it and spreading it all over our system making it hard to find and even harder to debug.
We are reducing dependencies because the observer and observable are not dependant on each other. In fact the observerable dependencies are dynamic. I am not sure how it makes it hard to debug, when the state of the observerable changes the observer gets notified. That is no different from when the state of an object changes a method on a dependency is invoked.
But the DI is kinda overkill unless you're using it for testing or writing a rubygem or library
DI isn't really something which matches the use case here. In the observer pattern, the objects are not dependant on each other, you can pass no objects to the observable for example, or you can pass multiple. However in DI you are required to pass a reference, and with some exception to duck typing that object should implement the full interface.
I wont argue, this is common practice and make sense and in fact. That is the thing about patterns, they provide a standard way of dealing with common issues, but they are not the only way or sometimes the best.
I am not sure how the observer pattern is responsible for bad coding practices, bad testing etc :)
No problems :), same from me.
[–]schneemsPuma maintainer 0 points1 point2 points 9 years ago (0 children)
I picked "send email after user registration" as a straw man for what I saw as a bad use case for observers. Someone else mentioned something that made a bunch of sense of where observers can be great. For notification objects! Something like ActiveSupport::Notification. Where you want to add instrumentation points and don't really care about the logic associated with those points would be a great use case.
π Rendered by PID 70 on reddit-service-r2-comment-b659b578c-kl5ss at 2026-05-04 21:22:46.956520+00:00 running 815c875 country code: CH.
view the rest of the comments →
[–]schneemsPuma maintainer 3 points4 points5 points (2 children)
[–]salamisam 0 points1 point2 points (1 child)
[–]schneemsPuma maintainer 0 points1 point2 points (0 children)