コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

「良いコード/悪いコードで学ぶ設計入門」をRails開発に活用する目線で整理してみる

ミノ駆動本の読書会を社内で行い、そちらを振り返りRailsで活用する目線でどのようなところが活きるポイントかを「章ごと」と「全体を通して」で整理をしてみます。

章ごとに振り返る

1 悪しき構造の弊害を知覚する

こちらはイントロダクションの章で、どのようなコードをこの書籍では「悪い」と呼んでいるNGパターンのものがどんなものなのかを説明していく章となっており、後続の個々の説明とつながっていく章となっていると思います。

2 設計の初歩

この章では例示した悪いソースコードをベースに、今後の章で取り上げていくものを当てはめていくとどのように改善されるのかという例示を示すパートです。この章だけでも初歩的な改善のやり方を紹介しており、言語に関わらず参考にできる部分が多いと思います。

3 クラス設計 ―すべてにつながる設計の基盤―

この章から具体的なプログラムコーディングにおけるクラスの組み立て方の話がNGパターンとともに取り上げられてます。

Railsで「FatModelになったからPOROに切り出そう」などとなったときにどういうクラスを作ればいいのかわからなくなる、というケースもあるのではないかと思うがその際に「3.2 成熟したクラスへ成長させる設計術」のパートで多く参考になるところがあります。ストレートに参考になるのは以下の部分。

  • 3.2 成熟したクラスへ成長させる設計術
    • 中でも以下の章
      • 3.2.1 コンストラクタで確実に正常値を設定する
      • 3.2.3 不変で思わぬ動作を防ぐ
      • 3.2.4 変更したい場合は新しいインスタンスを作成する

上記に関しては「変更容易性をあげる」というところに大きく寄与する部分なので言語に関わらず利用できると思います。

なお、この章に登場する「値オブジェクト」は語る人によって定義の変わるワードのため使う場合は気をつけると良いかと思います(参考サイト

4 不変の活用 ―安定動作を構築する―

前の章で取り上げた部分を掘り下げた章で、「なぜ再代入が変更容易性に影響するのか?」「可変にするべきケースはどういうものがあるのか?」という話が中心になっています。

Railsでも以下のようなコードを見かけるので、このようなコードがどういう悪影響をもたらす可能性があるのかをこの章を読むと認識できるようになり、バグの発生をグッと減らす書き方につなげることができるのではないかと思います。

def create
  name = params[:name]
  age = params[:age]
  user = User.create(name: name, age: age)
  ## ユーザ作成時にボーナスポイントが入る
  point = 2000
  
  ## 年齢が20歳以下の場合はポイントが4000pt
  point = 4000 if age >= 20
  
  user.point = point
  
  ## 関連プロフィールレコードを作成
  user.build_profile
  
  user.save!
  
  ### 所持ポイントが3000以上ならリダイレクト先を変える
  redirect_to "/special" and return if point >= 3000
  
  
  redirect_to "/"
end

個人的にはこの章がプログラムコードを書く面においては学びが多い部分かと思っています。

5 低凝集 ―バラバラになったモノたち―

この章ではメソッドを作るときの具体的なノウハウを紹介する章になっておりRails開発で使える部分としては以下の部分。

  • 5.1 static メソッドの誤用
    • ここではRubyのクラスメソッドとして作るときの考え方、判断基準がわかる
  • 5.2 初期化ロジックの分散
    • 初期化のロジックが複雑化する場合の一個のアプローチとして利用できる
  • 5.3 共通処理クラス(Common・Util)
    • どういうことを共通処理としておくべきか、というポイントがわかる
  • 5.5 多すぎる引数
    • 不変にしたり、完全コンストラクタを目指すと起きがちな多すぎる引数への対策アプローチがわかる

他の部分に関してはRubyRailsだと噛み合わない可能性があるので、考え方の1つとして読んでおくとよいと思います。

6 条件分岐 ―迷宮化した分岐処理を解きほぐす技法―

アプリケーションは成長していくごとに当初とは違ったユースケースが増えていくので条件分岐も増えるのは必然、そのときの条件分岐に関しての対策方法に関しての話がこの章です。Railsで有用そうなものは以下の部分

  • 6.1 条件分岐のネストによる可読性低下
    • 早期returnの有用性がわかる
  • 6.2 switch 文の重複
    • どのようなときに「条件分岐が散らばっているのか」というのがわかり、まとめる方針がわかる

6章ではinterfaceを用いた条件分岐ロジックの解体を中心に話が進むため、Rubyの場合読み替えれば当てはめられる部分も多く一切使えないというわけではないですが、ストレートに当てはめにくいところではあるので、読みながら使える部分を整理するトピックかと思っています。

7 コレクション ―ネストを解消する構造化技法―

この章は配列などのコレクション要素を取り出してループさせるときの処理に関して陥りがちな話を取り上げてます。この章はコンパクトかつRubyでもストレートに使える要素が多いと思います。

特筆しておくべきところはコレクションを直接渡さないようにする(7.3 低凝集なコレクション処理)というのは認識がないとやりがちな部分なのでは作り方の1つとして覚えておくと良いかなと思います。

8 密結合 ―絡まって解きほぐせない構造―

この章では「単一責任原則」がどのような利点をもたらすというのかを中心に説明している章で、メソッドやクラスをどういう塊で扱うべきなのかを説明しています。この章もストレートに活用できる部分が多いと思います。

また、DRY原則で陥りがちな罠に関しても書いてくれているので、「DRY原則で共通化したほうがみんな便利だ!」と善意からくる悲劇もここを読んでおくと起きることが少なくできると思います。

加えて「スマートUI」に関しては取り上げられている部分は少ないですが、RailsではViewにロジックが置かれすぎてしまうなどかなり起きがちな話なので意識してみると良い部分なのかなと思います。

9 設計の健全性をそこなうさまざまな悪魔たち

この章は変更可用性においてつらくなるポイントをあげている章になっています。Rails開発にストレートに活用できそうな部分は以下のパート。

他の部分はRubyだと参考にならない部分や、Railsのパッケージング構成自体がこれで述べられているアンチパターンに近いので一部そぐわないかもしれない、というところでした。ただ他の章同様に知識としては役に立つ部分なので一読すると良いと思います。

10 名前設計 ―あるべき構造を見破る名前―

ここでは「名前」を中心に語られています。「名前なんてみんながわかればいい」というように考えている人にはぜひ読んでいただきたい章で名前が以下にアプリケーションの成長と変更可用性に寄与するかというのが語られています。Rubyの父、Matzも名前重要というところは語っており、Rubyを扱う人には他の章よりも意義のあるパートかと思います。

個人的には「汎用的な名付けをするとなんでもかんでもそこに機構が追加されて低凝集になる」という旨の部分がコードレビューをする際に大変役に立つ考え方だなと感じました。

11 コメント ―保守と変更の正確性を高める書き方―

こちらの章はコメントに関しての考え方の章となっており、どのようなコメントが未来のために有用かという観点で書かれています。コメントを書く自分自身の指針や、チームのルールをつくるときの起点になるような内容のため、特定の言語に限らず役に立つ話題かと思います。

12 メソッド(関数) ―良きクラスには良きメソッドあり―

こちらは2章から9章で紹介してきた方法論をどう扱うと変更可用性の高いメソッドをつくることができるか、という実践紹介的な章です。いままでは問題に対しての解法という切り口だったので、いざゼロイチでメソッドを作るときにはどういうことを考えるべきかというおさらい的な章なので、いままでの章を読んだ上で読んだほうがいいかと思います。

13 モデリング ―クラス設計の土台―

この章では意味のあるモデルをどう考え、それをどうやってクラスにしていくかという話が中心の章になります。どうやってクラスを分けるべきか、概念を整理するべきかというところを説明しているため、システムの大枠の設計をする際に助けとなる話かなと思っています。

個人的にはこの章がRails開発をやっていると一番混乱する章かなと思っています。Model=ActiveRecordという前提で読んでしまうと混乱するので、一般的なモデルとは何かというのを前提として頭に入れてから読むとスッと入ると思います。

参考:モデルとは何であって、何でないのか #kichijojipm - Speaker Deck

14 リファクタリング ―既存コードを成長に導く技―

こちらは著者の経験値や知識をベースにしたリファクタリングのテクニックが紹介されている。いざリファクタリングをしなければならなくなったときにコードを直していく手法などは参考になる部分が多いです。

また、著者のRailsでのリファクタに関してもコラムとして書かれているのでその部分ももともと主軸を別の言語においていた目線なので従来のRailsでのリファクタとは違う切り口が紹介されているので学びがあると思います。

15 設計の意義と設計への向き合い方

こちらの章は章のタイトルどおり向き合い方の話となる、設計というよりかは考え方が主体の部分とはなる。そのため設計というよりかは知識の活かし方や取り組みかたのTips的なことが書かれているので、今までと毛色は違う部分となるが読み物として読んでおくと良い部分かなと思います。

16 設計を妨げる開発プロセスとの戦い

こちらはいままでの手法などをどうやって実際のプロダクトコードやチームに浸透させていくか?という部分の話となる。もしいままでの話をチームとして広げて行く場合の想定問答として活用できる部分かと思われます。

17 設計技術の理解の深め方

こちらは最後の総括の章なので、この本よりも先に、というところの内容となっています。

全体を通して

Railsでも使えるコードのテクニック

こちらの本は著者の方が「変更可用性」を中心においた書籍であるということは様々な場所で語られており、導入部分にも記載があります。そのため考え方や心構えの部分はビジネスの成長や変化に伴ってアプリケーションやシステムをいかに楽に(≒省コストで)変更させることができるかというのを扱っていると思っています。

Railsだとフルスタックフレームワークの密結合の特性を生かして、素早く作ることができるという利点があるため部分的にはこの書籍と相反する部分もあります。しかしながらプログラムコードレベルでの設計の話もあるためRailsのレールで高速にプロダクトコードを書きつつ、一定の変更のしやすさを作り上げることができるテクニックは紹介されていると感じています。

名前重要と単一責任原則

この書籍内でも紹介されているが、Rubyは静的型付け言語や他の動的言語と比べても自由度が高い言語のため、クラスをたどるためのコードジャンプが苦手な言語となっています。

ただこちらの本は様々なシーンで名前の重要性を説いており、また単一責任原則に関しても度々登場します。そのためこの本で紹介されている名付けや単一責任原則を意識すると名前が洗練され良い意味で名前のかぶりが減るのでコードジャンプの恩恵が受けやすくなり、変更時の把握がしやすくなるという効果も期待できると思われます。

Railsだと理解しづらいモデリングの部分

従来のモデリングは「アプリケーション上の課題に対して扱い易くするためのオブジェクトのモデリング」であり、この書籍で取り上げられているモデリングもそちらに類するものと思っています。

ただ、RailsだとどうしてもActiveRecordがあるため、この書籍で取り上げられているようなモデリングがどうしてもデータと一体化して考えてしまう。またRailsがキャリアスタートの場合「Model=データベースのテーブルから成り立つもの」という理解をしている可能性もあるので余計に「モデリング」がわかりにくいかなと思います。

そのためモデリングの部分に関してはRailsActiveRecordの性質を理解した上で読み直すと良い部分かと思っています。また、そこがわかるとオブジェクトとしてのメソッドの選り分けかたも洗練されるのではないかと思います。

なお、ActiveRecordの性質を理解するにはこちらが大変参考になると思います。

参考/関連リンク