天の月

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

春の復習ランチタイム#6「分岐を低減するinterface設計と発想の転換に参加してきた

forkwell.connpass.com

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

会の概要

以下、イベントページから引用です。

プログラミング言語にはinterfaceやそれに類似する、抽象的に扱うための仕組みがあります。interfaceを駆使すると分岐が減り、変更が楽になります。

しかし現状の開発でinterfaceは有効に用いられていますでしょうか。仕様変更時、「既存ロジックにむりやりif文をねじ込む」「分岐が異常に複雑化する」といった実装になっていませんでしょうか。分岐の複雑化は変更容易性を著しく低下させます。

interfaceをどういう状況で用いればよいのか観点が不十分なのが原因だと考えられます。interface設計には大幅な発想の転換が必要です。

この講演では、interface設計に必要な考え方について解説します。

会の様子

目的単位で抽象化する

システムには必ず何かしらの目的があるため、システムの構成要素(例えばクラスなど)にも必ず目的があるという話がありました。
更に、目的を達成する際には何かしらの課題とその課題に対しての対応策がセットで必要になってくるということです。

また、実際のシステムでは一つの目的/課題に対して、それらがツリー構造でブレイクダウンされた目的/課題が出てくるため、仕様ごとに目的/課題を整理していくことが重要だというお話も出ていました。

「作る」と「使う」を分ける

良くないロジックは、何を使うのか判断する分岐と何を実行するかのロジックが混在してしまっていることが多いという話がありました。

そのため、「作る」→「作ったものを使う」という風に分類するのが重要だということが話として出ていました。*1

目的のバリエーションと機能性

同じ目的であっても、達成手段それぞれで性能が全く異なるため、自分たちは同じ目的であっても性能を使い分けることが多くあるということでした。

そのため、interface設計可能な箇所は機能性を向上させることができる可能性を示唆している場所であるとも言えるし、より顧客にリーチする機能に置き換えられる可能性を秘めている箇所であるとも言えるだろうということです。

このルールにしたがってinterfaceを設計することができると、より高機能なものに素早く書き換えられるようになり、開発生産性が高まるだろうというお話でした。

interfaceを使うときの注意点

あくまでも目的手段のバリエーションとして利用することが重要で、分岐が複雑だからinterfaceを使うというのは、コードがぐちゃぐちゃになってしまうリスクがあるため注意したほうがよいということでした。

参考書籍

最後に参考書籍の紹介がありました。

Q&A

発表の後はQ&Aセッションがありました。以下、内容を常体かつ一問一答形式で記載していきます。

インターフェースを実装したことがあるのだが、PhpStormなどでコードジャンプするとインターフェースのメソッドに飛んでしまうため、インターフェースはいらないと思う

追わなくても良いクラス(=完成品として作られているクラス)を実装するのが重要。(例えば標準ライブラリなどは中身を追いたい場面が少ないはず)

interfaceは一度広く公開してしまうと変更するのが難しくなる。どのような対策があるのか?

新しいクラスを公開し、古いクラスを非推奨とするのが対策の一つとしてある。(ストラングラーパターン)

目的と解決手段、及びその具体化と抽象化をモデリング言語化する技術力を高めるために最初にやるべきことは?

ビジネスの目的を知るためにドメインエキスパートに話を聞きに行くのが重要。

今日の話はRubyなどインターフェースがない言語で使える話か?

メソッド名が被ったりすることはあるはず。そのため、Rubyでもモジュールをインターフェースの代わりとして使うようにしている。

interfaceに引数やレスポンスを生やし始めると一部しか使わない引数が出てくることがあるのだが、これは設計が悪いのか?

目的が単一になるように分析すれば防げるはず。

抽象化する方法としてAbstractを使う方法もあるが、どう使い分けているのか?

抽象クラスは密結合になりやすいので、抽象クラスをあまり使わないようにしている。

早すぎる抽象化は負債になりかねないと思うが、うまい抽象化を見つけるためにどういうコツがあるのか?

まずものを作ってみて、作ったものを見てやばい臭いを感じ取ることができたら抽象化をするようにしている。

拡張可能性とYAGNIのバランスは?

これもやはり、一度作ってみた上で将来的にどうなるのか?というのを考える必要がある。

会全体を通した感想

質疑応答の内容から、皆さんの現場でも苦しみがだいぶ感じ取れるセッションで、色々と闇の深さを感じました。

ソフトウェアプロダクトラインエンジニアリングはまだ読んだことがなかったので、読んでみようと思います。

*1:作るクラスの例としては、Factoryなどが挙げられる