2010年3月27日土曜日

十分性,完全性,プリミティブ性

SWEBOK 2004 の設計の章で次の基本原理が挙がっていました.

  • 抽象化(Abstraction)
  • 相互結合と凝集強度(Coupling and cohesion)
  • 分割とモジュール化(Decomposition and modularization)
  • カプセル化・情報隠蔽(Encapsulation/information hiding)
  • インタフェースと実現の分離(Separation of interface and implementation)
  • 十分性,完全性,および基本性(Sufficiency, completeness and primitiveness) 
このうち,最後の十分性,完全性,基本性(プリミティブ性)について原典をあたってみました.SWEBOK 2004 によると [Bus96] 第6章と [Lis01] 第5章でした.このうち [Bus96]は既に持っていたので参照しましたが,[Booch90] を引用していました.


[Booch90] には十分性,完全性,プリミティブ性について下記のように書いていました(改段落は僕が入れました).


By sufficient, we mean that the class or module captures enough characteristics of the abstraction to permit meaningful and efficient interaction. To do otherwise renders the component useless. For example, if we are designing the class Set, it is wise to include an operation that removes an item from the set, but our wisdom is futile if we neglect an operation that adds an item. In practice, violations of this characteristic are detected very early; such shortcomings rise up almost every time we build a client that must use this abstraction.
By complete, we mean that the interface of the class or module captures all of the meaningful characteristics of the abstraction. Whereas sufficiency implies a minimal interface, a complete interface is one that covers all aspects of the abstraction. A complete class or module is thus one whose interface is general enough to be commonly usable to any client. Completeness is a subjective matter, and it can be overdone.
Providing all meaningful operations for a particular abstraction overwhelms the user and is generally unnecessary, since many high-level operations can be composed from low-level ones. For this reason, we also suggest that classes and modules be primitive. Primitive operations are those that can be efficiently implemented only if given access to the underlying representation of the abstraction. Thus, adding an item to a set is primitive, because to implement this operation Add, the underlying representation must be visible. On the other hand, an operation adding four items to a set is not primitive, since this operation can be implemented just as efficiently upon the more primitive Add operation, without having access to the underlying representation. Of course, efficiency is also a subjective measure. An operation is indisputably primitive if we can implement it only through access to the underlying representation. An operation that could be implemented on top of existing primitive operations, but at the cost of significantly more computational resources, is also a candidate for inclusion as a primitive operation.
--- Grady Booch: Object Oriented Design with Application


僕が訳してみました.突っ込み歓迎.



十分であるとは,そのクラスやモジュールが意味のある効率的な相互作用をするのに十分な抽象化の特性を捉えていることを意味する.十分でなければ部品が役に立たなくなる.たとえばもし Set (集合)クラスを設計しているときに,集合から要素を削除する操作を加えることは賢明であるが,もし要素を追加する操作を無視してしまうと役に立たなくなる.実際には十分性に反することは早期に検出できる.そのような欠点はたいていこの抽象化を使う顧客から指摘される.

完全であるとは,そのクラスやモジュールのインタフェースがその抽象化の全ての意味のある特性を捉えていることを意味する.十分性が最小のインタフェースを意味するのに対し,完全なインタフェースはその抽象化の全ての観点をカバーする.その結果,完全なクラスやモジュールのインタフェースはあらゆる顧客が共通的に利用できるくらい十分一般的である.完全性は主観的な事柄であり,やりすぎになることもある.

多くのハイレベルな操作はローレベルな操作から構成することができるので, ある特定の抽象化に対して全ての意味のある操作を提供することは,ユーザーを困惑させ,一般には不必要である.この理由からクラスやモジュールがプリミティブであるということが導かれる.プリミティブな操作とは,その抽象化の基礎となる表現形式へのアクセスが与えられたときのみに,その操作が効率的に実装できることを意味する.その結果,集合に要素を加えることはプリミティブである.なぜならば,この操作 Add (追加)を実装することにより,その基礎となる操作は明らかになるからである.一方,集合に4つの要素を加える操作はプリミティブではない.なぜならば,この操作はよりプリミティブな操作 Add によって,基礎となる表現形式に対するアクセスをすることなく,効率的に実装できるからである.もちろん,効率性も主観的な尺度である.ある操作を基礎となる表現形式へのアクセスを通してのみ実装できるとき,その操作は議論の余地なくプリミティブである.あらゆる操作は,既存の最上位のプリミティブな操作で実装できるが,より多くの計算資源を犠牲にしてプリミティブな操作として包含する候補にもなる.


[Booch90] Grady Booch. Object Oriented Analysis and Design with Applications. Benjamin-Cummings Publishing Company, Subs of Addison Wesley Longman, Inc.
  



[SWEBOK2004]  英語版 



[Bus96] F. Buschmann et al., Pattern-Oriented Software Architecture: A System of Patterns, John Wiley & Sons, 1996. 





[Lis01] B. Liskov and J. Guttag, Program Development in Java: Abstraction, Specification, and Object-Oriented Design, Addison-Wesley, 2001.

2010年3月5日金曜日

スパイラルカリキュラム: 鈴木先生との議論

教材設計マニュアル鈴木先生にOOP演習を見てもらいました.議論は多岐に渡り,たくさんのアドバイスとヒントをいただきました.改めて感謝します.

今回の記事では,鈴木先生からいただいた,OOP演習の核となるアイデアを紹介します.それが,スパイラルカリキュラムという考え方です.



話の発端は,以前「OOP演習で学ばせたいこと(2)」で紹介した学習目標(上図)を見せて,僕が「でもこの学習目標は,そのまま順番通りに教えるのではなく,例題を演習していくうちに,順番が前後しながら重要な学習目標が繰り返し登場して『ほらね,この原則は重要でしょ?』と定着を図りながらすすめていきたい」と言ったことから始まります.すると鈴木先生は「それは良い.それをやるならスパイラルカリキュラムだ!」とおっしゃいました.

僕の理解では,スパイラルカリキュラムは文字通り,まず基礎的な学習目標を一通り習得させ,その後らせん状に発展的な学習目標を習得していくモデルです(上図).ポイントは1回目の学習では基礎的な学習目標やシチュエーションを厳選し,かつ例題の中でそれらの基礎的な学習目標で完結するように構成することです.2回目以降は,それに発展的な学習目標や例外的なシチュエーションなどを追加してレベルアップしていき,だんだん大きな例題に取り組めるようにしていきます.

例題の設定のしかたはさまざまです.

  1. 例題そのものが1つのテーマに沿っていて,最初の例題を部品の一部として発展的な学習を進める方法.学習効率はいいのですが,一貫した適切な例題を考えるのが難しいです.
  2. レベルアップするごとに,より複雑な例題に取り組む方法.学習目標に合わせて適切な例題を設定することができますが,例題そのものを理解する時間がかかり効率が悪くなります.
  3. 上記の折衷案もあり得ます.たとえば5段のレベルを設ける場合,2,3個の例題を用意して,複数のレベルで例題を共有するなど.
具体的な例として,GDM (Graded Direct Method) による語学の学習を挙げていました.例えば英語だったら,学習中に日本語を含むその他の言語を一切使いません.そして毎回の授業で習う英語とジェスチャーで全ての会話が完結するように構成します.なんでも最初は You と I から始めるそうです.そして第3者が登場して he や she を学ぶ,という具合に発展していきます.面白いのが一般的に中学英語で割と最初に学ぶ "This is a pen." よりも先に "This is my pen." を学習するんだそうです.「これは僕のペンだ」「あれは君のペンだ」と会話をして,そこへひょっこり新たなペンを登場させます.「これは君のペンか?」「いいや」「これは僕のペンではない」ときて,そこで "This is a pen." と来るわけです.こうすると,不定冠詞 a の意味が自然と体感できます.

もう1つのしかけとして鈴木先生が提案したのが,ソフトウェア工学の原理・原則のありがたみを体感させるような構成にしたらどうだ,ということでした.先ほどの GDM の例でも不定冠詞がなぜ必要かを体感する例題になっていましたが,同様のことをOOP演習でもやるべきだというのです.具体的には最初のレベルでは,とにかくグチャグチャで構造化されていないコードでも,とにかく気合いでできてしまうような形にします.そして高度なレベルの例題にトライさせて,何か手立てを打たないとやってられないという気分にさせておいて,構造化を教えるわけです.

この話を受けて1つ思いついたのが,派生開発をやらせるとありがたみを実感できるだろうというアイデアです.似たような製品を開発させてみて「なんか似たようなコードが複数現れるよね,これを何とかまとめたい」と思わせるわけです.

そういう教材設計をするにはどうしたらいいかというと,次の点がポイントです.
  1. 教えるべきそれぞれの学習項目に対してどういうシチュエーションでありがたみがあるかを具体的に考える.
  2. 学習項目にレベル付けをしてグルーピングする.
  3. 上記を考慮して具体例を順番に並べて教材化する.
これらのアイデアがもし実現できたら,それはかなり面白い教材になるでしょう.そう思うとワクワクしてきました! 問題は,うまくフィットする題材を思いつくかですが,案ずるよりも産む方がやさしいかもしれません.まずはいろいろ手を動かして考えてみたいと思います.

追記: Twitter 上の反応はこちらです.

2010年3月3日水曜日

ソフトウェア工学教育ワークショップ --- 求める人材像(技術スキル)

2010年2月27日(土)〜2月28日(日)に北九州にて,本学の「ソフトウェア工学概論」の授業で特別講師をお願いしている企業の方々をお招きして,ソフトウェア工学教育に関するプライベートワークショップを開催しました.

せっかく貴重な時間を割いていただいて合宿をするので,大上段に構え,大学におけるソフトウェア工学教育はどうあるべきか?という問題について議論を深めようと考えました.もっとも,そういうことは本来なら「ソフトウェア工学概論」の授業を始める前に議論すべきだったのかもしれません.しかし,前向きに解釈すれば,一通り講義がそろった段階で改めて振り返ってみることで,より深い議論になったと考えることもできます.

2日間の議論の成果として,企業が求める人材像,つまり大学でソフトウェア工学を学ぶ新卒学生に対して,企業が求めるスキルとは何かをまとめました.これをたたき台に,より深い議論ができたらいいなと思っています.

前提として,ワークショップ参加者が主に組込みソフトウェアに携わる技術者だったので,ここでいう企業とは組込みシステム開発を主たる業務としている企業だとしています.もしかすると業務系だと事情が異なるかもしれません.

また既に世にあるITSSETSSなどのスキル標準を多少参考にしましたが,打ち出している方向性はだいぶ違います.

この内容は,学生さんが学習計画を立てる上でも参考になるでしょう.企業の方たちは,ソフトウェア技術者を目指す新卒学生に対して,こういうことを求めているのです.

スキル体系

大別して技術スキル社会スキルヒューマンスキルの3種類があると考えました.ただし,これらは完全に独立しているわけではなく,互いに関連しあっています.今後,このあたりの関連についても考察していく必要があります.今回はこのうち技術スキルについて書きました.

技術スキル

実はワークショップで「ソフトウェア工学で大学が教えるべき技術スキルはない」とおっしゃった方がいました.ソフトウェア工学で話題になる技術は,陳腐化が速く,氷山の一角に過ぎないので,むしろ大学では流行にとらわれず,基礎となる数学や論理的思考,あるいは技術を獲得するためのスキルなどに注力すべきであるという主張でした.

それにたいし,現在どのような技術があって,それらはどういう問題意識で生み出されてきたのかという「土地勘」を身につけることは重要だという議論も出ました.土地勘を身につけるには,具体的な技術の事例を多く知っている必要があるわけです.

そういう議論を踏まえ,現在,企業で問題になっている事柄を意識しながら,基礎として身につけてほしい知識は何かを私たちは考えました.暫定的な結果として,モデリング,標準化,ソフトウェア開発技術,ドキュメンテーション,リーディング,位置づけの把握といった項目を挙げました.

モデリング能力

私たちは,モデリング能力が技術スキルの中で最も重要だと結論づけました.

ここでいうモデリング能力は,たとえば UML の読み方・書き方を知っているという狭い意味だけではありません.モデリング能力は,たとえば高校の物理でも扱われます.物理の授業では,文章題を読んで,図を書き,ニュートン方程式などの数式を立てて解を導くことをします.この行為は,実世界で起こる現象を抽象化し,モデルとしての図や数式を記述して問題を解決するという広い意味で,モデリングの一種だと考えます.今,このような広い意味でのモデリング能力が求められていると私たちは考えました.

モデリング能力につながる基礎的ドメインモデル


モデリング能力を養う観点,組込みシステム開発で必要なドメイン知識を理解する観点から考慮して,次のような基礎的なドメインモデルを知っておくと役に立つという議論になりました.

  • 数学
  • 物理
  • 制御
それぞれについて簡単にまとめます.
  • 数学
組込みシステム開発では,離散系(コンピューターの中の世界)と連続系(物理世界)を両方扱うので,どちらにも通じていると応用がききます.また,抽象化のセンスは,数学によって養われると考えられます.
  • 物理
組込みシステムではセンサーやアクチュエーターで物理世界を扱うので,基本的な物理の法則や概念を知っておくことは必要です.次の制御理論を勉強するにも,物理を勉強することが重要です.

余談ですが,私は物理実験も担当しています.どうせ物理実験をやるならば,組込みシステムに関連した形で教えられたらと思っています.が,全学横断の科目であり,教材等を新規開発するコストもかかるので,改善をずっと見送っているところです.
  • 制御

基本的なフィードバックなどの制御について知っておくと,主にアクチュエーターの制御をどうすればいいかが理解できます.

モデリング能力を鍛えるには何が必要か


モデリング能力を鍛えるには何が必要かという議論で,抽象・捨象,観点といった概念を教えることが必要だと私たちは結論づけました(それで全てだというわけではないです.他にも必要かもしれません).

抽象・捨象の概念は,前述したような数学や物理の文章題によって鍛えられると考えられます.またモデリングには「ある観点に沿って思い切って捨象する勇気」が必要です.こういったことをモデリング教育で伝えるのが重要だと私たちは考えました.


機能・構造・振る舞いの3面モデリング

観点に関連して,UML で一般的な機能・構造・振る舞いの3面からモデリングをする考え方を身につけさせたいという意見がありました.特に,これらの間の因果関係を事例に結びついた形で身についていると,複数の観点を考慮した「いいモデリング」をしやすいです.


モデリングの教え方

大きくわけて,抽象論から入って具体論に入る教え方と,具体論から入って抽象論に入る教え方があります.大多数の学生さんにとっては後者の方が理解しやすいだろうという意見でした.


標準化

この議論が始まって一番最初に挙がったキーワードが,実は標準化でした.例えば頂上人材としてCIO(Chief Information Officer) やアーキテクトが足りないことを考えると,プロセスやプラットフォームなどの標準化を推進できる人材を育成する必要があります.


ただ標準化を推進する立場の人は少数精鋭でいいかもしれないので,大学生や大学院生の教育を念頭に置いたときには,まずは「標準化についていける人」を育成すべしと結論づけました.その流れで,PSP (Personal Software Process)の話や,AUTOSAR (AUTomotive Open System ARchitecture)などの話,はたまた標準化戦略の話まで発展しました.


今後は,標準化に必要な知識が何かという議論が必要ですね(作る方もついていく方も).


ソフトウェア開発技術


発端は「いろいろ技術スキルについて議論したけど,今時の新卒にプログラミング能力はどの程度要るの?」という話からでした.さまざまな話が出ましたが,ソフトウェア工学のありがたみが実感できる程度にはプログラミングをしててほしいね,という結論でした.規模としては1000行程度,できれば複数の人間で開発している経験があるのが望ましいでしょう.そこから派生して,せっかく複数の学生さんが同じ場に集まっているので,チームで働く能力を開拓するといいという話になりました(パーソナルスキルに続く).

他には,基本的な設計手法,UML をつかった開発プロセスについて経験があると望ましいという意見がありました.


ドキュメンテーション


理系文章の基本的な作文能力は,社会で強く求められているにも関わらず,日本の教育では軽視されがちなスキルの1つです.日本における高校以前の作文教育は,感想文などの情緒的な文章ばかりで,いわゆるテクニカルライティングはほとんど教えていないのが現状です.

理系の大学ではまだマシな方で,レポートや卒業論文の作成を通してOJT的に指導をしていますが,指導が行き届いているかというとまだまだです.大学によっては卒業論文で初めて指導を受けたという学生も多く,しかもOJT的なので体系的な教育ではありません.

北九州市立大学では1年次必修科目の物理実験で工夫をしています.3週がセットになっていて,第1週で実験をしたあとレポートを作成し,第2週で教員のもとに来て査読を受けます.そこでいろいろ指導を受けて第3週に提出,という流れです.

私たちは,ソフトウェア工学におけるドキュメンテーションの重要性を考えると,もっとドキュメンテーション能力の開発に注力するべきだという結論を出しました.

リーディング


人が書いたコードやモデル,ドキュメントを読む能力を身につけた方がいいと私たちは結論づけました.まずどういうコード(モデル,ドキュメント)が良く,どういうのが悪いのか,実感できることが重要です.また知識習得の一手段として活用できるでしょう.品質モデルの理解にもなります.


コードリーディングを参考に教材を作るとよさそうです.



位置づけの把握


ここからは純粋な技術というよりはMOT(技術経営)的な話になります.CIOをイメージすると,技術動向の「勘」つまり自社・他社の SWOT 分析や技術ロードマップが書けるのは必須だねという話をしていました.そこで,新卒の時点では,自分や自分が研究した技術の強みや弱みといった位置づけを把握していることが重要だと私たちは結論づけました.


つづく

追記: この記事に対する Twitter 上での反応をまとめてみました.このリンクをクリック!

追記: Satohru さんが記事を書いてくださいました.このリンクをクリック!