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

Rails構成とオブジェクト指向/ rails-structure-and-object-oriented

@amyroi
June 08, 2018
960

Rails構成とオブジェクト指向/ rails-structure-and-object-oriented

@amyroi

June 08, 2018
Tweet

Transcript

  1. コード構成素案
    主にビジネスロジックの話
    @amyroi

    View Slide

  2. コード配置例
    #

    app/
    ├ lib/ #
    もしくは lib/
    配下、autoload
    │ └ aiml/ #
    プロダクトコードに影響しないコンポーネン
    │ └ aws/ #
    プロダクトコードに影響しないコンポーネント
    │ └ nlu/ # gem
    化想定

    ├ models/
    │ └ concerns/ # ActiveSupport::Concern
    │ └ user.rb # ActiveRelation
    継承
    │ └ validators/ #
    独自validation
    クラス
    ├ behaviors/
    │ └ user_search_form.rb # Form
    オブジェクト
    │ # | Service
    クラス
    │ # | Decorator
    クラス
    │ └ nlu_manage/ #
    プロジェクト内で行うNLU
    への
    │ #
    アクセス関するクラスをまとめるnamespace
    │ └ project.rb #
    振る舞いのクラス
    │ └ bot.rb #
    振る舞いのクラス
    2

    View Slide

  3. 継承と結合をなくしていく
    module, callback, 継承の使用を極力さける
    継承より委譲
    密結合 → 疎結合へ
    lib配下のライブラリは対象外
    3

    View Slide

  4. メリット
    振る舞いに合わせたオブジェクト設計
    疎結合にすることによりユニットテストの見通しがよくなる
    デメリット
    デザインパターンの乱用
    振る舞いにおけるファイル数増
    4

    View Slide

  5. 継承
    class A
    def save
    end
    end
    class B < A
    end
    b = B.new
    b.save
    5

    View Slide

  6. 委譲
    class A
    def initialize(object)
    end
    def save
    object.save
    end
    end
    class B # object
    を汚染しない
    end
    class C
    end
    a = A.new(B.new)
    a.save
    a = A.new(C.new)
    a.save
    6

    View Slide

  7. モジュール
    インスタンスを生成しない
    例:helper
    グローバルでアクセスが可能。
    moduleではなくclassにしていく。もしくはnamespaceとして使
    う。
    7

    View Slide

  8. concernについて
    ActiveSupport::Concern
    使用用途:ApplicationRecordに共通のクラスメソッド、インスタン
    スメソッドを追加する
    クラスのトップレベルの共通化。
    使用頻度を少なく
    8

    View Slide

  9. クラス
    インスタンス化
    メソッドのスコープを限定できる
    オブジェクト!
    models配下に振る舞いのクラスを生成していく
    ActiveModel、デザインパターン、委譲
    transactionは明示的に行う
    9

    View Slide

  10. FormObject (ActiveModel)
    フォーム表示するための振る舞いを分離したクラス
    validationも配置可能
    Serviceクラスでも可
    10

    View Slide

  11. モジュール
    module Seachable
    extend ActiveSupport::Concern
    def self.seach(params)
    end
    end
    class User
    include Seachable
    end
    # Usage
    User.search(params)
    11

    View Slide

  12. Formオブジェクト
    class UserSearchForm
    include ActiveModel::Model
    def self.search(search_params)
    end
    end
    class User # object
    を汚染しない
    end
    # Usage
    UserSearchForm.search(params)
    12

    View Slide

  13. Callback
    Railsのcallbackの影響
    モデル同士の結合度の高さ
    完結したユニットテストがかけない
    ActiveModel::Callbacksを使用
    transactionは定義
    Decoratorパターンで作成したクラスで処理を完結させる。
    13

    View Slide

  14. ActiveRecordのcallback
    class User
    before_create :join_project
    def join_project
    self.project = Project.create()
    end
    end
    user = User.new
    user.save
    14

    View Slide

  15. Decoratorパターンで役割を分離した例
    class UserCreateDecorator
    include ActiveModel::Model
    attr_accessor :user
    define_model_callback :save
    before_save :set_project
    def save
    User.transaction do
    run_callbacks(:save) do
    @user.save
    end
    end
    end
    def set_project
    @user.project = Project.create
    end
    end
    user = UserCreateDecorator.new(User.new)
    user.save
    15

    View Slide