Hacker News new | past | comments | ask | show | jobs | submit login
Extreme isolation in web apps (chrismdp.com)
19 points by patchfx on May 9, 2013 | hide | past | favorite | 6 comments



This must be the Ruby equivalent of the once prevalent Java pattern craze, I mean what the hell is the purpose of a class like this:

  class JoiningError < Struct.new(:message)
    def effect(caller)
      caller.joining_error(self)
    end
  end


The purpose is to avoid a big case statement:

    case(change.class)
    when JoiningError:
      joining_error()
    when SomethingElse:
      something_else()
    ...
    end
It's actually not implemented like that under the hood: it's done using a module with a `send`.


I don't get it at all. Here is the whole thing in straightforward 80's OOP:

  post '/join/?' do
    game_server = GameServer.instance
    if game_server.join(params[:name], @account.id)
      flash[:notice] = "You have joined the game."
      redirect_to '/game'
    else
      flash[:error] = "There was an error when joining: #{change.message}"
      haml :join
    end
  end

  class GameServer
    include Singleton

    def initialize
      @games = [Game.new]
    end

    def join(name, account_id)
      player = Player.new(name, account_id)
      return @games.last.joined_by(player)
    end
  end

  class Player < Struct.new(:name, :account_id)
  end

  class Game
    def initialize
      @players = []
      @events = []
    end
  
    def joined_by(player)
      if @players.none? { |player| player.name == player.name }
        @players << player
        @events << PlayerJoined.new
        return true
      else
        @events << JoiningError.new
        return false
      end
    end
  end

  class Event
  end

  class PlayerJoined < Event
  end

  class JoiningError < Event
  end
Could you explain to me how is the version presented an improvement over such a straightforward one?


There's no persistence in your example: how would you plug that in?


If I would see any purpose in striving for this level of separation I would use the DataMapper pattern (http://martinfowler.com/eaaCatalog/dataMapper.html), but I do not see it, so the Player etc. models would probably be ActiveRecords.


I've written lots of web apps using the plain ActiveRecord approach, and I've found it scales well to a given level of complexity, and then becomes hard to manage - hence trying something different.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: