Project

homie

0.0
No commit activity in last 3 years
No release in over 3 years
Implementation of Observer pattern.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 1.14
~> 10.0
~> 3.0
 Project Readme

Homie

Welcome!

Those of you who know why and when we need the Observer pattern will definitely find this gem useful. Those of you who don't, should read about the Observer pattern and return here afterward.

Ruby has a default module called Observable that reflect same idea but doesn't have such flexibility as Homie.

Homie will do the dirty work for you. It will call and execute all required logic sequentially. All you need is to:

  • consider Homie syntax
  • decompose the logic into the subject and observers bound to particular events
  • broadcast those events when they happen

Installation

Add this line to your application's Gemfile:

gem 'homie'

And then execute:

$ bundle

Or install it yourself as:

$ gem install homie

Usage

About

To implement Observer pattern and start using Homie first you should decompose logic into 2 object types:

  • Subject - the main part of logic, depending on the results of which the further part of logic should vary between scenarios.
  • Observer - those scenarios that will be executed depending on the Subject result.

Include into your Subject Homie module

  include Homie

Subscribing

Bind Observers to your Subject on particular events. As an Observer it could be any object with a call method(that is an entry point for business logic) OR a block of code.

To bind Observer use method on(event_name, Observer).

You have 2 options, how you could bind your observers:

  • When you want to incapsulate those observers.
class UserCreator
  include Homie

  def initialize(params)
    @params = params
    
    self.on(:succeeded, StatistictsGenerator.new)
    self.on(:succeeded) { |user| EmailPublisher.send_email(user) }
  end
end

Your observers should repeat signature of params passing by Subject in their method call or in a block of code.

  • When incapsulation don't bother you OR you need to apply a closure for some context/method execution.
class UsersController < ApplicationController
  def create
    UserCreator.new(params).
      on(:succeeded) do |user|
        render json: user, status: 201
      end.
      on(:failed) do |user|
        render json: user.errors, status: 422
      end.call
  end
end

Subscribing supports chaining.

Broadcasting

To broadcast an event use method broadcast(event_name, *arguments). Broadcasting also support chaining.

class UserCreator
  include Homie
  
  def initialize(params)
    @params = params
  end

  def call
    user = User.create!(@params)
    broadcast :succeeded, user 
  rescue ActiveRecord::RecordInvalid => invalid
    broadcast :failed, invalid.record
  end
end

You can incapsulate broadcasting of events or make public method calls as well.

I support the theory that says that two events are usually enough: succeeded or failed.

I have made shortcuts for these cases.

So

broadcast :succeeded, user is equal to succeeded(user)

and

broadcast :failed, user is equal to failed(user).

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/donasktello/homie. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.