Laravel JP Conferenceで『抽象化って何?』というトークをしました
2019年2月16日に開催されたLaravel JP Conferenceで『抽象化って何?』というトークをしてきました。
トーク内容
数独アプリの正解チェック機能をお題にして、以下の3つを目標に話しました。
- 現実世界における抽象化とはどのようなことなのか、理解する
- プログラミングにおける抽象化とはどのようなことなのか、理解する
- 抽象化の指針を知り、抽象化の良し悪しを判断できるようになる
このトークの中で、以下の3つを、「プログラミングにおける問題の抽象化の指針(仮)」とし、説明しました。
- 適切な命名:名前と内容が一致していること
- 抽象度の統一:ある側面が取り出されたものだけで辻褄が合うこと
- 狭い範囲:考慮する特徴の数が小さくなっていること
参考書籍:S・I・ハヤカワ「思考と行動における言語」
振り返り
- 参加者の皆さんがやさしかった(小ネタ的な部分で、笑い声が聞こえると、発表側はすごく安心します)
- 会場の設備は非常によかったが、若干スクリーンの位置が高かったたため、スライド内のコンテンツは上下で中央寄せくらいで作る方がよかった(上寄せ目に作っていたため)
- 発表の時間が若干オーバーした(少し早めに始めさせて頂いたので、なんとかなった)
参加者のみなさんから頂いたフィードバック
懇親会その他で、私のトークを聞いて頂いた方からいくつかフィードバックを頂きました。主に要改善内容を自分用メモとして以下に書いておきます。
- お題がLaravelのものだとさらに良かった
- 最後の改善後コードのAdapterのところが省略されていたが、そこがあった方がわかりやすいと思う
- 改善後のコードの全体像が分からなかった
- パフォーマンスとの両立はどうなるのか気になった
これ以外にも、良かった、勉強になったとたくさんの方からコメント頂きました。どんなものでも、フィードバックは発表者にとってとても貴重です。ありがとうございます!
カンファレンスの良かったところ
偶然なのかもしれませんが、今回のLaravel JP Conferenceでは、比較的長い時間いろいろな方と話せました。スピーカー控室があって、楕円形の丸テーブルがある部屋でした。その部屋は、カンファレンス空間からやや隔離されていて、比較的静かだったこともあり、居心地がよかったです。他のスピーカーの方と、その控室でいろいろな話をしました。
また、発表後のAsk The Speakerでも、かなり長い時間お話をしました。これも、Ask The Speakerの部屋が比較的静かで、話しやすい雰囲気だったからだと思います。
昨年PHPerKaigiに参加したときのブログでも書きましたが、私がカンファレンス参加やコミュニティ参加に求めているのは、コミュニケーションです。しかし、単にカンファレンスに参加すれば十分にコミュニケーションできるかといったらそういうことはなく、発表する側にまわったり、その内容に興味を持つ参加者がいらっしゃったり、そして、コミュニケーションできる場といった、偶然が重なってようやく成立することだと思います。ですから、今回のLaravel JP Conferenceで、いろいろな方とじっくりコミュニケーションできたのは、個人的にとても良かったです。
おっさんトークのニーズ
懇親会等で何名かの方とお話する中で、以下のような話もしました。
- 私が35歳で決意したこと
- 私が技術者として大きく成長するきっかけになった師匠たち
- 私が今モチベーションを持って取り組んでいることとそのきっかけ
このような、いわゆるおっさんトークを求めている方も一定数いらっしゃるように感じました。こういう話は大勢の前で話すものではなく、一対一で、お互いのことを話す過程で自然と出てくるタイプのものですよね。興味のある方は、カンファレンスの場などでぜひお声がけください。
ありがとうございました!
すばらしいカンファレンスに関わった、スタッフの方々、参加者のみなさん、スピーカーのみなさん、ありがとうございました。
次回は、3月末のPHPerKaigiで、同じタイトル(内容はバージョンアップします)で講演予定です。
モデルベース要件定義テクニック(RDRA)
技術顧問先のエンジニアからの薦めで、神崎善司さんの『モデルベース要件定義テクニック』を読んだ。この書籍では神崎さんの要件分析手法であるRDRA(Relationship Driven Requirement Analysis:ラドラ)の実践方法が解説されている。
RDRAの手法自体の特徴などを、自分のメモとしてまとめておく。
※ 手法の具体的な内容について知りたい方は、書籍やWebを参照されたい。
RDRAについて
RDRAは一言で言えば「要件分析・定義のフレームワーク」だ。つまり、次の事柄が提供されている。
- 要件分析〜定義の活動において必要な事項の全体像が示されている
- 事項間の関係性が示されている
- 個々の事項の目的(それが必要な理由)が示されている
長年の実務経験のノウハウから抽出されたフレームワークだと思う。要件分析〜定義の活動を効率よく進めるために必要なことがうまくまとめられている。
RDRAは特に、以下の点にフォーカスしたフレームワークだ。
- 網羅性
- 整合性
- 表現力
(書籍やWebにも、RDRAの背景としてこの3つが挙げられている)
RDRAでは、要件分析〜定義活動によって以下の4つをクリアにしていく。
- システムを使って生み出す価値
- システムを取り巻く環境
- システムとの接点
- システムそのもの
この4つのすべてに対応する図の表記方法が用意されており、活動の広範囲をサポートしていると言える。また、ある図に記載する内容と、別の図に記載する内容との関係性が定義されており、整合性のフィードバックが働くようになっている。
RDRAによって得られるもの
- 要件分析〜定義工程の進行をスムーズにできる
- 要件分析〜定義工程の成果物のクオリティを一定以上にできる
- 上記を、KKD(勘と経験と度胸)に頼らずに、非属人的なノウハウとして利用できる
- 要件分析〜定義工程の全体像を伝えやすくなる
現場で試して学んでいきたい。
2018 retrospective
サクッと振り返る2018年。そして来年のチャレンジ。
アウトプット
カンファレンストーク:3
ブログ記事:16 (このブログ) + 1 (メルカリ)
仕事
- 株式会社メルカリへ転職
- 技術顧問開始(アジアクエスト株式会社)
趣味・生活
- カンファレンスアフターツアー(6月大分、7月京都)
- ジム復帰&食生活改善開始
- 東京で生活開始(10月中旬〜)
- 東京でもジム契約
来年のチャレンジ
- カンファレンスまたは勉強会でのトーク: ソフトウェア設計 (1)、Microservices (1)、Go(1)、マネジメント (1)
- ブログ記事:ペース維持(月1以上)、マネジメント、Microservices、Goについての記事を書く。英語で記事を書く。
- ジム:週3回以上
- 仕事:Go Bold、All for One、Be Professional
DIPの定義を考える
ソフトウェアの設計原則には分かりづらいものが多い。主な原因は、以下だと考える。
- 原則が生まれた当時の内容のまま、現代に伝わっている
- 原則の説明が十分に抽象化、本質化されていない
最近TwitterでDIPに触れているtweetを目にした。DIPを十分に理解している方も多くなってきていると思うが、それでもやはりこの「原則」は、依然分かりづらいままになっているのだと思う。これを機にDIPの整理に着手してみることにする。
例えば、「開放閉鎖原則」と「依存性逆転の原則」って、本質的に同じでは?(要出典
— at_grandpa (@at_grandpa) 2018年12月20日
DIP、一度は「完全に理解した」って思ったのに30分後にそれが消えてしまってそれ以来5年以上経つのに「理解」が帰ってこない。定期的に呼び戻そうと思考実験するんだけど今日もだめだった。悟りみたいなもんなのかな
— ななうぇぶ (@77web) 2018年12月21日
DIPの定義
DIP:Dependency Inversion Principle(依存関係逆転の原則)は、Robert C. Martinの1996年の論文によると次のように定義されている。
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.(上位レベルのモジュールは下位レベルのモジュールに依存すべきではない。両方とも抽象(abstractions)に依存すべきである。)
B. Abstractions should not depend on details. Details should depend on abstractions.(抽象は詳細に依存してはならない。詳細が抽象に依存すべきである。)
Dependency inversion principle - Wikipedia
これが定義だと言われても分かりづらい(分かりづらいからなのか、書籍Clean Architectureではこの定義は使われておらず、サラッとした説明のみとなっている)。この定義から、言わんとしていることをフワッと理解できても、本質的に何のことを言っているのか捉えづらいだろう。違和感を生む単語も混ざっている。論文が提出された時代には、プログラマたちに共通する教養として「構造化分析・設計」があった。その時代であれば、上位レベル、下位レベルといった言葉には共通認識があった。しかし現代のソフトウェア構造は複雑になり、その複雑な構造を扱うための新たなアーキテクチャも登場してきている。現代のソフトウェア構造において、上位下位といった形を前提に語ってしまうと、そこで混乱を生む。また、抽象や詳細といった言葉についても、対象を限定しすぎている。
そして何より、この原則の定義方法の弱さが最も大きな問題だろう。定義が「異常状態と正しい状態」を併記する形でしか書かれていない。この書き方ゆえに、DIPを「ソースコードのある種の状態を、良いか悪いか判定するためのルール」だと解釈してしまうのだと思う。
DIPは、状態判定のためのルールではない。悪い状態から良い状態への「変更操作そのもの」を表している、と見た方がしっくりくる。その変更操作を行えば、ソフトウェアの状態を改善できると言っているのだ。整数の加算や乗算に可換則(交換可能)が成り立つというのと同じようなニュアンスになる。つまり、法則なのだ。
まとめると、DIPは、ソフトウェアのモジュールが別のモジュールに依存している時、依存の特徴だけを抽出したより安定度の高いモジュールに両者を依存させるように書き換えることができる、という法則だ。
この「書き換え可能性」がDIPの本質だと考える。そして、この書き換え可能性は、さまざまな目的に利用できる。ソフトウェア構造全体としての安定性を高められるし、OCPが言うようなソフトウェアらしいモジュール性を実現する際にも役立つ。
Robert C. Martinは1996年の論文の結びで、次のように書いている。
The principle of dependency inversion is at the root of many of the benefits claimed for object-oriented technology.
Robert C. Martin "The Dependency Inversion Principle"
DIPは方法である。そしてそれは、ソフトウェア開発における偉大な発明だ。
安定度とは何か
さて、私のDIP定義では「安定度」という言葉を使った。安定度を別の言い方にすると、その要素が「変わらない度合い」だ。プログラミング言語のコア要素であるほど、一般的には安定度が高い。プログラミング言語が提供するユーザー定義要素の場合は、特徴によって高い安定度を持ちやすいものと、そうでないものとがある。また、ユーザー定義要素においては別の視点として、そこに含まれる可変要素の数も安定度に影響する。要素の数が多ければ、客観的可能性として変更が発生する確率が高くなり、安定度は低いといえる。
昨今のクラス指向プログラミング言語であれば、おおよそ次のような順に安定度が高いといえる。
- プログラミング言語に内蔵された言語要素
- プログラミング言語に内蔵された標準ライブラリ
- ユーザー定義のインターフェイス
- ユーザー定義のクラス、ユーザー定義の関数、ユーザー定義の抽象クラス
「ユーザー定義の抽象クラス」はよく議論の俎上にあがる。抽象クラスは、高い安定度が求められる位置づけにあるにも関わらず、サブクラスの要件を一手に引き受けてしまい、結果として変更頻度が高くなることがある。これでは、低い安定度しか持ちえない。これは下手な事例だとしても、一般的に抽象クラスの安定度を高く保つのは難しい。だから基本方針として抽象クラスを使うことを避け、interfaceといった、制約が強く、高い安定度を保証しやすい要素を使う方向へ時代は進んだ。
DIPは、「具象ではなく、抽象へ依存するように書き換えること」というルールだと理解されていることが多い。具象クラスへ依存している箇所を、interfaceを介する形に書き換えるということだ。もちろん、この書き換えは可能で、それによってソフトウェア構造の安定度を高めることはできる。しかし、一律にinterfaceを使って書き換えればよいという理解では、本質を見失ってしまう。肝要なのはあくまで「ソフトウェア構造全体としての安定性」を達成することだ。
おわりに
DIPについては、緻密に考えれば他にもいくつか議論になるポイントがある。特に、2つのモジュールを仲介する安定度の高い存在を、どのように定義するのか、どこに所属させるべきなのかといったあたりだ。 このような議論も緻密に検討していくことで、設計原則の働きを具体的に捉えることができる。引き続き検討してみたい。
ところで、今回行ったDIPの定義の改善では、もともとの定義文にあった「具象要素」を、DIPの表現により適切と思われる抽象要素に置き換えた。これは、日本語の文章に対して「具象ではなく抽象に依存せよ」というルールを適用したことに相当する。DIPはこの操作のソフトウェア版に相当するとも言える。安定した構造を生み出す普遍的な法則の共通性として興味深い。
参考