Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DCI with Ruby

Sho Kusano
December 25, 2012

DCI with Ruby

DCI の使い方を考える

Sho Kusano

December 25, 2012
Tweet

More Decks by Sho Kusano

Other Decks in Programming

Transcript

  1. Case 1: Model class User def buy_item(item) self.purchases.create(item: item) end

    end https://gist.github.com/285ec33e6cfceb0ba0cf#file-case_1_model-rb
  2. Case 2: Controller class PurchasesController def create item = Item.find(params[:item_id])

    current_user.purchases.create(item: item) end end https://gist.github.com/285ec33e6cfceb0ba0cf#file-case_2_controller-rb
  3. Case 3: DCI class BuyItemContext def initialize(user, item) @user =

    user @item = item @user.extend(Customer) end def process @user.buy(item) end end module Customer def buy(item) self.purchases.create(item: item) end end https://gist.github.com/285ec33e6cfceb0ba0cf#file-case_3_dci-rb
  4. Wikipedia 曰く Model View Controllerページ Model ͦͷΞϓϦέʔγϣϯ͕ѻ͏ྖҬͷσʔλͱखଓ͖ʢϏδωεϩδοΫ - γϣοϐϯάͷ߹ܭֹ΍ૹྉΛܭࢉ͢ΔͳͲʣΛදݱ͢ΔཁૉͰ͋Δɻ· ͨɺσʔλͷมߋΛviewʹ௨஌͢Δͷ΋modelͷ੹೚Ͱ͋Δʢmodelͷมߋ

    Λ௨஌͢ΔͷʹObserver ύλʔϯ͕༻͍ΒΕΔ͜ͱ΋͋Δʣɻ ଟ͘ͷΞϓϦέʔγϣϯͰ͸σʔλͷ֨ೲʹӬଓతͳهԱͷ࢓૊Έʢσʔ λϕʔεͳͲʣ͕࢖ΘΕ͍ͯΔɻMVCͷ֓೦Ͱ͸ɺσʔλͷʢUIҎ֎ͷʣ ೖग़ྗ͸औΓѻΘͳ͍ͷͰɺσʔλΞΫηε΋ຊདྷMVCͷ֓೦ͷൣᙝΛ௒ ͑Δ΋ͷͰ͸͋Δ͕ɺ׶͍͑ͯ͑͹modelͷதʹӅṭ͞ΕΔͱߟ͑ΒΕΔɻ
  5. # Redmine - project management software # Copyright (C) 2006-2012

    Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require "digest/sha1" class User < Principal include Redmine::SafeAttributes # Different ways of displaying/sorting users USER_FORMATS = { :firstname_lastname => { :string => '#{firstname} #{lastname}', :order => %w(firstname lastname id), :setting_order => 1 }, :firstname_lastinitial => { :string => '#{firstname} #{lastname.to_s.chars.first}.', :order => %w(firstname lastname id), :setting_order => 2 }, :firstname => { :string => '#{firstname}', :order => %w(firstname id), :setting_order => 3 }, :lastname_firstname => { :string => '#{lastname} #{firstname}', :order => %w(lastname firstname id), :setting_order => 4 }, :lastname_coma_firstname => { :string => '#{lastname}, #{firstname}', :order => %w(lastname firstname id), Redmine app/models/user.rb
  6. Token.delete_all ['user_id = ?', id] Watcher.delete_all ['user_id = ?', id]

    WikiContent.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] WikiContent::Version.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] end # Return password digest def self.hash_password(clear_password) Digest::SHA1.hexdigest(clear_password || "") end # Returns a 128bits random salt as a hex string (32 chars long) def self.generate_salt Redmine::Utils.random_hex(16) end end class AnonymousUser < User validate :validate_anonymous_uniqueness, :on => :create def validate_anonymous_uniqueness # There should be only one AnonymousUser in the database errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists? end def available_custom_fields [] end # Overrides a few properties def logged?; false end def admin; false end def name(*args); I18n.t(:label_user_anonymous) end def mail; nil end def time_zone; nil end def rss_key; nil end def pref UserPreference.new(:user => self) end # Anonymous user can not be destroyed def destroy false end end Redmine app/models/user.rb 706 lines
  7. Token.delete_all ['user_id = ?', id] Watcher.delete_all ['user_id = ?', id]

    WikiContent.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] WikiContent::Version.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] end # Return password digest def self.hash_password(clear_password) Digest::SHA1.hexdigest(clear_password || "") end # Returns a 128bits random salt as a hex string (32 chars long) def self.generate_salt Redmine::Utils.random_hex(16) end end class AnonymousUser < User validate :validate_anonymous_uniqueness, :on => :create def validate_anonymous_uniqueness # There should be only one AnonymousUser in the database errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists? end def available_custom_fields [] end # Overrides a few properties def logged?; false end def admin; false end def name(*args); I18n.t(:label_user_anonymous) end def mail; nil end def time_zone; nil end def rss_key; nil end def pref UserPreference.new(:user => self) end # Anonymous user can not be destroyed def destroy false end end Redmine app/models/user.rb 706 lines
  8. 現状の Rails で DCI をするには 1. dci gem を頑張って使う(微妙) 2.

    DCI-Sample みたいに自分で頑張る(辛い) 3. user.extend(Customer) しまくる(妥当) 4. ESM に gem 化をお願いする(どうなん)