猫の魔法

主にruby系の技術メモを記載

個人的メモ:Rails AntiPatterns(10)

CHAPTER7 Testing

AntiPattern: Mock Suffocation

Solution: Tell, Don’t Ask

  • スタブが多く出来る物はスタブになっている側の機能が特定の機能を実行するのに多くの質問をしている可能性がある。
  • 質問として分かれてしまっているmethodを意味のある単位に集約したmethodを用意することで、スタブ数を少なくできる
    • ★stubってなんだと思って調べたらRspecの機能だった。*1

AntiPattern: Untested Rake

  • rakeタスクをテストしようとする際に、一番簡単な方法はテストでシステムコマンドを発行すること
  • しかしながら、そのようなやり方はテストの複雑化(システムコマンドで作成されたファイルやDB上のデータのクリーンアップ)を招く。

    Solution: Extract to a Class Method

  • テスト用のmodelクラスを作り、その中でrakeタスクを処理するタスク入れてあげるようにする。
  • そうすることで通常のmodelを用いたテストと同じようにテストを行う事が出来る。
    • ★この手法はDSLを使うようなアプリのテストだったら適用出来そう

AntiPattern: Unprotected Jewelsの手前まで読了。

関連

個人的メモ:Rails AntiPatterns(一覧) - 猫の魔法

個人的メモ:Rails AntiPatterns(9)

最近仕事が忙しく読む速度が落ちがち。

CHAPTER7 Testing

AntiPattern: Lost in Isolation

  • モックを使いすぎると改修の際にテストが漏れる事がある
  • 特にモジュール間の結合点は今回の事象が起こりやすい
    • ★あんまり理解出来てないが、前後の話を統合すると結合テスト以上の統合テストをする必要があると言っているように思える。

Solution: Watch Your Integration Points

  • テストフレームワークにCucumberを使ってユーザーストーリの視点からのテストを行う
  • ★Cucumberを後で調べる
  • なおこの試みは既存のコードに対してやると、むしろ状況を悪化させる可能性がある。

AntiPattern: Mock Suffocation

  • モックやスタブが多様されているプロジェクトは、その設計自体問題がある可能性がある。

Solution: Tell, Don’t Askの手前まで読了

関連

個人的メモ:Rails AntiPatterns(一覧) - 猫の魔法

個人的メモ:Rails AntiPatterns(8)

CHAPTER7 Testing

AntiPattern: Fixture Blues

Solution: Refactor into Contexts

  • fixstureを使った書き方は一見シンプルだが、テストを複数の人が書いたり何度も改修が入ると何をしてるか分からなくなる。
    • まずはfixtureで記載していた部分を必要な要素が見えるように記載する。
    • モデルのcreateには直接要素のハッシュを渡す
  • 上記の対応に加え、各テストで共通的に行う処理があるならcontextを使って意味のある単位に処理をまとめてsetup時にそれを実施するようにする
  • 一つのテストに複数のassertがある場合、上のassertが失敗すると下のassertは実施されない。
  • 上記を防ぐ為に複数のassertがあるテストはcontextで括った上で、共通の処理をsetupに記載するようにし、1assert毎別のテストに分ける。
  • テストの専門家は1テストで1assertを推奨している。
  • 上記の例はFactoryGirlを使うともっとシンプルになる
    • ★FactoryGirlを使うとなんでシンプルになるのかがいまいちピンと来ていない。

AntiPattern: Lost in Isolationの手前まで読了

関連

個人的メモ:Rails AntiPatterns(一覧) - 猫の魔法

その他

  • JSON.loadの件で追記があるかも。

個人的メモ:Rails AntiPatterns(7)

CHAPTER7 Testing

  • railsはテストを比較的簡単に行えるのでTDD(test-driven development)やBDD(behavior-driven development)に向いている
  • Shouldaというフレームワークを使ってテストフレームワークの機能を説明している。

AntiPattern: Fixture Blues

  • テストを行う際にFixtureが肥大化してしまう問題。
  • yamlファイルにテストケース毎にテストデータをどんどん追加していくと管理出来無くなる。

Solution: Make Use of Factories

  • テスト用のFactoryクラスを作り、そのクラス内でデータの登録を行う。
  • パターン毎に新たなFactoryクラスを作る必要があるが、Fixtureを管理するよりはまだいい。
  • FactoryGirlというgemを使うともっとシンプルにテストデータ作れる。 -例えばテストデータの一部のみを変更して登録するということができる。

Solution: Refactor into Contextsまで読了

関連

個人的メモ:Rails AntiPatterns(6) - 猫の魔法

個人的メモ:Rails AntiPatterns(5) - 猫の魔法

個人的メモ:Rails AntiPatterns (4) - 猫の魔法

個人的メモ:Rails AntiPatterns(3) - 猫の魔法

個人的メモ:Rails AntiPatterns (2) - 猫の魔法

個人的メモ:Rails AntiPatterns - 猫の魔法

個人的メモ:Rails AntiPatterns(6)

CHAPTER 5 Services

AntiPattern: Kraken Code Base

  • ある程度の期間をかけて巨大になってしまったアプリケーションのこと
  • modelの数が多くなるとそれに比例して保守性が下がる。

Solution: Divide into Confederated Applications

  • 一番いいのはお互い関係ない機能を別のシステムとして分離する方法。
  • 関連がある部分切り出す事も出来る。
  • アプリケーションを分離する所までは同じで、APIを作る事によってアプリケーション間の連携を行う。
  • APIで直接的にシステム間を繋ぐと、落ちないシステムが要求される。この場合、キューイングの仕組みを使うとベスト。

CHAPTER 6 Using Third-Party Code

  • gemを使う際の注意点を記載

AntiPattern: Recutting the Gem

  • アプリケーションを構築する際に2回以上繰り返すようなことがある状態

Solution: Look for a Gem First

  • 繰り返すようなコードがある場合、まずはgemがないかを探してみる。

AntiPattern: Amateur Gemologist

  • 十分に成熟していないgemを使ってしまっている状態

Solultion: Follow TAM

  • TAM(test, activity, and maturity)の原則に従い、使うgemを評価する。
    • 自動テストがついている事(test)
    • コミュニティが積極的に活動している事(ソースコード、チケット等の更新が最近されている事)(activity)
    • 作成されてから時間が経過していて、よく管理され、多くのユーザがいる事(maturity)

AntiPattern: Vendor Junk Drawer

  • gemを利用することは一般的にいいことだが、使うgemの管理に注意を払わず、闇雲にgemを使ってしまっている状態。

Solution: Prune Irrelevant or Unused Gems

  • 使用していないgemを削除する。
    • ただこれは簡単なことではないため、そもそもgemの追加をするときに慎重になるのが正しい。

AntiPattern: Miscreant Modification

  • 使っているgemに不具合がある状態。

Solution: Consider Vendored Code Sacrosanct

  • モンキーパッチを当てる。lib以下に作る。
    • 直接vendor/以下のコードをいじらないように。
  • モンキーパッチとは下記のような物
    vendor/gems/hoge/hoge.rb
module Hoge
 class Piyo
  
  def print
     p 'piyo'
  end
end
lib/hoge_extensions.rb
module Hoge
 class Piyo
  
  def print
     p 'gao'
  end
end
  • 修正が恒久的な解決策なら、forkして開発にプルリクエストするといい。

CHAPTER7 Testingの前まで読了。

関連

個人的メモ:Rails AntiPatterns(一覧) - 猫の魔法

個人的メモ:Rails AntiPatterns(5)

CHAPTER 5 Services

  • ここで言うサービスとはサービスクラスのそれというよりAPIやウェブサイトと言った外部が提供or外部に提供する物の総称の事。

AntiPattern: Fire and Forget

  • 外部のAPIを呼ぶ際に、「例外返却される可能性があるメソッド」の例外を取得しないことによって発生する問題。
  • 本来であれば無視したい例外を無視出来なくる。

Solution: Know what Exceptions to Look Out For

  • とりあえず全部rescueして、何もしないというのが一番簡単
    • だがその場合、本当の例外も全部消えてしまう。
  • どのような例外が発生するか調べて、rescueする必要がある例外を配列の定数に持つ
    • 必要な例外のみを無視出来る。万が一見落としがあったとしても配列にその例外を追加するだけで足りる。
  • 例外が調べられないような場合は分かっている最低限の例外だけをrescueする。
    • このような場合は、未知の例外が発生を追えるように、ロギングする事が大切。

AntiPattern: Sluggish Service

  • 応答が遅い外部サービスによりアプリケーション全体が上手く動かなくなる問題

Solution: Set You Timeouts

  • Net::HTTPライブラリを使っている場合、デフォルトタイムアウトが60秒なので、これを短くすることで、アプリケーション全体の問題から局所的な問題へと置き換えることが出来る。
    • ようは待ち続けてコネクションプールが枯渇するというような致命的な問題をさけられるよという話だと思った。

Solution: Move the Task to the Background

  • 処理を非同期にしてしまう。
  • バックグランド処理をする仕組みとしてdelayed_jobを使うのがよい

AntiPattern: Pitiful Page Parsing

  • APIみたいのが提供されておらず、サイトのHTMLを解析するような処理が必要な場合、正規表現でそれを実装すると容易に壊れてしまう問題

Solution: Use a Gem

  • Nokogiriというgemを使って解析するとよい
    • XPath,CSS3セレクタを介してHTMLとXMLを検索するパーサー
    • rails使うと標準でインストールされるが、このような仕組みだとは知らなかった。もう少し詳しく調査したい

AntiPattern: Successful Failure

  • API等で外部に応答するシステムの場合、エラーの際にその応答にエラーコードを返すようなシステム(エラーが発生したかどうかは応答をパースする必要がある)

Solution: Obey the HTTP Codes

  • エラーの場合は適切なHTTPレスポンスコードを返すようにする。
    • RESTfulなAPIだとこれはその通りという感じ。
  • 画面であってもエラーの際に正しいレスポンスコードを返すのは重要。例えば認証エラー等は401を返すべき。

AntiPattern:Kraken Code Baseの手前まで読了

関連

個人的メモ:Rails AntiPatterns(一覧) - 猫の魔法

個人的メモ:Rails AntiPatterns(4)

Rails AntiPttrnsに関する個人的メモ。今日読んだとこまで。

CHAPTER 4 Controllers

Solution: Refactor Non-RESTful Actions into Separate Controller

  • この章ではRESTfullなContollerが責務を負いすぎている例として、認証管理を上げている。
  • 認証機構はUsersコントローラのようなものに直接実装するのではなく、それ用のクラスを作りログインが必要なときに呼び出せるようにroutes.rbを記載する。
  • Railsで作成されるnewとeditアクションは純粋なRESTfulには必要ない。画面の場合のみ、人間のUI上必要になっている。

AntiPattern: A Lost Child Controller

  • 1対多のモデルをview側で多側の情報と同時に1側の情報を取得する際に、1側のIDを指定する必要があるような状態。
    • computer:display 1:多のような形だと/computer/:computer_id?display=:idのような形でアクセスするような物

      Solution: Make Use of Nested Resources

  • routes.rb側でresourceをネストするようにする。
    • /computer/:computer_id/display/:idのような形でアクセス出来るようにする。

AntiPattern: Rat’s Nest Resources

  • 同一のモデルがネストされてアクセスされる場合と、単一でアクセスされる場合の話。
    • 同じViewテンプレートを使っているが、表示条件が異なる為にView内に条件分岐が生まれてしまっている状態。

Solution: Use Separate Controllers for Each Nesting

  • Controller側をネストするものとそうでない物で分離し、Viewテンプレートも別物を使う。
    • 例えば、controllers/display_controller.rbはcontrollers/display_controller.rbとcontrollers/computer/display_controller.rbに分離する。
  • この方式にするとサブディレクトリに入るものとそうでない物が混在する可能性があるので、サブディレクトリを切るなら必要なものはみなそこに入れるようにした方がいい。
  • また、この方式はDRYの原則を弱めることに繋がる可能性があるが、上手く使えば保守しやすいコードになる。

AntiPattern: Evil Twin Controllers

  • 機能が大きくなってきて、HTMLとXMLを画面とAPIによって返し分ける必要があるようなアプリケーションの場合に、一つのメソッドの中で同時に処理を行ってしまっているようなパターン

Solution: Use Rails 3 Responders

  • Rails 3から導入されたrespond_to メソッドとrespond__withメソッドを使う事で解決出来る。
    • ★このrespon_toから呼び出している実体が恐らく掲載されているコードの他にある気がするのだが、respond_to自体を調べないとなんとも。。。

CHAPTER 5 Servicesの手前まで読了

関連

個人的メモ:Rails AntiPatterns(一覧) - 猫の魔法