実践 ICONIXプロセス : モデルと同期する

コードを書きはじめると、コードの世界だけに没入しがち。

コードレビューや、リファクタリングでコードを修正したら、必ずモデルと同期をとりましょう。

ユースケース記述との同期

コードは、ユースケースを実現するためにあります。
ユースケースのアクションステップを実現するのは、どのクラスの責務で、どのメソッドを使うかのチェックを必ず行いましょう。

詳細クラス図との同期

設計は、コードで表現できていますが、詳細クラス図でも表現しましょう。
コードと絵という異なる方法で表現すると、問題点を発見しやすくなります。

コードと詳細クラス図との同期は、Enterprise Architect などのモデリングツールを使えば、意外と簡単です。

コードを更新して、同期をとると、詳細クラス図を自動的に更新できます。
そして、更新結果を詳細クラス図という別の視点で見直すと思わぬ発見があります。

---

ICONIXプロセスの品質確保の考え方は、

・複数の表現方法を使って、照らし合わせる
・複数のメンバーの視点でチェックする

の2点です。

実践 ICONIXプロセス : コードのチェックリスト

私の個人的なコードレビューのチェックリストです。

3行ルール

3行を超えたら、改行する。別ブロックにする。
import 文にはじまり、フィールドの宣言、メソッド内のロジック、if ブロック内のコード、どこでも、連続していいのは、3行まで。

3行を超えていたら、グルーピングを考える。
5行以上、改行やブロックの区切りがなかったら、まちがいなくNG。

メソッドでくくり出したり、2つ3つの変数を持つ小さなオブジェクトを設計するなりするべき。

重文禁止

if 文で、 || や、&& で評価式を連結するのは禁止。
最低限、評価メソッドで外だしにする。
評価メソッド内でも、原則使わない。

重文はバグの巣ということを経験的に分かっているから。(特に修正時)

複文禁止

object.get().get().get() は禁止。
3つの文に分解する。それぞれの get() メソッドで取得するオブジェクトを一次変数で明示する。
変数名はもちろん、意味のある名前をつける。

入れ子の禁止

if文のなかの if文。
if文のなかの for文。
for文の中の if文。

メソッドでくくりだすことを考える。
入れ子もバグの巣であることを経験で知っているから。

ゼロパラメータ

メソッドのパラメータは、ゼロが最も良い。

2つ以上だったら、一つのオブジェクトにカプセル化することを考える。

一つだけのパラメータは、そのパラメータのオブジェクトにメソッドを移動すると、ゼロパラメータになる。

クラスの責務設計、メソッドの割当が洗練されてくると、ゼロパラメータのメソッドが増えます。

パラメータがずらっと並ぶメソッドは、アンチパターンです。

名前はフルスペル

パッケージ名、クラス名、メソッド名、フィールド名、一次変数名、すべてフルスペルで書く。
習慣的な短縮形も使わない。(悪い習慣)

他の人の短縮形を理解できずに保守に苦しんだことが何回もあるから。

コメント禁止

名前をフルスペルにしても、まだコメントが必要?
名前がたぶんおかしい。

まあ、英語の訳語を注釈することが良い時があるかもしれない。

実践 ICONIXプロセス : コードレビューの手順

コードレビューのミーティングを効果的に行うためのガイドライン。
時間を無駄にしないためのテクニックですね。

事前に読んでおく

レビュー対象物は事前に配布し、レビュアーは事前に読んでおき、チェックポイントはマークしておく。
一人でできる作業は事前に済ませておいて、みんなで集まっている時間をムダにしないようにする。

チェックリストの有効活用

すでにあるチェックリストの項目番号などでマークしておく。
個別の課題ごとに、どういう点が問題かの説明をはじめるのは時間のムダ。
すでに検討済みのチェックリストを最大限利用しましょう。
チェックリストがあっても、人間だから、ミスや見落としがあって、コードに同じ問題がでてくる。

レビューは検出だけ

前に書いたとおり。
修正方法の議論や実際の修正作業は別セッションにしたほうが効率的です。
Do one thing, do it well.

アクションリスト

検出結果は、アクションリストとして作成する。
コードの印刷物の蛍光ペンのマーキングでも十分です。
ただ、個数は確認しておきましょうね。

フォローアップミーティング

アクションリストの実行結果をもう一回レビューする。
フォローアップミーティングを必ず設定する。

ツールの活用

コードとモデルの同期とか、修正箇所の一覧作成とかはツールの機能を使いこなせば、自動化できます。
使える機能は積極的に活用して、みんなで楽をしましょう。

実践 ICONIXプロセス : コードレビューのチェックリスト

コードレビューをしていると、最初は、まあ、いろいろでてきてたいへん。
特にコーディングの規約やスタイル。

ベースラインを確立する

開発メンバーがいろいろなところから集まってきて、まだチームになっていないプロジェクトの初期では、特にそうですね。考え方、スタイル、こだわりポイントが違うから。

最初は、それぞれの意見の違うところ、一致しているところを、まず棚卸して、それをリストにすることからはじめましょう。

一致しているところは良いけど、スタイルが違うところはどうするか?

まず、自分は意見は異なるが、決まればそれに従える項目を洗い出します。ほとんどの項目はそうなると思います。
(タブのサイズなんて、どっちでも良い話でしょう?)

後は、そのソフトウェアに将来、一番責任を持つべき人間を選ぶ。リリース後の変更や改良の責任者。
その人の決定に従う。その人は、現在の開発メンバーではないかもしれません。また、まだ未定かもしれません。

重要なのは「保守する人」の利益を考えてコーディングの規約やスタイルを決めること。
開発者が気に入らないやり方でも、保守する人がやりやすいようにすべきです。
なんといっても、ソースコードを真剣に読んで格闘するのは、保守をする人ですから。

これがチェックリストのベースラインになります。

チェックリストを発展させる

あとは、コードレビューを繰り返しながら、発見した課題をコードレビューのチェックリストに追加していく。
結構、パターンが決まってきます。ある程度やっていると、チェックリストへの追加はほとんどなくなります。

チェックリストは、適度にグルーピングしたり、重要度のマーキングをしたりして、洗練させていきましょう。

こういうレビューチェックリストの改良作業を、チームメンバーでいろいろ話し合うことで、共通の価値観がだんだん醸成されます。役に立つソフトウェアを楽に開発するための、チームの財産になります。

実践 ICONIXプロセス : ユースケース駆動のコードレビュー

コードのレビューもユースケース駆動でやるべし。

レビューの対象

まず、コードレビュー対象とするユースケースを決める。
そして、そのユースケースを実現しているクラスをレビュー対象にする。

ロバストネス図のコントロールに対応するメソッドを持つクラスを探せば、対象クラスをより詳細に特定できる。

もっとも、対象クラスの特定にそこまで必要だとしたら、設計を再検討したほうが良い。
アンチパターン「小さいなオブジェクトの海」になっちゃている可能性が大きい。

ユースケースとそれを実現するクラスとの対応が簡単に取れないとしたら、設計に問題がある。

モデリングツールで、ユースケースとクラスを「実現」関係でモデリングする、という意味ではないです。
そんな作業をしなくても、ユースケースとクラスは簡単に追跡できる名前とパッケージ構成になっているべき、ということでです。

ユースケースとメソッドを対応づける

ユースケースの一つ一つのアクションステップに対応するメソッドを探しながら、メソッド内容を確認します。
ユースケースのアクションとクラスのメソッドの対応づけが簡単にできなかったら、設計に問題がある警報だと考えます。

ICONIXプロセスでは、詳細設計は、ユースケースと対応させたシーケンス図を描きながらクラスに操作を割り当てます。ですから、クラスの操作(メソッド)とユースケースのアクションとは簡単に対応づけができます。

それができない、やりにくい、ということは、ユースケース---設計---コード、のどこかで、不整合が発生しています。

コード、特にメソッドは、ユースケースを実現するための振る舞い記述だということを徹底しましょう。


実践 ICONIXプロセス : レビューは検出だけに集中

ICONIXプロセスのコードレビューのガイドラインで「レビューは検出だけに集中する」べきだとしている。
別の言い方をすれば「修正作業はすべて後回しにする」ということです。

レビューを効率的に進める重要なテクニックですね。

ソースコードを印刷して、指摘箇所を蛍光ペンでマーキングする。なにを指摘しているか曖昧なら、簡単なメモを書く。

この作業に集中すれば、コードレビューの時間はそれほどかかりません。
どうやって直すべきかとかいう議論も必要ですが、それは、検出の時にはやらずに、後でやる。

ICONIXプロセスでは、一つの作業を単純化して集中することを繰り返し強調しています。関心ごとの分離ですね。
コードレビューでは、まず、問題と思われる箇所のピックアップに集中する。途中で修正方法の議論をしたり、そのチェックが妥当かどうかのチェックはしない。

指摘箇所の検出が終わったら、ほとんどの箇所は、おそらく議論の余地がない、単純な修正箇所。それは各作業者のアクションアイテムとして割り当てる。コードを最初に書いたメンバーと別のメンバーが担当するほうが良いでしょう。(ペアプログラミングの変形かな?)

議論が必要な指摘箇所がある。それは「要検討」マークをつけて、検討会議をセッティングする。もちろん、指摘事項検出セッションに続けてやっても良い。
大切なのは「検出フェーズ」と「議論フェーズ」を明確にわけること。

実践 ICONIXプロセス : 警報が鳴っている

コードのレビュー、コードとモデルも修正、そのフォローアップ。
そんな時間が取れない。最初は私もそう思いました。

でも、ICONIXプロセスでは、ほんとうは、コードレビューとモデルの修正は短時間でさらっと終わる作業のはずなんです。

さらっとできないとしたら、それは警戒警報です。

・プロセスのどこか(コードを書く前)に問題がある
・開発メンバーに、技術的な取り決めが浸透していない
・レビューのやり方がおかしい

コードレビューがたいへんだと感じたら、この三つの視点で自分たちのやり方を見直しましょう。

私たちの場合は、最初は、三つとも問題でしたし、今でも、程度の差はあれ、三つの問題が残っています。
でも、最初のころに比べたら、コードレビューの時間は明らかに短縮してきている。

ICONIXプロセスのやり方と、実装技術(アーキテクチャ)にだいぶ習熟してきた証しだと思います。

実践 ICONIXプロセス : レビューと修正がたいへん?

ICONIXプロセスのガイドブック「ユースケース駆動開発実践ガイド」を読むと、

・コード内に閉じたレビュー
・設計とコードの同期のレビュー
・ユースケースをコードで実現しているかのレビュー

を徹底的にやるように書いている。

時間がかかりそうで、実践的ではない?

私も最初はそう思いました。
実際にやってみると、やっぱり時間がかかり過ぎる。
指摘事項は多いし、問題点を見つけたらコード修正だけでなく、モデルの修正やプロセスの改善までやるのは、負担が大きくとちょっと現実的ではなかった。

でも、今は、状況は改善してきています。
改善のポイントは以下の3点でした。

コードを書く前の作業

ドメインモデル、ユースケースモデル、要求レビュー、ロバストネス分析、予備設計レビュー、アーキテクチャ、シーケンス図と詳細クラス図、詳細設計のレビュー。

これらの作業が雑だったり、手抜きだった結果が、結局コードレビューに集中した。

コードになると、いろいろ意見がでてくるが、上流のモデルの時点ではメンバー間でのレビューが少なく、またレビューの効果が少なかった。

上流の要件定義、分析、設計、そして各工程でのレビューについて、もう一度、本を読み直しながら、基本事項をひとつずつチェックしました。

最初の頃は、コード書きやコードレビュー段階で発見していた問題を、早い段階で発見・修正できることが増えました。結果としてコードレビューの時間がだいぶ減少しました。

技術知識と約束事の共有

アーキテクチャ(特に採用したフレームワーク)やコーディングスタイルについて、メンバー間で共有する知識や約束事が増えるにつれ、レビューの時間がだいぶ減りました。

コードレビューは、こういう技術知識や約束事に共有には、かなり効果的ですね。

XPのペアプログラミングの目的の一つもこういうことなんだと思う。

最初は、時間がかかって非効率に感じるけど、技術知識や約束事の共有には効果があるので、最初のうちはコードレビューにかなり時間を割くべきだと思います。

レビューのテクニック

いくつかレビューのテクニックがあって、それを徹底することで、レビュー時間の短縮と効率アップができました。
例えば、事前に必ず読んでおく、問題点の発見だけで修正の検討はしない、修正結果を確認するフォローアップミー手イングをやる、などですね。

実践 ICONIXプロセス : コードを書く視点

ICONIXプロセスでは、コードを書く視点を次の四つに分けている。

・コードという世界に閉じた視点
・設計と実装の同期という視点
・ユースケースとの同期という視点(ユースケースの実現という視点)
・ドメインモデルの実現という視点

コードを書くときも、コードをレビューする時も三つの視点がある。どれも必要...

コードという世界に閉じた視点

コードレビューで言えば、コーディング規約、コードスタイル、命名(の形式的な)規約とかをチェックする視点ですね。
いろいろ好みというか思想というか、意見が分かれるところですね。
「コードコンプリート」では、プログラマー気質として議論していたかな。

この世界がなくなるわけではないけど、役に立つソフトウェアを作る、理解が容易で、変更がやりやすいコードにする、という目的のためには、この視点は視野が狭すぎる。

どんなソフトウェアが価値があるかは、コードの外の世界からやってくる。役に立つソフトウェアかどうか判断するのは、コードの外の世界の人たち。

変更要求も、コードの外の世界からやってくる。直すのはコードだけど、なぜ直すのか、どう直すべきかの理由は、コードの外にある。

だから、コードの外の視点を重視すべき。

設計と実装の同期という視点

ICONIXプロセスでは、シーケンス図と詳細クラス図で設計を詳細に完成させる。そして、コードは可能な限り詳細設計から自動生成することを重視する。

設計自体は、より上流の分析設計から導き出しているので、設計とコードを徹底的に同期すれば、役に立つソフトウェアを実現できるし、設計時に可能な限りプレファクタリングしてあるので、変更にも強いソフトウェアになっている(はず)。

最低限、この設計と同期という視点でいつもコードを書き、レビューすることが必要。

ユースケースの実現という視点

ICONIXプロセスが最も強調している視点。
ユースケース記述を元に、ロバストネス図を描いて、それを元にシーケンス図を描きながら、詳細クラス図を完成させる。その設計結果から、コードを自動的・機械的に生成する。

ユースケース記述をそのままコードに落とし込み、ユースケースを実現したソフトウェアを作ることを強調している。

ロバストネス図でもシーケンス図でも、必ずユースケース記述を貼り付け、ユースケースのステップをひとつずつ絵にしながら、実装方法まで落としていく。

予備設計のレビューも、詳細設計のレビューも、コードのレビューも、いつも、ユースケースとの同期をチェックする。

このやり方を徹底すれば、確かに役に立つソフトウェアの開発に直結しますね。

しかし、理解が容易で変更がやりやすいソフトウェアになる保障はない。

ドメインモデルの実現という視点

ICONIXプロセスの基本の流れはユースケースをコードで実現する手順。
しかし、同時に大きな流れとして、ドメインモデル(用語集)から出発して、詳細クラス図にして、最後はコードに落とし込む流れが基本構造になっている。

コードは、ユースケース側の動的(振る舞い)の流れではなく、ドメインモデル側の静的(構造)の流れの成果物ですね。

これはユースケース駆動だと言っているICONIXプロセスのある種のトリックだと思う。

あまりガイドブックでは強調していないが
・ドメインの構造は比較的安定している
・その安定構造を元にソフトウェアを設計しておくと、変更に強い
という思想、価値観を明確に持っている。

これって、ドメイン駆動設計と同じ価値観ですよね。

ICONIXプロセスは、動的モデルと静的モデルをいつも見比べて、整合性を取ることを重視している。
振る舞いと構造でバランスを取る、という言い方ができるかもしれない。

だから、静的モデルの最終形のコードは、ユーザの要求を具体的に表したユースケースモデルと一致する。

これが ICONIXプロセスの特徴だし、実践してみて、効果に手ごたえを感じているところです。

---

コードを書くときに、コードに閉じた世界ではなく、ソフトウェア開発の出発点のドメインモデル(問題領域の用語集)とユースケースモデル(使い方のシナリオ)をいつも意識する。実践手順として、それが自然にできるようにする。

そうすることで、役に立つソフトウェア、読みやすいコード、変更が安全にできるソフトウェアを、確実に楽に作ることができる。

実践 ICONIXプロセス : ドメインモデルの実装

ICONIXプロセスでは、イテレーションとかの定義はありません。
しかし、基本的には、ユースケースが最小の開発単位で、ユースケースパッケージが大きな開発単位だと思います。
「ユースケース駆動開発実践ガイド」の開発例も、こういう単位ですね。

ユースケース単位の開発の前に、ユースケースパッケージとかの単位で、準備すべき作業があります。それが、ドメインオブジェクトの実装です。

ドメインモデルのクラスは、テーブル、画面表示、ドメインクラスとして実装します。

テーブルとデータ

だいたいのドメインクラスは、Entity クラスで、永続化の対象ですね。つまりデータベース構築が必要。
ドメインモデルの実装の第一ステップは、テーブルの作成と、テストデータの作成です。

テーブルは、ドメインモデルからデータモデルを作って、DDL文を自動生成すれば、簡単に実装できます。
この段階で、初期テストデータも生成すべきです。データベースを構築するということは、空っぽの入れ物をつくることではなく、必要なデータを用意することです。

テストデータも開発物ですから、初期のデータセットを、しだいに改良・発展させていくというインクリメンタルな開発モデルが良いと思います。

ただし、初期データの段階から、現実のデータやテスト用途を丁寧に考慮したテストデータの設計と実装をやりましょう。

また、テストデータの設計と実装は、テーブル設計、つまりドメインの設計のレビュー活動としても重要です。テストデータの設計過程で、データモデルの不備や不整合を発見することはよくあります。

テーブルは自動生成できちゃっています。ここで余った時間を、テストデータの設計と実装に振り向けましょう。
実データも、ドメインオブジェクトの実装の方法の一つです。
ある意味では、もっとも雄弁に、そのドメインオブジェクトを表現したものです。

画面表示(CSS)

個々の画面は、ユースケース単位の開発で実装します。その前に、CSSを準備します。
CSSは、画面の基本構成とドメインモデルを参考に作成します。

画面の基本構成とは、ヘッダー、ナビゲーション、メインコンテンツ、サブコンテンツ、フッターなど、画面のレイアウトの視点で定義したオブジェクトですね。

これらの体裁を、CSS で定義しておきます。

たいせつなのは、ドメインモデルのオブジェクトごとの体裁指定も、CSSですること。

一覧(テーブル)用の体裁、という考え方ではなく、書籍の一覧の体裁、会員の一覧の体裁、書籍明細の体裁、ちおうように、ドメインオブジェクトごとの体裁指定をCSSで用意するということです。

CSS のコードも、ドメインモデルと同期すべき対象です。

CSS で、Booklist というようにセレクタにドメインクラス名を使います。
結果として、XHTML でも、class 属性に、ドメインクラス名が登場します。

ドメイン駆動設計(DDD)の ユビキタス言語 ですね。実装のあちこちに、どこにでも、ドメインクラス名が使われる。
ドメイン駆動を実践するということは、こういうことだと思っています。
Eric Evans も、重要なドメイン駆動パターンをひとつだけ選ぶとすると、ユビキタス言語だと言っていますね。

ドメインクラス

一番狭い意味でのドメインオブジェクトの実装ですね。

Enterprise Architect などのモデリングツールを使えば、簡単に自動生成できますね。
自動生成ができるように、念いりにモデルを作成し、レビューすることが大切です。

calendar
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< December 2017 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
  • 番号より名前。 ニーモニックコードより名前。 【パターン】
    師子乃 (03/10)
  • Smart UI が優れている?
    masuda220 (03/10)
  • Smart UI が優れている?
    kagehiens (03/09)
  • オブジェクト指向プログラミングの教え方?
    masuda220 (12/05)
  • オブジェクト指向プログラミングの教え方?
    ZACKY (12/04)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (08/14)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    kompiro (08/14)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (06/13)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    JHashimoto (06/13)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (02/28)
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM