作成日 2011/4/9
最終更新日 2011/4/17
問題2.14(問題タイトル:下位モジュールが不安定な場合)
オブジェクト指向設計についての問題(中級レベル)です。
問題タイトル:下位モジュールが不安定な場合
重要度:★★★★☆(やや重要)
難易度:★★★☆☆(普通)
問題タイトル:下位モジュールが不安定な場合
重要度:★★★★☆(やや重要)
難易度:★★★☆☆(普通)
問題:プログラムの設計を行っていると、上位モジュールよりも下位モジュールが不安定(使用するアルゴリズムやパラメータ、ライブラリが1つ決められない)で、それに対処する必要が時としてある。この場合、インタフェースを規定し、下位モジュールはそのインタフェースに合うように作ることとなる。
この時のインタフェースの設計方針や注意事項などとして正しいものをすべて選択せよ。
a.インタフェースを規定するのだから、下位モジュールが持つデータの洗い出しは行う必要がない。
b.可能であれば、サンプルとして具体的な下位モジュールを作成し、インタフェースの漏れ(メソッドや引数の漏れなど)を確認した方が良い。
c.インタフェースをバージョンアップする場合で、元のバージョンの仕様に問題がある(仕様バグがある)場合、すぐさま修正すべきである。
問題文終わり
注意:これ以上、下にスクロールすると解答・解説が見えちゃいます。
解答:b
※部分点は存在しませんよー。1つでも余計なのを選択したり、間違えたら0点です。
解説:
部品化、多態性、オブジェクト指向設計の基本を正しく理解して設計に活用しているかを問う問題です。
1つ1つ解説していきます
a.誤り。
何度も言っているが、重要なのは処理ではなくデータです。(データ中心アプローチ)
インタフェースを規定するということは処理(メソッド)の名前、引数、戻り値しか規定しないということですが、だからと言ってデータを考慮しなくていいことではありません。
具体的な設計方針としては、
必要なデータ(共通するもの、しないもの両方)の洗い出し⇒データ構造の作成(必要なデータが記載されたクラス図の作成)⇒(公開する)処理(メソッド)の設計
という感じです。
まあ、場合によってはデータが出てこない場合もあるかもしれないが・・・。
b.正しい。
インタフェースのメソッドの引数の型の変更、追加・削除などは厄介です。(上位モジュールに影響が出るため)
それを最小限にするため、サンプルを実装するのは良いことです。
また、この問題とは関係ありませんが、サンプルを作ると上位モジュールが実際にそれを使うことで、上位モジュールのプログラミング担当者が、下位モジュールをより理解できるというメリットもあります。
ただし、その分工数がかかりますので、そこは注意してください。
c.誤り。
特に仕様バグの場合、すぐに修正できません。(※メモリリークなど仕様バグではない場合は即修正できる)
これはなぜかというと、上位モジュールに影響が出るからです。バグであっても修正できないので、バグを仕様とするか、非推奨のメソッドにして代替メソッドを作成することが多いです。
※一般に、「オブジェクト指向設計をすると部品化ができ、工数の削減に寄与する」と言われていますが、このようなデメリット(というよりリスク)があるということも押さえましょう。
そして、このようなことを減らす必要があるため、部品部分の設計・実装というのはスキルの高い人でないとできないと考えてます。
問題に対する解説は以上ですが、この不安定な下位モジュールへ対処はほとんどの場合厄介です。だるまが知る限りのことを以下に示しますので、参考にしてもらえればと思います。
- 対処しても結局無駄になることも多いです。まずは、本当に必要か良く検討しましょう。
- まだ作成されていない下位モジュールを想定してインタフェースを作るのは本当に大変です。後になって、「あ、これも必要だった」なんてことにならないようにするのは至難の業です。
どうしても、という場合、すでに不安定な下位モジュールに対してのインタフェースを定義しているシステムやライブラリを参考にするのが良いです。
例えば、以下があります。
- JavaのJDBC(DBを作っているベンダがこれの仕様に合わせ、JDBCドライバを作っている)
- CORBA(分散オブジェクトの規格。Javaならorg.omg.CORBA.ORBクラス。これもCORBAのベンダが仕様に合わせ製品(J2SE付属のCORBA、VisibrokerやOrbixなど)を作っている。)
- 一方向ハッシュ関数(Javaならjava.security.MessageDigestクラス。OpenSSLの該当関数もそうです。)
- 暗号化(※一般に、一方向ハッシュ関数や暗号化処理を使うプログラムは、後になって使用したアルゴリズムが破られて使えなくなっても、作成したプログラムの再コンパイルなしに対処できるような設計にする必要があるがあるため)
- ファイルIO(ストリーム)(方式(ネットワーク、ファイル、Zipファイルなど)相手がなんであろうと意識せず、使えるようになっている。)
- OSGi(OSGiは規格です。これに合わせ、ベンダが実装します。)
- Itron(OSの仕様です。例えば、これを実装したものとして、TOPPERSやHOSがあります)
※ちなみに、だるまは仕事の関係でμItron4.0およびμItron4.0/PX仕様の仕様書を読んだことがありますが、仕様を決めるうえでの理由まで書かれており、本当に勉強になったという記憶が残っています。
- JavaやC++の例外クラス(Javaならjava.lang.Exception。C++ならstd::exception。)
- Javaのインタフェースのようなものを設計する場合、C++の純粋仮想関数のみのクラスを設計する場合(要するに属性のないクラスを設計する場合)であってもデータ構成の洗い出しは必要です。
これは、処理中心よりもデータ中心の方が保守しやすいこと、モジュールの強度(凝集度)の考えからそうなります。
まあ、データが出てこない場合もありますが・・・。
この時ですが、共通するデータだけではなく、そうでないデータ(個々の下位モジュールの実装に依存するデータ)にも注意を払ってください。考えておかないと、後で、「あ、このインタフェースだと必要なデータを渡せない・・・」的なことに陥ります。
- 設定値(各種パラメータ、使用アルゴリズムなど)を外部ファイル(設定ファイル)に記載しておき、システム起動時(あるいは、任意の機能の起動時)に読み込んで、使うということは良くあることです。
この場合は、以下の点に注意してください。
- 設定ファイルはコメントの記載ができるようにした方が良いです。設定値に関するコメントを記載したり、ちょっと変えてやってみるといったときに使います。
- 設定値のチェックは厳格に行った方が良いです。
具体的には、型のチェック(数値、小数、文字列)、範囲チェック、文字列長チェック、重複チェック(同じ項目を重複して定義していないか)、関連チェック(例えば、ある値が5だったら、別のある項目は10〜60でないといけないなど)です。
それから、チェックエラーとなった場合には、どのファイルの(ファイルのパス)、何行目(場合によっては何列目という情報も)がなぜダメなのかを画面やログなどに出力してください。
(ログの場合、一般に何もなければログは見てもらえませんから、「ログを見てください」的な情報をユーザに知らせる必要があります。)
過去、チェックエラーになった場合や設定されていなかった場合に、「デフォルト値で動作させるのが良い」と言っている輩がいましたが、これはユーザが意図しない動作の原因になりうるので危険です。止めましょう。少しでもおかしかったらプログラムを動作させないで、確認させた方が良いです。
- 設定ファイルを書く人が、設定値の修正・チェックを短時間で繰り返しできる作りが良いです。例えば、ファイル修正後、チェックするのに1時間かかるとしたら、大変です。
- 設定ファイル(というかファイル)アクセスは一般に低速です。なので、1度全部取得し、メモリに展開し、2回目以降はそこから取得するようにした方が良いです。何度も何度もファイルを読みにいかないようにしましょう。
それから、設定ファイルの読み出しにWindowsAPIのGetPrivateProfileStringを使う場合ですが、もし仮に設定項目が1000あった時にこの関数で取得すると、プログラムの動作が遅くなります。
なぜなら1000回、ファイルにアクセスするから。
なので、GetProfileStringで一気に取得し、取得した値をプログラム内で保持した方が処理が高速です。
※一般に、プログラム動作中にユーザが手で設定ファイルを直接いじるということはあまりありません。なので、プログラム起動時に全部読んで、メモリに格納すればいいです。で、ユーザが手で直接修正した時については、プログラムを再起動してくださいと制限事項にすればほとんどの場合事足ります。
- 設定ファイルに「XXX=YYY」のみのような設定値ではなく処理を書きたい場合や、その他複雑な構文にしたい場合があります。この場合の設計についてはGoFのデザインパターンのインタプリタパターンが参考になると思います。
- 正常系のみ考えるのではなく、エラー処理(例外のスロー)にも注意を払ってください。
これにより例外クラスの階層(継承関係)も設計する必要が出てきます。
このページを作成する際に参考にしたページや、もっと勉強したい人向けの資料です。
このページの利用によって発生した、いかなる損害について、このホームページの作成者は責任を負いません。
このページの間違いや嘘を見つけた方、このページに書いて欲しい情報がある方は
メールをお願いします。
Microsoft 、Windows 、Visual Basic および Excel は米国Microsoft
Corporationの米国およびその他の国における登録商標または商標です。
ここではExcel® をエクセル、Visual Basic® for Applications をVBAと表記する場合があります。
Mac 、Mac OS
、Mac OS
X は米国Apple
Computer,Inc.の登録商標または商標です。
Sun、Sun Microsystems、サンのロゴマーク、Java、及び、Sun/Solaris/Java に関連するすべての商標およびロゴマークは米国 Sun Microsystems, Inc. の米国およびその他の国における商標または登録商標です。
OMG、CORBAは、Object Management Groupの商標または登録商標です。
ITRON は "Industrial TRON" の略称です。
μITRON は "Micro Industrial TRON" の略称です。
TRON および ITRON は特定の商品ないしは商品群を指す名称ではありません。
VisiBrokerは、Visigenic Software,Inc.の商標です。
Orbixは、IONA Technologies PLC.の登録商標です。
"TOPPERS"およびTOPPERSプロジェクトのロゴは、TOPPERSプロジェクトの登録商標です。
その他、社名および商品名、システム名称などは、一般に各社の商標または登録商標です。
このホームページの作成者はこれらの会社とはいっさい関係がありません。