Presenter pattern 的原理是,是 Model-View-Controller(MVC) 架構模式衍生出來的一個部分,主要用於建立使用者的介面接口。 在 MVP 中,Presenter 承擔了 中間人 的功能。在 MVP 中,所有邏輯的部份都會寫在 Presenter 內。事實上,其實與 Decorator 有點相似,通常有些些微的差異,但通常只會選擇兩個其中一個來整理,也沒有一定的通則,主要還是以團隊內的方式為主。
直接來看如何使用:
假設我有一張 Log 的表,裡面 operator 欄位紀錄了 User 誰操作了某項東西,所以紀錄這個 Log,並且知道
Source->Target從 A 到 B,這時候想要後台的前端可以看到 Log 紀錄,隨便舉個例子。
app/presenters folderPresenter to Controller假設 Log 是在 TrackController 內的 show 來顯示,範例如下:
  # frozen_string_literal: true
  class TrackingController < ApplicationController
    def show
      @user_logs = UserLogPresenter.new(user_id)
    end
    # ...
  end
app > presenters > user_log_presenter.rbEnumerable include 近來提供 each 等等方法,
  # frozen_string_literal: true
  class UserLogPresenter
  include Enumerable
    def initialize(user_id)
      @user_id = user_id
    end
    def each(&_block)
      logs.each do |log|
        yield format(log)
      end
    end
    def format(log)
      {
        user:       User.find(log.operator),
        source:     log.source,
        target:     log.target,
        created_at: log.created_at
      }
    end
    def logs
      @logs ||= Log.where(operator: user_id)
    end
  end
  @user_logs.each do |log|
    <th><%= log[:user] %></th>
    <th><%= log[:source] %></th>
    <th><%= log[:target] %></th>
    <th><%= log[:created_at] %></th>
  end
註: 想理解兩者的差異也可以參考這篇的比較 Ruby on Rails patterns - decorator vs presenter,雖然目前我也沒有可以完全的分懂 orz