天の月

ソフトウェア開発をしていく上での悩み, 考えたこと, 学びを書いてきます(たまに関係ない雑記も)

現場で役立つシステム設計の原則 - Forkwell Library #9に参加してきた

forkwell.connpass.com

こちらのイベントに参加してきたので、会の様子と感想を書いていこうと思います。

会の概要

これまで Forkwell のイベントで登壇されたエキスパートの方々は、先達が記した書籍から「気づき」を得て実践し、振り返り、再現性のある「学び」として身に付けていく中で、実績を築いてこられました。

しかし、日々限られた時間の中で知識や情報をアップデートし続けるのはそう簡単ではありません。 Forkwell Library では、著者・訳者・実践者らを登壇者として招き、そんな思いを抱えた開発者の皆さまが「学びのきっかけ」を得られる勉強会を目指します。

今回の第9回目では2017年7月5日に出版された 『現場で役立つシステム設計の原則〜変更を楽で安全にするオブジェクト指向の実践技法』 を取り上げます。著者である増田亨氏をお招きして、「良い設計と悪い設計の違い」について、最近の技術動向にも触れていただきながらご説明いただきます。

会の様子

基調講演〜「良い設計と悪い設計の違い」〜

良い設計とは何か?

変更が楽で安全なものが良い設計だと考えているということで、この前提を持ってして、この後の話はされていきました。

このように考えている理由としては、ビジネスの特性やソフトウェアの性質上、常に変更要求は出てくるものであることや、開発者の学びを即時に反映できるタイミングや開発者の成長機会を増やしたいことが挙げられるというお話でした。

設計の良し悪しをどう判断するのか?

コードの不吉な匂いがあるかどうか?で判断するということでした。

具体的には、以下のような部分を気にしているそうです。

  • 怪しげな名前(ドメインを理解できていない兆候)
  • 長いメソッド
  • 大きなクラス/大きなパッケージ(ツールで常に確認するようにしている)
  • 可変性
  • 重複(計算処理、丸め処理、同じコレクションに対して同じ目的で操作しているのにstream, for文と処理がバラけている)
  • データクラス(getter/setterだけしかないコード)
  • 基本データ型の群れ
良い形の習得

具体的に習得すべき良い形として、以下が紹介されていました。

  • 値オブジェクト(計算ロジックの置き場所)
  • 区分オブジェクト(if文やswitch文の重複を防止する場所)
  • コレクションオブジェクト(for文、stream処理の重複防止)
  • 名前空間(規模が大きくなるほど重要になってくる、パッケージ構造やクラス構造を整理することで、業務知識の整理が可能)
良い形の背後にある背景

型/カプセル化/契約プログラミングの3つを背景として持っているということでした。

型は、操作の集合として値の種類を定義するもので、型を使用することで値の種類が分類できるという話がされていました。

カプセル化は、データ操作とデータの表現を同じモジュールに凝集させる考え方で、言語レベルでいえばクラス構文やメソッド構文として実現ができるというお話でした。

契約プログラミングは、クラス間の繋ぎ方を約束する考え方で、事前/事後で条件を指定したり普遍条件を指定することで制限をすることという話がありました。

設計原則と設計パターン

原則やパターンはあくまでも他人の経験知でしかないため、本で学んだパターンのうち、自身が実感できるようなものだけしか現場の実践では使えないということでした。

そのため、まずは手を動かすことが重要だというお話がありました。

分け方・集め方・つなぎ方

クラス&パッケージや、テーブル&スキーマの設計と実装とリファクタリングでコードレベルの原則とパターンとして理解し、単一のアプリケーションのアーキテクチャの実装/運用保守で中範囲の原則とパターンとして理解し、分散アーキテクチャの実装/運用保守で広い範囲の原則とパターンとして理解しようという話がありました。

なお、分散アーキテクチャを理解するにあたって、ソフトウェアアーキテクチャ・ハードパーツはめちゃくちゃ参考になるということで、増田さんは今後名著として君臨し続けていくだろうと予想しているそうです。

Q&A

Q&Aの内容に対して増田さんが回答してくれました。以下、常体で内容を書いていきます。

オブジェクト指向がmutableからimmutableへデータの取り扱い方を変えるようになった歴史的背景は?

メモリとCPUの値段にパラダイムシフトが起きて、メモリやCPUをガンガン積むことができるようになったことで、immutableなデータにすることが実用的になった。

技術者のレベル的に設計やアーキテクチャを意識するのが難しい場合、どうすれば良いのか?転職しかないか?

増田さん個人としては、転職をしてきた。
ただ、熱量が現場にあったりどうしても出れないなら、「良いアーキテクチャを意識しよう」「良い設計を意識しよう」ではなく、変更を楽にしたいならどうする?というのを考えるアプローチで推進する方がいいと思う。

システム設計のトレンドは変化しているのか?

これは見方による。天動説と地動説の話に近いと思う。

実態は何にも変わっていなくても人間の見方は変わりつつあると思う。
なので、実態や本質は変わっていないが、人間の見方は変わりつつあるのかな、と思っている。

人間の見方が変わっていく部分のキーワードは、「分散アーキテクチャ」だと思っている。

見方の変化などの情報はどうキャッチアップしているのか?

2-3年持たない技術ネタはたくさんある。
なので、新しいネタは基本的に2-3年後はなくなると思っている。

そのため、フィルタリングは意図的にかけるようにしている。
具体的には、この人面白いな、と思える人をフォローして、その人が興味を持っている内容をキャッチアップするようにしている。

また、増田さんは失敗が出始めた技術を現場では意図的に使おうとしている。
XXXバンザイ!ではなく、こういう問題が起きて厳しくなって失敗するけど、そこでこういうふうにするんだよ、という話が出たら使うようにしている。ソフトウェアアーキテクチャ・ハードパーツがお勧めできるのはそういう具体的な話が多いから。

リファクタリングでまとまった工数が厳しい現場にいる。少しずつリファクタリングすることはできるが、根本的改善にならない。。。どのように改善すればいいのか?

まず、少しの改善であっても意味がないことはないと思っている。

また、悪い設計や抜本的な改善が必要なソフトウェアに携わるのもスキルアップという意味では決して悪くはないと思っている。

なお、増田さんの持論だが、小さな積み重ねの改善(=リファクタリング)が根本的改善につながることはない。ストラングラーパターンはありだと思う。

実践的な学びを得るという意味で、OSSのコードを読むのは学びにならないのか?

OSSの設計ノウハウと業務アプリケーションの設計ノウハウは違うので、これを理解できているのならいいと思う。

具体的にいうと、業務アプリケーションの設計は非常に限定的な領域(ドメイン)の問題を解決しようとしている点に注意した方がいい。

また、正直なことを言ってしまうと、OSS*1の設計で良い設計になっているのはごく少数だと思っている。

増田さん書籍の続編はあるのか?

今の時点で発表できることはない。
ただ、色々発表機会をもらったりしてネタがあることは事実。

OOPやDDDの手法を取り入れる/入れないの判断はどうすればいいのか?メンバーの平均的なスキルのレベル?

取り入れるべきだと思う。
ただ、スキルが低いメンバーならほぼ間違いなく失敗するので、小さく失敗するアプローチを地道にやっていくことが重要。(例えば週2時間くらい実験的にコードをDDDのアプローチで書いてみるなど)

プログラミング未経験者に今日のような内容も教えた方が良いのか?

正直最近は接する機会は無くなってしまった。(増田さんは時代的にもかなり乱暴だったので、現場に放り込まれて勝手に学べ、というスタンスで育てられていた)
その前提でアドバイスするなら、アプリケーションの一部を小さく変えていく経験を積むのではなく、一つの業務アプリケーションを一通り作る経験をさせた方が良いのかな?と思う。

技術的負債を解消するコストをビジネス側に説明するのが難しいのだがどうしたら良いか?

一発でいい設計のものが作れると思っていないので、一度で作る前提ではなく、3回くらい作り直すような前提でコストを見積している。

軽量DDDのプラクティスやアーキテクチャだけ適用する手法についてメリット/デメリットを教えてほしい
  • ヴォーン・ヴァーノンの単語が広まっているんだと思っているが、「ヴォーン・ヴァーノンは軽量に開発しようよ、それがDDDだ」という説明をしているので、「軽量」という単語自体を問題視しているのはよくわかっていない。
  • 上記の理由から、値オブジェクトだけを実践してDDDだと言っている人を揶揄しているんだと思うが、値オブジェクトを業務知識なしで実践することができるとはとても思えないので、何を揶揄したいのかよくわかっていない。
  • 増田さんの経験だと、「ユビキタス言語大事だよ」と言っているチームと「値オブジェクト実践しようよ」と言っているチームなら、前者の方が失敗するチームが多いイメージ。なので、体感と全然あっていない
DDDを開発するならJava以外にお勧めがあるか?

「色々な理由はあるけれど、Java一択だと思っている」という発言を苦笑しながら話してくれました。

全体を通した感想

Q&Aセッションで後半にかけて熱が上がっていくような感じがあってワクワクしながら参加できました。

また、こういったエンジニアのアンテナを広げるような機会をどんどん提供してほしい、と最後に言ってくれていたのも増田さんらしい言葉で、すごく印象的でした。

*1:特に長く使われているような複雑度の高いOSS