Continuous Modeling

みなさまご無沙汰しております。僕はここの所、残業はしないまでも毎日クタクタになるほど忙しい毎日を過ごしています。どんな仕事か一言でいうと、あるプロダクトのアーキテクチャを刷新するお仕事です。今までできなかったあれやこれやを実現するために、既存のアーキテクチャを改善したり、作りなおすお仕事です。今はまだ始まったばかりで、方針を決めるために、既存のアーキテクチャ上に機能拡張してみて問題点を調査したり、どう改善するのか方針案を考えたり、実際に改善案を少しずつやってみたりしています。
このプロジェクトは、それほど大所帯ではないですが、他の会社のエンジニアさんも加わるなど、結構スキルセットがバラバラです。そのため、久しぶりにペアプロで作業を回しています。1日じゅうペアプロすると、一日の終わりの頃には頭がクタクタです。久しぶりです、この感覚。楽しい。
さて、既存のアーキテクチャを見ていくと、10年以上続いているプロジェクトなので、継ぎ足し継ぎ足し増築を重ねた温泉旅館のような風情を持ったクラスがゴロゴロあります。リリースする前に時間のプレッシャーに負け、十分にリファクタリングしきれなかった部分が積み重なり、かなり訳が分からない構造になっているクラスが結構あるわけです。10年以上前はJUnitが世の中に広まる前のコードなので、テストコードも十分にありません。ここに、ほんものの、れがしーこーどがあるぞ。
レガシーコード改善ガイドよろしく、テストコードを書いてリファクタリングを進めていく事もできます。しかし、いきなりその作業には入れません。今実現されている姿はこうなっているけど、本来どうなっているべきなのかを考える段階なのです。だから、どうやってアプリが実現できているのか、機能を拡張してみて問題点を探り、感じた問題点をチームに共有するために、2,3日に1回は朝会の後にモデリングのワークショップをしています。
思い返せば、以前自分が所属したアジャイルなプロジェクトでは割とモデリングをしてきていました。アジャイルソフトウェア開発宣言に記名した方々の多くはOOPSLAで発表するようなOOスペシャリストの皆さんです。実は、オブジェクト指向設計の技術がアジャイルソフトウェア開発の基盤技術です。
少し前の自分は、TDDで実装を進めれば自然といい感じのOO設計ができるんじゃないか、モデリングはしなくてもいいんじゃないか、と思っていました。でも、2,3日に1回、短時間のモデリングワークショップをしてみると、割とメンバー毎にコードに対して抱いているクラス構造が違う事が多く、メンバー間のモデル認識を揃える意味で、この活動は重要なんじゃかろうかと感じるようになりました。この活動の事を、Continuous Integrationや、Continous Deliveryという名前が流行しているので、僕はContinuous Modelingと名づけてみました。同僚からはDaily Modelingじゃないか、とか色々言われています>< Kanbanの中で毎日30分モデリングする時間を取ると品質が向上する、という話が書かれていたので、実践してみました。
ところで、ちょっと前に書籍「ドメイン駆動開発」を読み返していたのですが、この本の中では「オブジェクト指向はモデルをコードに表現するための手段」と言うような事が書かれていました。(正確な表現は失念しました。スミマセン。)ただ、僕はこの表現に「我が意を得たり」と膝を叩きました。クラスに責務を割り当てたり、適切な名前をつけるのは、会話の中で登場するモデルをコードの中に表現するための活動だったんですね。
自分が考える良くないコードの代表例の1つは、モデリングを全くせずに拡張を続け、一つのクラスに様々な責務を割り当ててしまう、と言うものです。言い換えると、1つのクラスにだらだらと処理が書かれているクラス。メタファに例えるなら、クリスマスのプレゼント袋とか、福袋というものでしょうか。(これを僕は「モデルが薄まったクラス」と表現してみたものの、同僚から「よく分からない」と言われました。名前付けはいつも本当に難しいですね。)要求が実現されているので、確実に役に立つものが中に入っているけど、妥当な名前がついていないから中に何が入っているか分からない状態になっている状態。後で機能拡張する時に処理を追いかけてみると、なんかよくわからないけど呼ばれているコードとか、ありませんか?そういうクラスです。こういうクラスが、コードの中にモデルをうまく表現できていないクラスです。
オブジェクト指向設計は、いかにこういう責務が曖昧なクラスを減らし、明確な責務をクラス構造に落としこみ、コードに実装するか、という活動なんじゃないかと最近考えるようになりました。だから「チーム」で「定期的」に「モデリング」を行う事が割と重要だと思うのです。
チームでモデリングする、と言ってもそんな大した事をしていません。ホワイトボードの前に立って共有したい疑問点や、違和感をUMLなどのモデル図に描きだしてみます。モデル図は、あくまで概要的なもので、どこに違和感があるのか、疑問点があるのか、解説しながら描いていきます。そうすれば、単に解説を口頭で話をするよりも、どこの話をしているのか指し示せたり、関係を目に見える形で議論できるので、より具体的に話を進められます。こういう疑問点や違和感の共有が、より良いオブジェクト指向設計について議論するきっかけになるので、単に構造を改善に留まらず、オブジェクト指向設計のスキル伝達になるような教育も兼ねられます。
例えば僕はどんな事に違和感を感じるのか、例をあげてみます。

  • 構造的な違和感
    • 分割すべき責務
    • 過剰な継承
      • 継承階層が深くなると、上位クラスの変更が下位クラスに影響を及ぼす事が増えるため、修正が難しくなる
    • 過剰なif文の改善
    • 過剰なユーティリティクラスの導入
      • モデルが知っているべき情報や処理であれば、モデルに移しましょう
    • 適切なパターンの導入
      • ValidationをStrategyパターンにする
    • 過剰なパターンの導入
      • 特に不要なSingletonに注意する
    • 過剰なinstanceofによるStrategyの切り替え
      • クラスとStrategyをEntryにしたMapの導入
    • 類似クラスの発見
    • アーキテクチャを拡張するようなレイヤーの発見
  • 振る舞い的な違和感
    • 相互関連から片方向関連へ
    • 循環参照の解消
      • 相互にメッセージが飛ぶ構造は理解しづらさを生む。メッセージが片方向から流れるようにモデルの振る舞いをとらえ直す
      • コミュニケーション図を描いてみる
    • 実装を共有するための継承
      • 委譲を使うようにする。
  • 整理すべき依存関係
    • 過剰に多くのクラスに依存したクラスの発見
    • パッケージ間の依存を整理する
      • インタフェースやAdapterの導入による実装の隠蔽
      • コンストラクタやメソッドのパラメータ数の削減
        • パラメータオブジェクトの導入
  • テスタビリティを向上させるための試み
    • 依存するオブジェクトの削減
      • fieldに保持するオブジェクト数が多いとsetupしづらいクラスになる
    • テストケースが多い実装は責務過多の兆候
      • 新たな責務を抽出し、クラスを作成し、テストケースを分担する
    • 過剰なUIへのアクセス
      • Strategyパターンを導入し、テスト中はテストダブルに置き換える

割とこういう事はこれまでの開発経験によって異なってくると思うので、一度チームのメンバーで話し合ってみると面白いでしょう。ということで、今日はContinuous Modelingを紹介してみました。オブジェクト指向の設計力を向上させたいチームは、試してみてください。

オブジェクトデザイン (Object Oriented SELECTION)

オブジェクトデザイン (Object Oriented SELECTION)

  • 作者: レベッカ・ワーフスブラック,アラン・マクキーン,株式会社オージス総研藤井拓,辻博靖,井藤晶子,山口雅之,林直樹
  • 出版社/メーカー: 翔泳社
  • 発売日: 2007/09/13
  • メディア: 大型本
  • 購入: 3人 クリック: 52回
  • この商品を含むブログ (41件) を見る

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)

  • 作者: マイケル・C・フェザーズ,ウルシステムズ株式会社,平澤章,越智典子,稲葉信之,田村友彦,小堀真義
  • 出版社/メーカー: 翔泳社
  • 発売日: 2009/07/14
  • メディア: 大型本
  • 購入: 45人 クリック: 673回
  • この商品を含むブログ (145件) を見る

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)


Clean Code アジャイルソフトウェア達人の技

Clean Code アジャイルソフトウェア達人の技


Kanban

Kanban

Kanban vs Scrumを訳しました。

InfoQ Japan 2009で講演されたHenrik Kniberg氏の「Kanban vs Scrum」の翻訳をid:wayaguchiさんと共に行いました。Henrik氏は「塹壕より Scrum と XP」の著者としても有名で、最近はカンバンについても色々話されているナイスガイです。
原本(Kanban vs Scrum)

自分はこの資料を訳すために下記の本を読みました。

アジャイルソフトウェア開発 (The Agile Software Development Series)

アジャイルソフトウェア開発 (The Agile Software Development Series)


ザ・トヨタウェイ(上)

ザ・トヨタウェイ(上)


アジャイルソフトウェア開発には、宮本武蔵の引用があり、アリスター・コーバーン氏が深く感銘を受けて付録としたため、海外ではよく引用されているようです。「武器や流派にこだわるな」と訳しているあたりです。世の中にはいろいろなプロセスはあるけれども、プロセスはあくまで仕事を回すためのツールであり、必要な場面で必要なものを選択すればよい、というようにHenrik氏は言いたいんだ、と僕は理解しました。スクラムやカンバンこそが素晴らしい、という原理主義なエバンジェリストになっちゃだめってことなんでしょうか。一緒に働くチームや、お客さんに合わせて僕等はプロセスを変える事をためらっちゃダメなんです。スクラムアジャイルの導入としてやりやすいという話を聞きますが、アジャイルやることが目的じゃなくて、お客さんにとってよりよいソフトウェアを提供する事が目的な訳です。もしお客さんがスクラムのやり方についていけないのであれば、ついていけない部分はやり方を変えて歩み寄らないといけないんじゃないかと思う訳です。
トヨタウェイは、リーンの14の原則を引用していたため、それを訳すために読みました。トヨタウェイの中にはプリウスの開発についても描かれていますが、大部屋に全ての情報を集め、2日ごとに集まって色々決めていったことで1年半という短期間で新技術を使って量産工場を作ったという物語がありました。物語の中では部署をまたいで活躍する技術者の話だったので、カンバンというよりもスクラムっぽい匂いを感じましたよ。
大部屋を作るプラクティスもプロセスに依存した話じゃないんじゃないでしょうか?>id:wayaguchiさん
僕がこのスライドから感じたことはこんな事なんですが、みなさんどんなことを感じましたか?自分たちのやり方で、こんないい方法があるんだよ、と言うものがあれば、ぜひ教えてくださいね。

オブラブ忘年会をふりかえって一つだけ言いたいこと

最後のあいさつの時に平鍋さんから、「オブジェクト倶楽部って言ってますが、オブジェクト指向の話がそんなになくてごめんなさい」という話がありました。でもオブジェクト指向アジャイルってそんなに離れてない気がしてるんですが、どうなんですかね。

どちらも構成要素を活性化するためのお話だと思うんです。並べてみるとなんとなくその気になります。

オブジェクト指向の中だと、オブジェクト指向はクラスやインスタンス・オブジェクトの一つ一つをよりよく活性化させるための技術です。最初シーケンス図にあるインスタンスの活性化って奴がよく分かんなかったんですが、こじつけられそうじゃないですかと。インスタンス・オブジェクト同士のコラボレーションを期待したソフトウェアの設計指向です。インスタンスのコラボレーション、メッセージパッシングによる網によってソフトウェアの品質を担保します。
アジャイルの中だと、アジャイルとはチームやメンバー一人一人が活躍するためのプロセスです。プロセスって言うと正直拒否反応をする自分です。なのでプロセスではなく、やり方と言い換えましょうかね。一人一人の自主性や規律を重んじる文化の中で、開発者のコラボレーションを期待したやり方です。コラボレーションという、コミュニケーションの網によって、ソフトウェアの品質を担保します。

そんな風に思うんですけど、同じように思う方ってそんなにいないのかね。

追記:
構成要素って書いてみましたが、別に歯車になろうっていうわけじゃないっす。歯車になるんだったら駆動する側になろうぜと。