ラベル Model の投稿を表示しています。 すべての投稿を表示
ラベル Model の投稿を表示しています。 すべての投稿を表示

2012/10/16

構造化/クラス指向/オブジェクト指向/サービス指向
Map Methods to the Abstraction Plane

先日のとある雑談のまとめ。その2。

前回の抽象化の基本2軸と照らし合わせながら
ソフトウェアの設計手法について、少し考えてみます。

  1. フローチャート
  2. 構造化設計/構造化プログラミング
  3. クラス指向
  4. オブジェクト指向
  5. サービス指向

1. フローチャート
 「フロー」という名前の通り、
 動的な振る舞いを記述する手法です。
 条件分岐や繰り返し等もありますが、
 基本的に上から下に流れる1本道です。
 小さなバッチ処理であれば、これで十分ですが、
 構造の記述が容易ではないため (つまり設計者に構造について考えることを促さないため)

 ソフトウェアの規模が少し大きくなると、
 使い辛い手法になってしまいます。

2. 構造化設計/構造化プログラミング
 階層的に抽象化されたプログラムの組み合わせとして
 プログラミングを記述する手法です。
 簡単に言えば「本の目次」のように
 プログラムを設計/実装することです。
 鳥の目から虫の目に段階的に変化していくということです。
 但し、「本の目次」であるため、前から順に読んでいくという
 フロー(=振る舞い)の記述も含んでいますが、
 1本道であるという点ではフローチャートと変わりません。

3. クラス指向
 さしあったって、クラス指向では
  構造化プログラミングでの構造化を助けるために、
  クラスという枠組み(箱)を提供している
 と考えれば良いでしょう。
 オブジェクト指向言語を導入したバッチプログラムで、
 よく見かける形態です。

4. オブジェクト指向
 バッチ処理の場合、振る舞いはほとんど1本道のため
 設計上は余り問題にはなりませんが、
 ユーザー対話型のイベントドリブン処理の場合、そうはいきません。
 様々な状態での様々なイベントに対して、
 適切な振る舞いを提供するというのが、
 大きな設計課題となります。
 そこで、構造とともに振る舞いをモデル化する
 オブジェクト指向設計が、もてはやされているわけです。
 とはいえ、イベントドリブン処理といえども
 一度振る舞いが決定されれれば、
 そこから先は(比較的短い)1本道です。
 構造化が重要なことに変わりはありません。

5. サービス指向
 鳥の目で、静的な構造を決定するときの手法の一つです。
 業務全体を鳥の目で見て、業務上の一処理を基本粒度として
 ソフトウェア群を構造化するという手法です。
 ソフトウェアの大規模化とクラウドコンピューティングの台頭により
 全体の構造がどうあるべきかということが、
 昨今のホットな話題になっているのでしょう。


ということで、雑談のまとめはこれで終わりです。


2012/10/15

設計と抽象化
The 2 Axises for Abstraction


先日のとある雑談のまとめ。その1。

そもそも(ソフトウェアの)設計とは何でしょうか?
広辞苑によれば、設計とは
  …或る製作・工事などに当たり、その目的に則して、
  工費、敷地、材料および構造上の諸点などの計画を立て
  図面その他の方式で明示すること。…
とのことです。
「その目的」とは、何らかの問題解決でしょう。
「図面その他の方式」とは、実物を作るのではなく、
モデルを作るということでしょう。
「設計」のインスタンスが「実装」という考えです。
そこで、ここでは設計を
 「問題を解決する解(案)のモデルを作ること」
と定義して、
少し考えてみることにします。

  1. 解(案)
  2. 抽象化
  3. 解はどこから来るのか?

1. 解(案)
 「解」ではなく「解(案)」としたのは、
 実際に作ってみるまでは、それでうまくいくのか
 わからないことも多いからです。
 なお、問題にはいくつもの説明が可能であり、
 そのため、解もいくつでも存在しえます。
 もちろん、解の良し悪しはありますが、
 最終的にはそれも価値判断でしかありません。

2. 抽象化
 実物を作るのではなくモデルを作るということは、
 抽象化するということです。
 抽象化とは、思考方法の一種で、
  対象から注目すべき要素を重点的に抽出し、他は捨て去る方法
 です。
 そこで、何に着目し、何を捨てるかが問題になります。
 決まった答えはありませんが、ソフトウェア設計に限らず、
 抽象化に以下の2つの軸が広く使用されています。

 (1)鳥の目 <-> 虫の目
 (2)静的 <-> 動的

 (1)鳥の目 <-> 虫の目
  鳥の目は、全体像に着目し、細部を捨て去ります。
  虫の目は、細部に着目し、全体像を捨て去ります。
  巨視的/微視的、マクロ/ミクロ、等呼び方は色々です。

 (2)静的 <-> 動的
  静的な視点は、構造に着目し、振る舞いを捨て去ります。
  動的な視点は、振る舞いに着目し、構造を捨て去ります。
  データ構造とアルゴリズム、と言った方が判りが良いかもしれません。
  会計でのストック/フロー分析も同じ手法です。

3. 解はどこから来るのか?
 これが一番問題なのですが、
 設計解を得るプロセスは明確ではなく、
 設計者の思いつきや閃きといっても過言ではありません。
 とはいえ、ゼロからでは思いつきや閃きは生まれません。

 設計中は、虫の目 <-> 鳥の目  静的<->動的 を
 行ったり来たりしならが、
 知識と経験を基にしたパターンマッチングや
 演繹/帰納/アブダクションを行っているのだと思います。


ということで、続きはまた明日。

2012/01/08

RESTfulWebサービス設計課題 和暦検索 #03 提供データの特定とER図

RESTfulWebサービスの第3回目は、提供データの特定とER図の作成です。

本題のリソース設計に入る前に、サービスとして提供するデータを特定します。提供するデータは要求でかなり明らかになっていますが、構造化されていないため何をリソースとして管理すべきか分かりません。
そこでまずは、必要なデータをRDBのテーブル設計の要領でER図に落としてみました。それが下図です。(「astah*」のクラス図を使って作成したためプライマリキー(PK)が表現できていませんが、「テーブル名ID」がPKです。)
1. 説明
(1)南北朝の問題は「時代・王朝」を提供データとして設けることによって対応
南北朝や大覚寺統/亀山統の解決方法に悩みましたが、要求中には明示されていなかった「時代・王朝」を設けることで対応しました。これにより日本の平安時代の年号一覧などの機能(要求にはありませんでしたが)にも対応可能になります。
また、他の国/地域の王朝も区別できるようになります。特に中国では複数の王朝で同じ元号(「建武」など)が使用されることもあったようで、区別が容易になります。

(2)4カ国・地域共通データと日本独自データに分割
「時代・王朝」は共通データとして「元号」から参照しています。しかし「天皇」は日本独自データとして、天皇と元号を紐付けるデータを別途持たせるようにしました。
最初は「天皇」を「皇帝・天皇・国王」のように読み替えて「元号」と「時代・王朝」の間に挟むことも考えました。そうすれば、全て共通のデータ構造になるからです。
しかし
・日本の場合「将軍」や「総理大臣」という軸も考えられてなかなか複雑であること
・基本的には天皇の交代時に改元されがもし例外があった場合の処理が複雑になること
・中国/朝鮮半島/ベトナムの元号の詳細が勉強不足で分かっていないこと
メインコンセプトである「西暦による各国元号の串刺し」には直接関係しないこと
から、断念しました。

2. 主な問題点と変更点
(1)2時代に跨がる元号の存在
実は「時代・王朝」の対応には、問題がありました。
日本では1つの元号が2つの時代に跨がることがあり、例えば「延暦」は西暦782年〜806年のため奈良時代と平安時代の両方に属します。少し複雑になりますが、「元号」のデータを2時代分重複してもつことで対応可能なので、正規化して「元号_時代・王朝」を設けました。

(2)「西暦」を削除
西暦ID = 西暦 で問題なさそうなので、「西暦」を作ったのはちょっとやり過ぎでした。
(が、下図のように消してから気が付きましたが、リソース設計用のデータ構造を示すだけなのでの残しておいた方が良かったように思えます。)

ということで変更後のER図を以下に示します。

3. 課題
(1)正規化し過ぎ
このER図は、リソース設計を行うためのデータの構造化として作成しました。
CRUDのうち基本的に使用するのは「C」と「R」のみで、しかも「C」を行うのは管理者のみであることを考えると、ほとんどの処理は「R」で、管理者がたまに簡単な「C」と「R」を行うのみであることを考えると(2012/01/09修正。改元時に終期の「U」があることの考慮もれ)、ここまでの正規化は行き過ぎかもしれません。
また現状では、RDBではなくGAEのBigTableに載せることを考えています。「元号年」のデータ数は多く見ても1万件程度のオーダーですので、ごりごりテーブルを結合させても大丈夫かと思いますが、詳細設計の段階では正規化を崩すことの検討も必要です。

(2)歴史学上の議論
元号、王朝、時代、その他諸々、今回のアプリで扱うデータの値にはいろいろ議論のあるところです。いくつかバリエーションを持たせることも不可能ではありませんが、ここでは何かひとつ決めうちで対応することにします。
たとえば「元号の読み」ですが、明治以前は明示されていないため複数の読み方が成立します。しかし今回は複数の読は対応せず、私の独断と偏見で読みを1つに絞らせて頂きます。

4. 要求の再確認
要求を上から順番に確認し、実現できないものないことを確認して本日は終了です。
○1. 機能要求
 ○1-1. 西暦から和暦を知りたい(例:西暦2012年 -> 平成24年)
  ○1-1-1. 西暦に対応する和暦が存在しない場合は、その旨を教えて欲しい
  ○1-1-2. 西暦に対応する和暦が複数存在する場合
   ○1-1-2-1. 改元の場合は、改元月日と併せて全和暦を表示して欲しい
   ○1-1-2-2. 南北朝期の場合は、南朝/北朝両方の和暦を表示して欲しい
 ○1-2. 和暦から西暦を知りたい(例:平成24年 -> 西暦2012年)
 ○1-3. 元号から和暦情報を知りたい
  ○1-3-1. 和暦情報としては少なくとも以下の項目が欲しい
      元号名、元号名の読み、元号の年数、始期(年月日)、終期(年月日)、天皇名、天皇名の読み
  1-3-2. 元号名の部分一致で和暦情報を検索したい
  1-3-3. 元号名の読みの部分一致で和暦情報を検索したい
 1-4. 天皇から和暦情報を知りたい
  1-4-1. 天皇名で和暦情報を部分一致検索したい
  1-4-2. 天皇名の読みで和暦情報を部分一致検索したい
 1-5. 他アプリへのサービス提供を可能とするためJSON形式のデータが欲しい
 1-6. もちろん人間の読みやすい形でのデータも欲しい
○2.非機能要求
 2-1. 他の元号使用国(中国、ベトナム、朝鮮半島)用機能の追加が容易な設計にして欲しい
 2-2. 機密情報は扱わず、ユーザー管理も行わないのでセキュリティに配慮する必要はない

以上、お疲れさまでした。



2010/12/31

HTMLをサーバー側で生成すべきか?

DjangoTemplateとAjax でも書きましが、Django Template はサーバー側でのHTML生成をサポートする仕組みです。GAE/Python では Django Template が標準装備されており、スタートガイドのチュートリアルでも使用方法が紹介されています。その流れでDjango Templateを使用して自分でもアプリを作ってみました。しかしAjaxを使用する段になって、サーバー側でHTMLを生成してクライアント側でinnerHtmlを書き換えるという手法に、違和感を覚えました。

HTMLはMVCパターンでいうところのViewに当たる部分です。そのViewをサーバー側で作ってしまったら、疎結合なサービスとして提供できなくなってしまいます。たとえデフォルトのViewは提供するとしても、Viewと切り離したサービス(つまりデータとビジネスロジックであるModel)のインターフェースを公開しておけば、誰でも好きなViewを勝手に作ることができるようになります。(お前のアプリのViewなんか誰が作るんだ、という話は別にして(^_^;))。

従って、AjaxではJSON(XMLだとデータサイズが大きくなるのでJSONを第一選択としたい)でデータを取得して、JavaScriptのControllerでHTMLを生成というのが、ストレートな解法だと思います。

しかし、課題もあります。
1. Django Template のような仕組みを、JavaScript + JSON で実現する必要がある
2. クライアント側に処理負担がかかる(未検証)

1. についてはライブラリを探すとして、2. についてはちょっと注意が必要です。
処理を 「サーバー側処理 + 通信 + クライアント側処理」に分けると、クライアント側でHTMLを作成する場合は、サーバー側処理と通信(HTML > JSONとして)の負荷が減ります。しかし、サーバー側の処理が減った分、クライアント側で処理が増えます。
モバイル端末の性能向上には目覚しいものがあるとは言え、比較的重たい処理を行う場合は処理速度の検証が必要でしょう。

とここまで考えて探してみると、中島聡氏がブログでもっと正確で判り易くて格好良い説明を図入りでされていました(「RESTful MVC」なアーキテクチャの話)。しかも 1. のクライアント側Templateの仕組みをjQueryのplug-inとして作成されていました(jQBinder, ブラウザー側でのHTML templateを可能にするjQuery plug-in)。ちょっと凄過ぎです。
さらに、既に2005年の段階でAjaxの本質として「データ・バインディングはサーバー側ではなく、クライアント側で行う」ということを挙げられています(Ajaxの本質、「非同期メッセージ型ウェブ・アプリケーション」のススメ)。

以前ブログを読んだ時にはちゃんと分かっていなかったということが、わかりました。

それでは皆さん、良いお年を (^O^)/

2010/10/03

レビューチェックリストへのフィードバック

ソフトウェアの開発では、障害をDBに蓄積したり、レビュー時にレビューレポートを残すことも多いです。欠陥を記録し、修正が完了すると、ほっと一息つけますね。そこで忘れがちなのが、次の開発へのフィードバックです。定期的に蓄積した記録を分析して、レビュー用のチェックリスト等にフィードバックしていけると嬉しいですね。

2010/06/05

状態遷移とテストケース

「状態遷移表 = テストケース一覧」となることは、よく知られています。クラスやオブジェクト単位の状態遷移は、xUnit等でのテスト自動化もやり易いところです。

見逃しやすいのが、アプリケーションソフト全体でも考え方は同じということです。
まず、入力されるイベントが、

  • 画面のボタンクリック
  • 他のシステムからのメッセージ
  • etc...
になるかわるだけですね。 
出力されるアクションは

  • 画面へのメッセージ表示
  • ファイルへの書き出し
  • etc...
ですね。
後は、入力 と 状態の組み合わせで、結果がどうなるかを示せば、漏れの無いテストケースが出来上がるというわけです。


実際は、その状態の洗い出しが難しいわけです。ひとまず入力と状態を分けて考えることで、この難しい状態の洗い出しに集中しやすくなります。

2010/06/03

シーケンス図も障害再発防止策も、全て仮説の表現?!

都合よく抽象化してしまえば、何でも共通化できてしまうことの一例。

(原画リンク)
UMLのシーケンス図は、もろに問題解決のためのストーリーですね。
新規事業の提案、旅行の計画、etc...
何にでも使えます。