ソフトウェアの構成物をオブジェクトという単位で捉えるオブジェクト指向は、ブームからコモディティへとこなれてきたと思う。しかし、そこには指摘する人が少ない影の部分が存在していると感じたので、それを記しておく。
1)開発プロセスの変遷からの類推
ウォーターフォールからアジャイルへの変化や分化などは最適化の結果と捉えている。
地図を例にとると、平面の四角い紙に表す地図(メルカトル図法)は、一定の狭い範囲での表現としては最適であるが、地球全体にまで領域を広げると形が歪んでしまう欠点がある。逆に地球儀のアイデアを狭い範囲で忠実に実現しようとしても精度的に無意味になってしまう。
つまり、対象とする事物や扱う方式によって最適なものは変化するということだ。
ユニファイドプロセスなどは、ウォーターフォールのやり方を部分最適な方式として捉えており、ソフトウェア開発をモジュール化してその一部を実行する時のプロセスとして採用し、これをイテラティブ・インクリメンタルに行うこととした。
一方アジャイル開発では、ウォーターフォール的な手法を採用する場面はもっと限定的になる。
開発方法論は、統一(Unified)のかけ声よりも、現実に即した進展をしたと思う。それは、1つの手法ですべてを統一するのではく、状況に合わせて最適なものを採用するという方式だ。
2)分析・設計手法におけるオブジェクト指向
ソフトウェアの世界をデータと振舞を内包した要素とその関連として捉えるオブジェクト指向は、ある領域では最適だと言えるが、無制限に一般のソフトウェアを対象に出来る訳ではない。
オブジェクトは仮想的なモジュールとして捉え、それがデータを内包し、他のオブジェクトと関連を持つと捉えるのがOOの基本であるが、この考えはある程度の固まりとしてのソフトウェアコンポーネントやサブシステムという単位ならとてもしっくりするのであるが、細かくなってくると現実と整合しずらい部分が出てくる。
たとえば、機能や振舞を細分化し抽象化していくと、特定のオブジェクトやそのクラスに属する限定をしないほうが扱いやすい、純粋に抽象的な機能というものも見つかり、無理やりにオブジェクトと捉えると何のデータも持たない要素となってくる。また、データの方も同様にまったく何の機能を持たせる必要性がない固まりというのも存在する。さらに、振舞に関する関連とデータに関する関連では、構造を定義しているという点では同じだが、意味合いは全く異なっており、データ同士の関連は状態を意味する一種のデータとして使われるが、振舞同士の関連が状態を意味することは通常ない。
通常と言ったのは、振舞同士の関連に状態を持たせようと思えば出来るからであり、この「やろうと思えばできる」的な曖昧さが、OOでの分析・設計をぶれの大きなものにしてしまっているように感じる。
異なっているのに、共通的に取扱えるから同じ用語やコンセプトで押し通されてしまうと、本当に重要な”違い”が見過ごされてしまうような気がする。
ではどうするかは、これからの検討課題とする。
2012年1月27日金曜日
2009年2月6日金曜日
案ずることと成すこと
「案ずるより生むが易し」とはよく言われることだが、日々の開発においてコードの「生成」に対して「案ずる」ことで費やす時間は結構大きい。特に対象が個別の業務処理ではなく、基盤部分(フレームワークやライブラリなど)である場合はそれが顕著である。デザインの要素が入ると生産性が大きく下がるという話を聞いたことがあるが、規模が大きな業務アプリケーション開発では、人員を増やしてのコード作成フェーズに入った場合に作業者の手が止まらないように、デザインすべきこと(考えて決定すべきこと)を、前もって終えておく必要がある。個別の作業者の作業は仕様を実現するように与えられた基盤の上でコードを組立て、テストをすることであるのだから。
では、デザインフェーズでの決定に時間がかかる要因は何であろうか?それを明らかにするのが本書の目的である。
1.本書でのデザインの定義
デザインとは、ラテン語の[designare]が語源であり、意味は「計画を記号に表わす」ことである。つまり、ある問題を解決するために思考・概念の組み立てを行い、されを様々な媒体に応じて表現することと解すことができる。(wikipedia)
多くの言葉は、狭い意味で使用される場合と、広い意味で使用される場合があるが、デザインの場合もこれが当てはまる。建築を例にすると、設計図を作成することが狭い意味でのデザインであり、部品展開して材料や道具を明らかにし、作成工程の立てて人員や資材などの調達を計画することが広い意味でのデザインとなる。
本書では「デザイン」という言葉をソフトウェアの「システム設計」に限定して話を進める。システム設計において必要となる事柄には、以下のようなものがある。
・要件や仕様を実現するための
・基盤部分の調査、選定、作成、テスト
・業務機能実装のための要素分解と作業量見積もり
・人員や資材などの調達計画の作成
・開発環境および作業要領の作成
・工程計画の作成
・基盤部分の作成においての
・各種規約類の整理
・共通ライブラリの作成
・フレームワークの作成
2.デザインのメカニズム
多様体的な見方:地図では、都市というような限定した場所を示す場合は平面に表示するメルカトル図法が適しているが、地球や宇宙というような平面とはとらえられない場所では、他の方式を採用する方が妥当となる場合がある。デザインにおいても、マクロ的な観点でのアプローチやアウトプットは、ミクロ的な観点でのそれとは異なるのも十分にありうることである。
2-2.マクロ的観点
マクロ的な観点から「システム設計」の流れを記すと以下のようになる。この内、最初の3件は「システム分析」と呼ばれることが多い。
・把握:何をどうしたいのかという要件、仕様の抽出
・分離:要件、仕様を基盤共通、業務共通、業務固有へと分離
・確認:実現可能性の調査、使用可能は製品や部品などの調査
・作成:基盤部分およびモデルとなる業務要素
・計画:作業計画
2-3.ミクロ的観点
ミクロ的な観点では、個々の作業ごとにアプローチやプロセス、およびアウトプットがあることになる。ここでは、基盤部分のライブラリ作成について記す。
・課題の把握:何をどうすればいいのか
・類似コードの調査:すでの類似のものがある、流用できないか、拡張するだけですまないか
・作成場所(クラスやパッケージ)の選定、作成
・コードの作成とテスト:狭義のデザインには実装は入らない。それは建築などでは個々の部品が実在しており、その機能性や外観が分かっており、実際の組み立てをしなくとも計画を作成できるからである。ソフトウェアの場合にはこれが当てはまらない場合が多い。
それぞれのステップにおいて、「探し、考え、比較し、決定する」ことが求められるが、これが対象により作業時間が大幅に異なってくる要因となる。だからといってこの部分を仮決定のままにしておくことは許されない、後の作業に大きな影響をあたえることになるためである。
3.決定を遅らせる要因
多くの場合、実装そのものが困難な場合は少数であり、以下のようなことを決定するための材料が不足していることが、決定を遅くする要因になると想定される。
・最適ゴールの悩み:
そもそも、要求されていることの解決(対処)が妥当なのか
ミクロ的には必要に見えるが、マクロ的にとらえれと別のアプローチの方がすぐれていないか
それを採用するとそもそもの要求が無意味や不要にならないか
・重複の悩み:
すでに類似のものがあり、流用できるのではないか
車輪をもう一度発明したくない
・最適配置の悩み:
作成するものをどこに配置するのがいいのか
とくに作成するものが公開仕様を持つ場合は顕著
配置の変更が公開仕様の変更になってしまい、影響が大きくなるため
・最適単位の悩み:
どういう単位で公開するべきか
大きめの機能モジュールとしてか、小さめのライブラリやユーティリティとしてか
単位の変更が公開仕様の変更になっていしまうため
・効率の悩み:
処理効率が悪くならないか
・拡張性の悩み:
将来の拡張の妨げにならないか
・再利用の悩み:
共通基盤として利用され続けられるのか
4.決定の重さ
決定事項には重い・軽いの別がある。遅くなりがちなのはほとんどの場合、重い決定事項であるといえる。
例えば、システムを作成する場合に、「公開仕様を限定した部品同士の組合せ」としてデザインした場合、個々の部品の実装は後回しにしたり、仮組しておいて後で取り換えるなどの融通が効く。しかし、この公開仕様部分の決定を変更することはコストが高くなる。つまり、この仕様の決定は、部品内部の変更に比較すれば重いものになる。つまり、ソフトウェア設計において「重い、軽い」は、後から簡単に手直しできるか、手直しには多くの影響を招くかの違いが大きいといえる。
Javaなどのクラスという定義要素をもつ場合においては、以下のようなものがある。
簡単に手直しできるもの:影響が限定的なもの
名称の変更:名称をAPI仕様にしていない場合
公開仕様を固定したモジュールの取替え、組直し
Private要素の移動や変更
大きな影響をもたらすもの:影響が大きいもの
公開仕様の変更:APIや機能の変更
Public要素の移動や変更
では、デザインフェーズでの決定に時間がかかる要因は何であろうか?それを明らかにするのが本書の目的である。
1.本書でのデザインの定義
デザインとは、ラテン語の[designare]が語源であり、意味は「計画を記号に表わす」ことである。つまり、ある問題を解決するために思考・概念の組み立てを行い、されを様々な媒体に応じて表現することと解すことができる。(wikipedia)
多くの言葉は、狭い意味で使用される場合と、広い意味で使用される場合があるが、デザインの場合もこれが当てはまる。建築を例にすると、設計図を作成することが狭い意味でのデザインであり、部品展開して材料や道具を明らかにし、作成工程の立てて人員や資材などの調達を計画することが広い意味でのデザインとなる。
本書では「デザイン」という言葉をソフトウェアの「システム設計」に限定して話を進める。システム設計において必要となる事柄には、以下のようなものがある。
・要件や仕様を実現するための
・基盤部分の調査、選定、作成、テスト
・業務機能実装のための要素分解と作業量見積もり
・人員や資材などの調達計画の作成
・開発環境および作業要領の作成
・工程計画の作成
・基盤部分の作成においての
・各種規約類の整理
・共通ライブラリの作成
・フレームワークの作成
2.デザインのメカニズム
多様体的な見方:地図では、都市というような限定した場所を示す場合は平面に表示するメルカトル図法が適しているが、地球や宇宙というような平面とはとらえられない場所では、他の方式を採用する方が妥当となる場合がある。デザインにおいても、マクロ的な観点でのアプローチやアウトプットは、ミクロ的な観点でのそれとは異なるのも十分にありうることである。
2-2.マクロ的観点
マクロ的な観点から「システム設計」の流れを記すと以下のようになる。この内、最初の3件は「システム分析」と呼ばれることが多い。
・把握:何をどうしたいのかという要件、仕様の抽出
・分離:要件、仕様を基盤共通、業務共通、業務固有へと分離
・確認:実現可能性の調査、使用可能は製品や部品などの調査
・作成:基盤部分およびモデルとなる業務要素
・計画:作業計画
2-3.ミクロ的観点
ミクロ的な観点では、個々の作業ごとにアプローチやプロセス、およびアウトプットがあることになる。ここでは、基盤部分のライブラリ作成について記す。
・課題の把握:何をどうすればいいのか
・類似コードの調査:すでの類似のものがある、流用できないか、拡張するだけですまないか
・作成場所(クラスやパッケージ)の選定、作成
・コードの作成とテスト:狭義のデザインには実装は入らない。それは建築などでは個々の部品が実在しており、その機能性や外観が分かっており、実際の組み立てをしなくとも計画を作成できるからである。ソフトウェアの場合にはこれが当てはまらない場合が多い。
それぞれのステップにおいて、「探し、考え、比較し、決定する」ことが求められるが、これが対象により作業時間が大幅に異なってくる要因となる。だからといってこの部分を仮決定のままにしておくことは許されない、後の作業に大きな影響をあたえることになるためである。
3.決定を遅らせる要因
多くの場合、実装そのものが困難な場合は少数であり、以下のようなことを決定するための材料が不足していることが、決定を遅くする要因になると想定される。
・最適ゴールの悩み:
そもそも、要求されていることの解決(対処)が妥当なのか
ミクロ的には必要に見えるが、マクロ的にとらえれと別のアプローチの方がすぐれていないか
それを採用するとそもそもの要求が無意味や不要にならないか
・重複の悩み:
すでに類似のものがあり、流用できるのではないか
車輪をもう一度発明したくない
・最適配置の悩み:
作成するものをどこに配置するのがいいのか
とくに作成するものが公開仕様を持つ場合は顕著
配置の変更が公開仕様の変更になってしまい、影響が大きくなるため
・最適単位の悩み:
どういう単位で公開するべきか
大きめの機能モジュールとしてか、小さめのライブラリやユーティリティとしてか
単位の変更が公開仕様の変更になっていしまうため
・効率の悩み:
処理効率が悪くならないか
・拡張性の悩み:
将来の拡張の妨げにならないか
・再利用の悩み:
共通基盤として利用され続けられるのか
4.決定の重さ
決定事項には重い・軽いの別がある。遅くなりがちなのはほとんどの場合、重い決定事項であるといえる。
例えば、システムを作成する場合に、「公開仕様を限定した部品同士の組合せ」としてデザインした場合、個々の部品の実装は後回しにしたり、仮組しておいて後で取り換えるなどの融通が効く。しかし、この公開仕様部分の決定を変更することはコストが高くなる。つまり、この仕様の決定は、部品内部の変更に比較すれば重いものになる。つまり、ソフトウェア設計において「重い、軽い」は、後から簡単に手直しできるか、手直しには多くの影響を招くかの違いが大きいといえる。
Javaなどのクラスという定義要素をもつ場合においては、以下のようなものがある。
簡単に手直しできるもの:影響が限定的なもの
名称の変更:名称をAPI仕様にしていない場合
公開仕様を固定したモジュールの取替え、組直し
Private要素の移動や変更
大きな影響をもたらすもの:影響が大きいもの
公開仕様の変更:APIや機能の変更
Public要素の移動や変更
2008年11月12日水曜日
世界のとらえ方
オブジェクト指向に限らず、システム分析の重大な関心事項の1つは対象とする世界(ドメインということが多い)をどうとらえ、どう表現するかということだ。分析の主眼が現状認識であることから、認識したものをシステム的な表現に落とし込むことが主たる作業となる。
対象とするものは複雑なものであったり、変動するものであったり、出来事や関係だったりする。よってそれを理解し管理しやすい塊へと分解してゆくことが求められる。そして、分解の仕方は、「それらをどう取り扱うのか」というシステム目的によって恣意的に変化し、大まかな捉え方から精密なものまで種々のくくり方ができる。
こうしてくくりだした事象をシステム的に表現する場合、塊(事象の枠組み)に対して名称を与え、その事象が持っている属性(プロフィール)を設定することになる。
プロフィールの記述には、「記述可能」特性を使用する。
「記述可能」とは、数値、文字、日付のような、何らかの文字や記号で記録し、他者とコミュニケーション可能なものという意味で用いる。また、記述可能特性には、「比較性」を持つものと持たないものがある。
「比較性」とは、~より大きい小さい、~より長い短い、~より広い狭い、など等号・不等号の関係でとらえることができるものである。言い換えれば数値に換算できるものと言ってもよい。比較可能でないものとしては、たとえば、「名前」や「国籍」などの同じだとか一部が似ているだとかの評価はできるが、不等式での評価ができないものをあげることが出来る。
「記述可能」でない特性としては、音楽や絵画などの時空間との関連でしか意味を持たないものなどがある。
たとえば、対象とする世界を乗り物と考え、子供が使う三輪車と、多くの乗客を乗せるジャンボジェット機を取り上げてみる。この2つのものは具体的なものとして存在し、触れることができるし、それぞれの機能性を持っている。
対象とするものは複雑なものであったり、変動するものであったり、出来事や関係だったりする。よってそれを理解し管理しやすい塊へと分解してゆくことが求められる。そして、分解の仕方は、「それらをどう取り扱うのか」というシステム目的によって恣意的に変化し、大まかな捉え方から精密なものまで種々のくくり方ができる。
こうしてくくりだした事象をシステム的に表現する場合、塊(事象の枠組み)に対して名称を与え、その事象が持っている属性(プロフィール)を設定することになる。
プロフィールの記述には、「記述可能」特性を使用する。
「記述可能」とは、数値、文字、日付のような、何らかの文字や記号で記録し、他者とコミュニケーション可能なものという意味で用いる。また、記述可能特性には、「比較性」を持つものと持たないものがある。
「比較性」とは、~より大きい小さい、~より長い短い、~より広い狭い、など等号・不等号の関係でとらえることができるものである。言い換えれば数値に換算できるものと言ってもよい。比較可能でないものとしては、たとえば、「名前」や「国籍」などの同じだとか一部が似ているだとかの評価はできるが、不等式での評価ができないものをあげることが出来る。
「記述可能」でない特性としては、音楽や絵画などの時空間との関連でしか意味を持たないものなどがある。
たとえば、対象とする世界を乗り物と考え、子供が使う三輪車と、多くの乗客を乗せるジャンボジェット機を取り上げてみる。この2つのものは具体的なものとして存在し、触れることができるし、それぞれの機能性を持っている。
2008年10月28日火曜日
親子クラスで同じフィールド定義があると、、、
トランザクション指定を変えてのテスト中、「CommitInterval」を2以上にしても動作に変化がなく、Debuggerで調べてみて発見。
子クラス定義で親クラスと同じフィールドを宣言していた。こうした場合、実際のInstanceには同名の2つのフィールドが存在することになり、それぞれ別のデータを保有する。実際には呼び出されるコードが親のものか子のものかによってアクセスする対象が変わることになる。
Javaでは、こうしたフィールドやアトリビュートの重複定義をハイディングといい、アクセスタイプ(private,public など)や型を含めて制限されていない。つまり、ついうっかり子クラスで親と同じフィールドとアクセッサを定義してしまうと、実行時には親クラスのフィールドは初期値のままということになる。もちろんコンパイルエラーも実行時エラーも出ない。
まさに、調査していたコードがそうであった。しかも子クラスで独自に使用する必然性が感じられないため、たんならミスか?と思われる
参考:
Hishidama's Java Memo
Java言語仕様 第3版
Javaの日々
子クラス定義で親クラスと同じフィールドを宣言していた。こうした場合、実際のInstanceには同名の2つのフィールドが存在することになり、それぞれ別のデータを保有する。実際には呼び出されるコードが親のものか子のものかによってアクセスする対象が変わることになる。
Javaでは、こうしたフィールドやアトリビュートの重複定義をハイディングといい、アクセスタイプ(private,public など)や型を含めて制限されていない。つまり、ついうっかり子クラスで親と同じフィールドとアクセッサを定義してしまうと、実行時には親クラスのフィールドは初期値のままということになる。もちろんコンパイルエラーも実行時エラーも出ない。
まさに、調査していたコードがそうであった。しかも子クラスで独自に使用する必然性が感じられないため、たんならミスか?と思われる
参考:
Hishidama's Java Memo
Java言語仕様 第3版
Javaの日々
2008年10月21日火曜日
トレーニングの本質
トレーニングとは、「一定の基礎的な学習を反復練習しながら身に着けていくこと」(http://ja.wikipedia.org/wiki/トレーニング) であり、教育の1方法である。
教育は様々に定義されてきたが、その定義の仕方は大きく次の4種類に分けることができる。
語源・語義からの定義 (例 「教育とは、能力を引き出すことを意味する」)
目標・目的からの定義 (例 「教育とは、よりよく生きるためのものである」)
方法・手段からの定義 (例 「教育とは、強制の一種である」)
機能・効果からの定義 (例 「教育とは、社会の再生産である」)
教育は様々に定義されてきたが、その定義の仕方は大きく次の4種類に分けることができる。
語源・語義からの定義 (例 「教育とは、能力を引き出すことを意味する」)
目標・目的からの定義 (例 「教育とは、よりよく生きるためのものである」)
方法・手段からの定義 (例 「教育とは、強制の一種である」)
機能・効果からの定義 (例 「教育とは、社会の再生産である」)
ここでは、「教育とは人の持つ諸能力が引き出されるよう導くことである」とする定義を採用して論議を進める。
ほとんどの人には現時点において容易にまたは全く行うことが出来ない事柄がある。しかし、それを偶然ではない何らかの方法によって、行いうる事柄に変えることができたとする。この方法の適用や伝達が他者によってなされた場合に狭義の教育を受けたとみなすことが出来る。つまり、その他者によって能力が引き出されるように導きを受けたといえる。一方、自分自身での試行錯誤や文献などの資料から能力を高めた場合は、自己学習をした言える。
ここで、「導き」に含まれるさまざまな意味の中から、現在の地点からある別の地点への物理的な移動を助けることに限定して考えてみる。すると、導くとは方向や距離、着地する足の高低や地面の柔らなさなどを示して、導きを受ける側の者が自らの力で当該地点にたどり着けるように援助をすることと捕らえることができる。もちろん、すでに持っている能力に応じて援助の範囲は変化することとなる。
たとえば、目が全く見えない者に対しての導きは詳細なものになるべきであり、自分で再度同じ道を進むことが出来るようにするためには、視覚以外の方法で印となるものを用意する必要がある。逆に、当該箇所をよく見知っている者に対する導きは、「XXの交番から右へ15メートル」などのようにポイントとなるものを示すだけで十分となる。
また、導きを与える側の物は導く事柄に対して充分な能力を持っている必要がある。そうでないと、盲人を手引きする盲人の喩えのようの状態に陥ってしまうであろう。
■まとめ
トレーニングとは教育の一種であり、目的とする能力を獲得するために、
基礎となる事柄を反復練習しながら身につけていくこと
トレーニングを施す人は、当該能力を充分に備えている必要がある
登録:
投稿 (Atom)