環境準備の延長線上にいます。
まじめに人に教えられるほどの設計技術を身につけたいと思います。
を読みました。
認識を改めた事項を以下に示します。
ヒアリングして要求をまとめた Microsoft Word 文書から設計に落としこむのは困難である。重要な文章には違いないが…
(要求を箇条書きしてドキュメントに起こすところから始めてました…これじゃいけないの?)
要求からユースケースを作成しますが、その要求からは少なくとも一つのテストケースが作れなくてはなりません。
(テストできない要求からはユースケースは作れないってことなのだろうか?そのような要求はどうする?省くのか?)
ドメインモデルとは、ユースケースを作成しながら固めていくもの。プロジェクトの用語集のことを指す。
(そもそもドメインモデルって単語を業務で耳にしなかった、今回の件で覚えます。)
最初のドメインモデル作成は2時間まで、オブジェクトとデータは違う、ユースケースを作る前にドメインモデルを作ること。
ドメインモデルは用語集として使い、部品クラスを配置してはいけない。
振る舞い要求(ユースケース)を作成するための元ネタになる。
(らしい、どうやって書くんだ?)
ドメインモデルからユースケースを作成することで、シナリオとオブジェクトが関連付きコードに落とし込めるようになる。
(早くその辺の実践例を見てみたい!)
画面の遷移と共にユースケースが示されることが解決の鍵、紙芝居を用意し、文書だけでは表現できない情報を提示することで良くなる。
(つまり、要求提出の段階で、この紙芝居まで作らないといけないの?)
ユースケースは実行時の振る舞いの仕様です。紙芝居を使いなさい、そして「何が何をどうする」という文書で統一しなさい。
ドメインモデルのクラス名を使うこと。
(プロジェクト用語集から用語を使ってユースケースを表現しろということですね、そして要求を全て実現することが重要なんだよね?)
ユースケースはパッケージで組織化されていること、少なくとも一つはパッケージにユースケースがあること。
重要な概念の80%は要望元に理解させること。
(要求レビューは要望元の理解あってこそなのですね、ここで理解されなかった場合は作り直しなのだろうか?そもそも何を以って理解?)
要求分析は「正しいシステムを構築する」のための作業、設計は「正しくシステムを構築する」ための作業。
(なるほど、間違ったシステムを正しく構築する可能性があるので分析をしっかりと皆で確認しましょうということですね。)
ロバストネス分析では、ドメインモデルからエンティティを全て取り出す、気づくなら追加することがある。
ユースケースを明確に書きなおす事がある。コントローラは純粋にコントロールクラスになる可能性がある。
(知識としては持っていたけど、ドメインモデルとのつながりがわかってきた。)
ロバストネス分析後はドメインモデルのオブジェクトに属性が付いている。
ユースケースの曖昧さが排除されオブジェクトとのつながりがはっきりする。
追加したエンティティはドメインモデルにもあること。
シーケンス図上で表現するようなレベルの詳細は示していないこと。
(ロバストネス分析でやらなければならないことが見えてきました。)
正しいシステムになることが理解できたので、あとは詳細設計にて「実行時間」「ネットワーク負荷」「メモリ消費」
を考え、また「コードの再利用性」を高めます。
(ここから技術者の知識が必要となってくるところですね。ということは、ロバストネス分析まで技術者以外ができるということ?)
ユースケースごとに一つのシーケンス図を作成する。
シーケンス図に登場するオブジェクトはロバストネス図から持ってくる。
バウンダリ、エンティティ間でメッセージをやり取りしてユースケースをどのように達成するか確認する。
そのメッセージがエンティティ(クラス)の操作になり、クラス図を整理してデザインパターンなどの適用を検討する。
(ユースケースに対応するシーケンス図を作る、シーケンス図を書いてクラスの操作が作られる、結構単純な作業に見えます。)
実装の手が止まるならば、設計に戻り、再設計しレビューする。
コードと設計は常に同期させること。
単体テストに注力してコードを記述する。
コードにコメントを書きすぎてはいけない。保守性を下げ、かつ読みにくくする。
(どちらかというと、コメントを書かなすぎなので…あと、コードと設計を同期させる件は Enterprise Architect の機能を使いたい。)
テストについて、バグの発見は勝利であり、敗北ではない。
ドメインクラスを生成する。(操作は全て空)
ロバストネス図のコントロールごとに単体テストを作成し、実装、テスト合格を繰り返す。
システムテスト、受け入れテストを行った後にリリース。
(このテスト書いてから実装という流れ、いつも作ってません。今度からちゃんとテストを作ってから実装をします。)
ドメインモデルは皆とのやり取りの中から生み出され、成長していくプロジェクトの用語集です。
(さぁつくろう!と作られるものではないのか…)
ドメインモデルをユースケースの前に作る理由は、ユースケースにてドメインモデルの用語を利用するため。
(確かにー)
現実世界のオブジェクトに焦点を当てる。なぜならば、現実世界はそうは変化しないものだから。
全体のオブジェクトの関係の95%は汎化、集約の関連で結ばれます。
(オブジェクトを定義する指針?)
高いレベルの要求からオブジェクトを抽出する。
要求の羅列からキーワードを抜き出し、オブジェクト候補とする。
候補の中から重複するものを取り除き、粒度として不適切なもの(UI項目の一つなど)を削除する。
(なるほど、最初は要求からドキュメントに起こし、その中のキーワードを抜き出してドメインモデルのオブジェクトを決める。)
オブジェクト同士を集約で結ぶ。結べないものは保留にする。
「オブジェクトがオブジェクトを持っている」と口にしておかしくないか確認する。
ブレインストーミングを行って要求書に登場しなかったオブジェクトを見つけ、ドメインモデルを編集する。
(おお、具体的な作業内容を想像できます。これを2時間くらいで切り上げて今後の分析での修正を期待するのですね。)
汎化について、サブクラスの作成をサブタイピングと呼ぶ。
汎化したなら「サブクラスはスーパクラスです」と口にしてもおかしくないことを確認する。
(汎化しながらも要求書にはない新しいオブジェクトが出てきます。ここ読むような人はご存知と思いますが、汎化はクラスの継承のこと。)
ユースケースにはユーザーがシステムをどのように使うかと、システムがどのように応答するかだけを書きます。
(それ以外の記述はおかしいユースケースと言えるのは良いですね。)
ユースケースには晴れの日と雨の日があり、基本コース、代替コースと呼ぶ。
1.何が起きるか?2.そして何が起きるか?を繰り返し基本コースを完成させ、3.他にどんなことが起きそうか?で代替を洗い出す。
(これが本質らしい)
アクターには役割があり、ユースケースを遂行する責任があります。
ユースケースから invoke (呼び出し)先にユースケースを書くことが出来る。
(精算するというユースケースから、カードで支払う、銀行振込で支払うとかに分岐する。精算を遂行する責任がアクターにあるってこと?)
ユースケースは誰が何をどうするかはっきりさせる。
例えば「ユーザーはパスワードでログインする」はダメです。次が正しいユースケースの文章です。
ユーザーはユーザー名とパスワードを入力してログインボタンを押す。
システムはユーザー名からユーザー情報を取得し、パスワードが正しいことを確認する。そして、正しいのでログインに成功する。
(おお、これなら設計に起こしやすそうだ。そして名詞句はドメインモデルで登場したものだけを使うってことですね。)
イベントとその応答という流れでユースケースを書く。
ログイン画面を表示する→ユーザー名とパスワードを入力してログインボタンを押す。
ユースケースはログインの手順を述べるのではなく示すのです。
(「手順を示す」のがユースケースか、わかってきた気がするー、ユーザーとシステムの対話を示すのですね。)
UIをイメージさせるために紙芝居を用意する。そのUIから起こるイベントをすべて洗うことが出来るので強力な情報になる。
変なこだわりを受け付けないために、手書きの紙芝居でUIを用意する。
(ボタンはもっと左、そこはコンボボックスで、とかそういった細かい指摘をされないように努力する必要があるのか)
(あ、この本の作者は Enterprise Architect を利用しているぞ!やっぱ Enterprise Architect 買おう。)
ユースケースとオブジェクトを結び付けない限り、ユースケース駆動のオブジェクト指向設計はできません。
(毎日朝食の前に100回唱える必要があります。)
名詞-名詞-動詞でユースケースを記述する。
名詞はオブジェクト名(ドメインモデルのクラス名かGUIオブジェクト名)で動詞はオブジェクト間のメッセージを指す。
(ユースケースはシーケンス図にとても近いものだそうです。)
ユースケースにドメインモデルのオブジェクト名を使用しないことは愚かなこと。
(ほんと面白い表現がいっぱい、多くのユースケース紹介書籍をディスってる。)
ユースケースはどんどん明確にしていく。
ユースケースはユーザーガイドとも言えます。
(そうか、先にシステムの使い方を完成させてから、設計、テスト、実装と進むのか、じゃユーザーガイドがないシステムって一体…)
ユースケースのステレオタイプは気にせず、大切なのはユースケースの記述のみです。
ステレオタイプについて細かく突っ込む輩は無視して構わない。
(ユースケースのステレオタイプについて学ぶ気が失せました。)
基本コースを書き終えたら、代替コースを記述する。
我々の予想の斜め上をゆくユーザーたちを想像する。
基本コースをたどるように、彼らの行動を修正するようなシナリオを用意する。
(3.他にどんなことが起きそうか?で延々と問いただすのが良いみたいです。)
ユースケースと紙芝居をすべて顧客に示す。シミュレートしながら要求を満たしていることの確認を取る。
(嫌がる顧客を無理やりプログラマーと同じ部屋に入れ、レビューに参加させることが利益につながるそうです。)
ユースケースが正しく書けているか確認するための、健全性チェックとなる。
(ユースケースからロバストネス図が簡単に書き起こせないのは、ユースケースがおかしいと言える。)
Enterprise Architect の機能を使うと、ユースケースとロバストネス図をリンクすることができる。
(ロバストネス図にユースケースのメモを貼り付け、このメモがユースケースとリンクしているということ。)
ロバストネス図の矢印の方向は本当に重要ではないのです。
ユースケース記述から曖昧さを取り除き、見逃したオブジェクトを発見することが重要なのです。
(矢印の方向からは何も得られないとのこと。)
ロバストネス図はユースケースの「オブジェクトの絵」である。
ロバストネス図にはユースケースの代替コースを含めてその全てを記述しなければならない。
(代替コースが多いと、結構大きな図になります。)
表示する、というコントローラは必要。
(画面を初期化するというもので、テストケースにも加えなければならない重要な操作といえる。)
ユースケース記述を順に追ってロバストネス図を作っていく。
アクターから始まる。
GUIの要素はロバストネス図には登場しない。
アクターからバウンダリには一本しか線を引かない。
新しいエンティティを見つけたら、ドメインモデルとユースケースを更新する。
(すべてのロバストネス図を完成させたら、静的モデル、つまりドメインモデルに対する更新を完了させなければならない。)
分析レベルのクラス図の更新が完了する。
(ロバストネス図の最終的なゴールはこれですね。)
ユースケース記述とロバストネス図が一致しているか確認する。
代替コースが漏れていないか?ユースケースがオブジェクトモデルとGUIの用語で記述されているか?
あくまで概念設計ですので、クラスの振る舞いまで言及してはならない。
(ここまで確認してきたとおりに書けているかを見る感じでしょうか?)
千差万別。
数値で攻める。(アクセスユーザー数、時間帯)
何で構築するか。
(実現するには、より具体的に何で作るかを決めなくてはならない、そのための決定ってことかな。)
ここまでの予備設計はオブジェクトの洗い出しのために行ってきました。
シーケンス図では振る舞いをオブジェクトに定義します。
ユースケースごとにシーケンス図を作成します。
(注意深くユースケースについて調べることが大事とか)
クラスに対する責務の割り当てを行なう。
大切なのは操作をクラスに割り当てること。
(肝に銘じます。)
ユースケースに対してシーケンス図は一つ。
複数に分けたいとか言い出す輩は、長すぎるユースケースを書いているはず。
だからユースケースを短く書き直すこと。
(ここでもユースケースの修正に戻るのか…)
シーケンス図にはロバストネス図に登場するバウンダリ、エンティティを配置する所から開始する。
(これは具体的でわかりやすい書き出しですね。)
クラスに操作を加えるという仕事には経験と才能が必要
(結局のところ、経験を積まないと設計は良くならないそうな)
精神分裂症のオブジェクトには注意
(仕事を与え過ぎたり、仕事があちこちに振りまかれている場合は、修正のたびにシステム全体を見渡さなくては…)
適切な?属性
他のオブジェクトの実装に依存せず
複雑になりすぎず
結果として抽象的な再利用性の高いコード
(結局、適切な?とはなんなの?未来を読めないと判断できない?)
予備設計によって詳細設計が適切に開始できることが重要
(それだけ予備設計が正しくないといけないということか)
多重度は正確にすること、これが最重要事項です。
(そんなに重要なの?)
直感はシーケンス図やロバストネス図に立ち返るために使い
想像で静的モデルに詳細を追加することに使ってはいけません
(わかった、今後はクラス図から編集することはしないでおきます。)
責任ある振る舞いを他のオブジェクトに任せてはいけない
操作を持たないオブジェクトはドメインオブジェクトと変わらない
それは手続き型の設計と同じであり、オブジェクト指向設計の真逆をいくものである。
(操作を持たないクラスが登場すると、それはオブジェクト指向から外れている可能性があると、そういうことですね。)
(割り当てた操作や属性について、それが本当にそのクラスに適切なものか考えましょうというフェーズ)
(操作を一つ一つ調べる単体テスト、ユースケースがあるのでそのとおりに動作するか確かめるテスト)
(くまなくシステムの振る舞いを定義して、それを実現するように作ってきたのだから)
(その振る舞いの定義すべてを正しく処理できなければいけないということです。)
(テストの再利用性を保つことで、いつでも、テストできるようにすれば、エンバグは防げる?)
(テスト環境を簡単に復元できるシステムも考えないといけないよね!)
とりあえず実践してみようと思います。
最近購入した Store アプリ作成の書籍を参考にアプリを一から作るので
要求分析から始めて、テストまで作ってみようと思います。
恥ずかしいけど、その工程を公開してよく考えながらアプリの完成を目指してみます。
2014/02/15 初記。
2014/02/22 更新。