Share
Embed
JJUG 2019 Spring 発表資料 ソフトウェア設計の教育工学的な分析と育成へのアイデア
Masatsugu Matsushita
May 18, 2019
Transcript
44 slides
-
自己紹介 名前 松下正嗣 SI系プログラマ/研修講師 去年独立しました!駆け出しフリーランス
会社( https://www.ander-prime.com/ ) twitter (https://twitter.com/masatsugumatsu) -
ソフトウェアの設計スキル 研修で教えるの、正直難しい。ぶっちゃけセンスや好み? 様々な流派もあり、正解がない 多分、研修に期待されていない。 講師にレベルの高い人がいない?
OJTで師匠から伝授。。。 とはいえ、一回分析してみることで何か役に立つのではないか、と考 えた。 -
やり方 手順 1. できるようになりたい行動をパフォーマンス目標として記述する。文脈や 背景も含めて マニュアル観たり、ググれる環境下での行動なのか、そうでないのか 2. 行動をステップに分解する
具体的なシーンを映像として思い浮かべて実施するのが大事 3. 各ステップで必要なスキルを定義・記述する。 「理解する」などの抽象的な表現ではなく、「例示できる」、「定義できる」など。「例示で きる」が有効 4. 学習目標が達成されたかを判定するテストを開発する 5. テストが通るようなカリキュラムを開発する -
スキルの分類 言語情報 定義できる/例示できる、などによってスキルが記述される。認知技能の下 位スキルになる。 知的技能 ルールを適用するなどの高度な技能。正解がない場合が多い
観察→認知→判断が行われる。 運動技能 訓練が必要な身体操作。タッチタイピングなど 態度 特定の選択や判断をする傾向 -
下位スキル 下位スキル あるスキルの前提となるスキル/知識 例:掛け算の前提としての足し算。メソッド定義の前にメソッドの構文を説明 する。 意外と成長しない原因は下位スキルが不足していることが多い。
クラスとインスタンスが分からない→実は代入(=)から分かっていない。。。 下位スキルをしっかり定着させることで上位スキルは自然と身についていく 可能性がある 百マス計算 -
方向付けのベース タイプ 問い 例 プロトタイプ どのようなものか オブジェクト指向の3要素、等 先行オーガナイザー どこに位置づけられるのか。 オブジェクト指向/手続き型/関数型
アルゴリズム/手順 どのような手順を踏むか オブジェクト指向設計プロセス システムモデル なぜ、このようになっているのか オブジェクト指向についての詳細な理 論。メイヤーのような。 胚細胞 どこから来て、どこへ向かうのか どのようにオブジェクト指向の概念が生 み出されたのか、どのように変遷した のか ユーリア・エンゲストローム『変革のための研修デザイン』P87に例を追加 例:オブジェクト指向の学習における方向づけのベース -
ソフトウェア設計メソッドの成り立ち あらゆるソフトウェア開発の目的 ビジネスゴールをもたらすソフトウェアビジョンの実現 そのためにはコントロールを失わず、コストの肥大化を防止しながら開発を 進める必要がある 中心的な問題:コントロールを失うリスク=デスマーチ
非線形の複雑さの上昇 減らないバグ 変更できないコード(動くコードは触るな!) →ソフトウェアエンジニアリングのゴールは「複雑さに対処すること」 -
ソフトウェア設計メソッドの成り立ち どのように分割して結合すると制御できるのか 本質的複雑さ(『人月の神話』) 「本質的複雑さ:人間系/ビジネス系観点」と「付随的関心事:技術的関心事」 ソフトウェアの複雑さの内、ビジネス/人間系に由来する複雑性は、物事の本質上複雑 なものであり、取り去ることができない。
技術ではどうにも解決できないものであり、中心的に取り組む必要がある DDD/「ドメインを隔離する」の原型的アイデア その他 疎結合と高凝集 関心事の分離 レイヤアーキテクチャ(依存関係のルール化) -
19 @2018 Ander Prime co,Ltd 複雑(複合)系/Complex 煩雑系/Complicated 自明系/Obvious 混沌系/Chaos 無秩序
カネヴィンフレームワーク 5つのものの見方 -
ソフトウェア設計メソッドの発展 カネヴィンフレームワークにおける2つの複雑性 Complicated(煩雑) 専門家による注意深い分析によって解決が可能なもの Complex(複合/複雑)
因果関係、メカニズムは事前には確定できない。事後的にだけ分かる 学究的なソフトウェアエンジニアリングは前者を前提。実践プログラマーやアジャイル以降のメソッドは後者。 複雑さを受け入れる ビジネスの複雑さ(事前に理解できない)を全面的に受け入れ、テスト容易性/変更可能性/開発容易性が強 調されるように。 複雑さをコントロールするのではなく、実践の中から創発させる 継続的なモデリング ソフトウェアを成長させる 事前のモデリングにより本質的構造を見つけ出すのは流行らなくなった。 対象の問題領域によっては今でも有効 -
設計のステップ ビジネス 要件を精緻 に把握する 概念/要件を 関心領域に 分類する アーキテク チャに基づ いて詳細設
計/実装す る リファクタリ ングする -
ビジネス 要件を精緻 に把握する 不足/不明確な 情報を明確にす る質問を発する 要件記述/発言 から矛盾点を洗 い出し、確認す る質問をする
自分が気づいてい ない情報を得るた め、オープン質問 を使う。 要件記述を記述 しなおし、確認を する。 効果的なオープン質問 を例示できる。 言葉の多義性に基づい た誤解を例示できる。 抽象的言葉の場合、具 体例を思い浮かべ、限 界事例を確認質問を発 することができる オープン質問が必要な 理由を説明できる こんな感じでステップを詳細化して スキルを割り出していく -
ビジネス要件を精緻に把握する 重厚長大な要件定義書であれ、ユーザーストーリーのような簡素なものであれ、要件の出し手とのコミュニ ケーションは必須。 含まれる行動 不足/不明確な情報を洗い出し質問する 暗黙の要件、特に機能要件に付随する非機能要件を確認するために質問する
要件について将来的な変更の可能性を質問する 矛盾点を洗い出し、整合性を確保するために質問し、話し合う 自分が気づいていない情報を得るため、オープン質問を使う 前提となる態度/スキル 多くを誤解している可能性を踏まえ、知らないこと/勘違いしていることを見つけ出そうとする態度 言葉の多義性に基づいた誤解を例示できる。 要件確認の状況においてオープン質問が必要な理由を説明できる 抽象的言葉の場合、具体例を思い浮かべ、限界事例を確認質問を発することができる 効果的なオープン質問を例示できる ビジネス 要件を精緻 に把握する -
概念/要件を関心領域に分類する 文書化するにせよ、しないにせよ、ビジネス要件に含まれるシステム 要件を抽出し、関心領域に再配置する 含まれる行動 要件や概念をビジネス領域と非ビジネス領域、さらにそれらのサブ領域に振 り分ける。
(ビジネス領域においてユースケースを記述する) 要件を吟味し、必要に応じて新しい概念を開発する。 整理できないものが現れたら領域構造を修正する 前提となる態度/スキル ソフトウェアの非線形的な複雑性の増大を警戒する態度 同一領域内での名前の不整合、不統一、矛盾を識別する。 概念/要件を 関心領域に 分類する -
アーキテクチャに基づいて詳細設 計/実装する アジャイルなどでは、ほとんど前のステップと同時に行われるが、ある程度 どのドメインに振り分けるか想定をしてから、実際の詳細設計と実装を行う。 含まれる行動 領域構造を設計に反映させてモジュール/パッケージ設計を実施する
アーキテクチャを維持しながら、要件を実現するコードの設計/実装/テストを行う アーキテクチャを破る必要が出てきたとき、アーキテクチャ、もしくは要件を調整する 統一の必要がある設計方針はアーキテクチャに追加する 前提となる態度/スキル ビジネスニーズを優先しつつも、アーキテクチャの整合性を維持しようとする態度 アーキテクチャを破ることによるデメリットを具体例を挙げて説明できる。 アーキテクチャの要素(各レイヤの役割など)となっている理論を説明し、アーキテク チャ違反の実装を例示できる アーキテク チャに基づい て詳細設計/ 実装する -
ここでのアーキテクチャの定義 ここでのアーキテクチャの定義 「主観的要素であり、プロジェクト内の熟練開発者がシステム設計に関して共通して理解してい る重要で変更しにくいことがら」 マーチン・ファウラー 例えば
ソフトウェア全体の構造はエヴァンス流のレイヤアードキテクチャにしましょう ユースケース層を導入しましょう。 標準APIはドメインからは利用しないようにしましょう。 非ビジネス領域の関心事はAOP/フィルター/インターセプター等の機能を利用してドメインからは 隔離しましょう。 ドメイン内のレイヤードアーキテクチャだけでなく、非ビジネスの領域にもアーキテク チャはある。 ログ出力は共通部品を介して出力する、等 -
リファクタリングする アーキテクチャ違反や関心領域の混在などのこれまでのステップで実施してきた設計の見落としの検証のほか、設計原則やリファ クタリングの定石、適宜適用してコードを改善する。 含まれる行動 実装に異なる関心領域が混在していないかを検証し、必要に応じて実装を別の関心領域に移動させる。 アーキテクチャを破った実装がないかを検証し、必要に応じて実装もしくはアーキテクチャを修正する。
設計原理を適用し、改善する より意図が不明確であったり、あいまいであったりする実装を見つけて修正する。 重複している実装があれば共通化できる概念/名前を見つけて共通化する。 データとそれにまつわる処理が別のクラスに分離している場合は一つのクラスに移動する。 SOLID原則違反の実装がないかを検証し、必要に応じて修正する。 関心領域の構造、アーキテクチャを前提として、分かりにくく、驚きを与える実装はないかを検証し、必要に応じて修正する。 リファクタリングの結果、過度に煩雑になり、設計の理解性が損なわれていないかを検証する。 リファクタリングの結果、ビジネス要件やアーキテクチャの改善アイデアが生まれたらそれをフィードバックする。 前提となる態度/スキル 設計コンセプトが統一され、理解しやすい状態を維持しようとする態度 設計原理を定義/例示でき、原理を緩めても問題ない場合を説明できる リファクタリ ングする -
態度の重要性 設計の各ステップで死活的に重要になるのは、態度 複雑性を受け入れて、分かった気にならずに対処しようとする 複雑性の増大を警戒し、設計思想/アーキテクチャの統一性/理解性の維持・増大を重視する 態度の育成
前提となる知識/スキルの付与 その態度のメリットを体験させる。問いかけ「分かりやすくなったか?」 ビジネス上の必要を伝えることも大切。大局観がないと無駄に細部に拘ったりする場合もあり、状況に応じて知 識を扱えない。そもそも、多くの設計メソッドはビジネスゴールを達成するためのものと伝えること。 態度の育成は比較的難しい 部屋が汚い人ときれいな人もいる。多くの場合、掃除の能力がないわけではない。 得意な人とペアプロをさせるなど、チームとして苦手分野を補完しあう体制をとることも必要。 -
概念(言葉)操作の重要性 設計を改善するステップの多くは概念操作に関係し、設計スキルの重要な下位スキルになって いる あるカテゴリにはまらない概念の検出 抽象概念の具体化による検証、具体的事例の抽象化による概念の発明 概念操作スキルの育成
概念の輪郭をはっきりさせていく作業を続ける 例を挙げる 範囲/境界を具体的にしていく 文脈によって定義が変わるという自然言語のもつ特性を理解させる そもそも、我々は言葉を適当に扱っている、という現実に気づかせる 「ドメイン」や「サービス」という言葉のどうしようもない多義性 意図的に、努力して概念の整合性を保とうとしない限り、我々は矛盾した言葉を使い始める。コードに概念を刻印することは、 それを防ぐ手助けになる -
方向づけのベースとしてのエンジニアリング の成り立ち モデリングやリファクタリングは正解がなく、いつまでも終わりはない、どこまでやれば いいのか、の基準はない 一つのヒントは、許容できるコストで開発/変更をコントロールできる程度の複雑さにとど められているか 今の現状の設計でビジネスゴールが達成できているのであれば、変える必要はないか
もしれない ただし、「鉄道の逆説」(ワインバーグ)に注意 サービスレベルが低すぎて誰も使わないからニーズがない、と判断されること。変更が高価で難 しすぎて機能追加が少なくなる。。。 設計メソッドを若手に教えていく上では、そもそもどういう背景や問題からそれが生み出 されたのかを共有していくことで、若手が自発的、実践的な判断をすることを助けると思 われる