Software Engineering Lecture 6/20
Software Engineering Lecture 6/20
前回の復習
- 戦略的なデバッグ
- ステップ実行
トレース
- トレース
- ブレイク
- 帰納的プログラミング
- 冒険的プログラミング
インタフェースと構造体
今までのadd-assoc, tree-insert, btree-insert などは、次のような機能を
持っているという意味で同じプログラムである。
- keyとvalueの組を格納するデータ構造である
- insert, delete によりkeyとvalueの組を格納したり取り除いたいりする
- 内容をkeyとvalueの組のリストにして取り出すことができる
しかし、LISPの関数としては異なるものだし、呼び出し方も異なる。
もし、複数の人がLISPのプログラムをただ乱雑に作っていけば、そのプログラムは
このような「似ているけど少し違う」関数の集合になってしまう。LISPに限らず、
どのようなプログラム言語を使ってもこの状況は変わらない。
このような状況では、
- プログラムの見通しが悪い、他の人に理解させることができない
- 機能の割りにプログラムが大きい
- プログラムを変更しようとすると、たくさんの部分を変更しなくてはならない。
- プログラムがちゃんと動くかどうか自信がもてない。
- プログラムを組織的にテスト、デバッグする方法がない。
などの状況になりやすい。
そこで、プログラムを作る時に、
- インタフェース プログラムの入出力の仕方
- インプリメント 機能の実現
を分けて記述するという方法が考えられる。defstruct などは、そのための
一つの道具である。defstruct では、xxxx という構造体のインタフェースを
- make-xxx
- xxx-yyyy yyyy はxxxの要素
という形で統一している。これはLISPで、すべてのデータ構造をリストで
統一し、cadr,cddr などでアクセスするというのと、ある意味で似ているが、
より読みやすい形になっている。
データ構造は構造体によって読みやすいインタフェースを持つことができた。
では、LISPの関数自身はどうだろうか? 例え、defstruct がたくさんあって
データ構造が見やすくなっても、わけわからない関数が雑多に転がっている
だけでは困ってしまう。
パッケージ
Common LISPは、一つの解決策としてパッケージ(package)を持っている。
これは他の言語だったらモジュール(module)と呼ばれるかもしれない。
パッケージは、複数の関数をまとめて、外から隠す機能がある。これに
よって、ありふれた名前(そういう名前が分かりやすい)を
使っても、他の人が書いているプログラムと衝突しないですむ。
+cw03+kono gcl
GCL (GNU Common Lisp) Version(2.2) Mon Mar 25 03:35:04 1996
Licensed under GNU Public Library License
Contains Enhancements by W. Schelter
>*package*
#<"USER" package> 普段はこのパッケージにいる
>(in-package 'kono) konoというパッケージを作る
#<"KONO" package>
KONO>(export '(kono-1 kono-2 kono-3)) この名前は外から見える
T
KONO>(defun kono-1 (x) (+ x 1))
KONO>(defun kono-2 (x) (+ x 2))
KONO>(defun kono-3 (x) (+ x 3))
KONO>(defun kono-4 (x) (+ x 4))
KONO>(in-package 'user) もとのuserパッケージに戻る
#<"USER" package>
>(kono-1 3) たしかに見えない
Error: The function KONO-1 is undefined.
>(kono:kono-1 3) こうすれば見える
4
>(kono:kono-4 4)
Error: Cannot find the external symbol KONO-4 in #<"KONO" package>.
>(kono::kono-4 4) :: はいんちきくさい
8
>(use-package 'kono) パッケージkonoを使う
Error: Cannot use #<"KONO" package> だめだ (X_X)
from #<"USER" package>,
because KONO:KONO-1 and KONO-1 will cause
a name conflict.
>(in-package 'kono-1) 真っ白なパッケージでもう一度
#<"KONO-1" package>
KONO-1>(use-package 'kono)
T
KONO-1>(kono-1 1) : を付けなくても使える
2
KONO-1>(kono-4 3) exportされてないものは使えない
Error: The function KONO-4 is undefined.
これによって、雑多な関数がある状況でも、安心してプログラムを行う
ことができる。
しかし、これは消極的な方法だともいえる。これだと衝突は少なくなるが、
同じような関数をたくさん作ったり、ちょっとづつ違うインタフェースを
持つ関数を作ってしまうことは、むしろ奨励しているようなものだ。
プログラム全体の構造を見通し良くするには、これらの小手先の
プログラム言語機能ではだめで、プログラムの作り方そのものを
考えていかなければならない。
プログラミング手法
巨大なプログラムを多数の人により開発する。そのためにはプログ
ラムを適切な要素に分割しなければならない。その分割パターンを
調べるのがソフトウェア工学だとともいえる。
- ソフトウェアライフサイクル
このモデリングと要求仕様をよりよいものとすることがプログラミング
手法の一つの目標だといえるだろう。
構造化技法
オブジェクト指向分析/開発
これらの手法はプログラム開発を分かりやすくするためのものなので、
図が良く使われることが多い。しかし、図は必須というわけではない。
構造化技法は
を合わせたような技法であり、例えば以下のようなデータフロー図に
より要求仕様を決めていく。
このような方法は、以下のような利点ある。
- データの流れが良く見える
- 流れるデータと処理をおこなうバブルが良く分離している
しかし、これは実際には欠点でもある。
- データはファイルであり、データベース設計等の視点にかける
- リアルタイムでの応答は、このようなデータフローにはなりにくい
- プログラムコードの再利用、仕様の変更等に対処されていない
構造化技法は事務処理等のアプリケーションを作成するのには向いているが、
GUIを含むプログラムや、リアルタイムを重視したアプリケーションには
力不足ということができるだろう。
オブジェクト
オブジェクトといっても、別に普通のデータ構造と変わらない。違うのは、
- メソッドと呼ばれる関数を持っている
- メソッドを通してのみアクセスできる変数を持っている
ぐらいだろう。したがって、特にオブジェクト指向に対するサポートがなくても、
プログラム全体で「オブジェクト指向にプログラムする」という約束を
守れば、それで良い。構造化技法もその点では同じである。
Prev
Next
Kono's home page