概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: When objects become super objects - Write it simple
- 原文公開日: 2020/08/11
- 著者: Juan Manuel Ramallo
- サイト: Write it simple - Simple programming short articles. Mostly ruby focused.
日本語タイトルは内容に即したものにしました。
Rails: 本当にやった「責務過剰クラス」の事例(翻訳)
鉛筆は、何かものを書くのに使います。それ以上のものではありません(お尻に消しゴムが付いている鉛筆もありますが、この際考えないことにしましょう)。
今は何でもデジタルに移行する時代ですよね。鉛筆本体に簡単なOCRスキャナを取り付けて、書いたものが片っ端からデジタル化できたらさぞ便利でしょう。
私は会議で意見を交換中、手元で書いたちょっとした技術用の図を共有しようとしてじたばたするのが常だったので、「この鉛筆にミニプロジェクター機能が付いていたら最高なのに」と思ってしまいます。外付けのプロジェクターがなくても壁に手元の図面をさっと映せる、そんな機能です。
そうそう、レーザーポインタも付けないと。レーザーポインタで遊ぶのは楽しいですよね。
名付けて「The Pencil 3000 」
前置きはこのぐらいにしましょう。私は、Railsのクラスを作ったり更新したりするときにもついそういうことを考えてしまいます。
本当にやった「責務過剰クラス」の事例
私がそんな調子で「この機能が欲しい」「あの機能も欲しい」を繰り返すうちにやってしまった事例を以下にご紹介します。
1. モデル
私は、Railsのビューでしか使わないメソッドをモデルの中に直書きしてしまったことが何度もありました。
- あのときの自分に伝えたい:「Presenter Objectがいいよ」。
はっと気がつくと、モデルの中にコールバックメソッドを書いてしまったことも数え切れないほどです(メールを送信するコールバックや、モデルにデフォルト値を追加するためのコールバックなど)。
- あのときの自分に伝えたい:「メール送信はユーザー操作に伴う副作用だろうから、コールバックじゃなくて普通にコントローラでトリガーしてみたら?」「モデルにデフォルト値を設定したいなら
ActiveRecord::Attributes
APIを使ってみたら?」。
ああ、そういえば昔バリデーションメソッドをインラインで書きまくっていたことも思い出してしまいました、この場で謝ります。ごめんなさい。
- あのときの自分に伝えたい:「新しいクラスを追加するコストはゼロなんだから、RailsのValidatorクラスを作ってそれでやるといいよ、んじゃまた」。
2. Form Object
「背後にデータベースがないのに、Railsビューのドロップダウンボックスのオプションをselect_tag
で作ること」は有罪です。私はこれまで、Railsビューのselect
タグで使うオプションを提供するためだけに、このメソッドをForm Objectに書いてしまったことが何度もありました。
- あのときの自分に伝えたい:「そこまで大ごとじゃないから安心して、でもそれこそPresenter Objectを使ってみたらどう?どうせビューでしか使わないんだから」。
ここまで書いているうちに、何だか私は懺悔して許しを請うている気分になってきました。どうか皆さんが私と同じ罪を犯すことがありませんように。それはともかく、あとひとつだけご紹介しましょう。
3. Page Object
テストでは「セットアップ」「実行」「アサーション」「終了処理」の4つのステップが必要になるのが普通です。そしてWebアプリケーションをテストするということは、ユーザーがHTMLドキュメントに対して操作を行うということです。
そんなときはPage Object(by Martin Fowler)です。Page Objectを用いてHTMLをラップし、テストコードで使う有用なAPIをそこで提供するのです。ここで言うテストコードには「実行」「アサーション」のステップも含まれます。
率直な感想ですが、Page Pbjectで何か新しいメソッドを書いて、「インスタンスを生成する」「何かを更新する」「環境変数を設定する」といったテストのセットアップに必要なことを行うのは、実に簡単で、しかもとても楽しい作業です。
- あのときの自分に伝えたい:「テストspecのうち、何かを作成する部分はサポート用のモジュールに切り出しておく方がPage Objectの意図がぶれなくなるよ、簡単だし楽しいよ」。
さて、冒頭に書いた「The Pencil 3000 」を皆さんは覚えていますか?もしそんなスーパーな鉛筆があったら、目移りする機能がありすぎて私は鉛筆の削り方も忘れてしまうでしょう。
単一責任の原則
ソフトウェアの各モジュールを変更する理由は、ただひとつでなければならない。
詳しくは以下の良記事をどうぞ。
参考: The Single Responsibility Principle
— Clean Coder Blog
関連記事
Rails API: ActiveRecord::Attributes::ClassMethodsの#attributeと#define_attribute(翻訳)