読書会(アジャイルソフトウェア開発の奥義)第2回議事録

[ 戻る ]


-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
java 読書会  http://www.javareading.com/bof/

BOF in 高津区民館 第6会議室 at 2004/12/25 10:00 - 17:00

出席者(敬称略)
高橋(智), 門脇, 杉山, 村上, 亀井, 栗野,
丸山, 岩室, 金, 坂本,
岩永, 遠藤, 吉本, 石黒, 根本, 吉村,
西野, 高橋(徹),


朗読者: 
書記: 栗野

本 : 「アジャイルソフトウェア開発の奥義」

==

    今日は、p.102 までゆきたい ( Source Code が多いので.. )
    p.102 にボーリングのルールがある..

==

[自己紹介]
    省略

==

p.33 テスティング
    unit test は、設計や、ドキュメンテーションに近い

    test first
        実装の前にテストを作る
            必ず失敗するテストをまず作り、失敗させる !!
                # これが、ソフトウェア開発に、どんな影響を与えるか ?

    どんな関数にも、それをチェックするテストが作られる
        予想外の失敗をチェックする仕組が作れる
            開発の途中で、元の仕組を壊した場合でも、直に発見できる
                壊れることを恐れなくてすむ
                # 開発が進むにつれて、出来たコードが開発者を縛るのは不合理..

    テストを先にする
        異る観点でプログラムを視ることを強制される
            提供する側から利用する側の観点へ
                作り易いから、使い易いへ ( 設計方針の転換 )
                # 作りは一人、使うは多人数 : どちらにコストをかけるか ?
        テストがし易い仕組みにすべき
            => モジュールの分離を促す

    Test モジュールが、ドキュメントとなる仕組
        用例、最新..、コンパイラ、実行可能なドキュメント

    [例] ゲーム: wumpus ( RPG )
        List 4.1 move の test モジュール

        意図的プログラミング ( intentional programming )
            これから作成しようとするプログラムにイメージする
                イメージをテストの形で表現する
                # シンプルかつ明瞭な形で記述
                ## What を記述 ( 実装は How )

            意図的プログラミングの結果
                Room クラスがない !!
                    これでよいのか ?
                        部屋と部屋の接続 (Connect) の方がメインなので構わない..
                # 「Room Class は不要」という設計的判断をした
                ## テストを先にすることにより、設計に関する知見/判断が得られる

    # 分離への影響
        [例] payrole class

        設計の段階で、ダイアグラムだけがあるとする..
            テストを書きたいが.. ?
                様々な問題点 ( 足りないもの.. ) がある
                    データベースは ? etc..
                    Print out した結果のチェックは ?
                モックオブジェクトパターンを導入
                    本物がなくてもテストができるようになる
            モックオブジェクトを導入することによりテストを行うモジュールとモックオブジェクトが担うクラスモジュールが分離された

    q. 図 4.2 の中で、一番上 (Payroll Test) から一番下(Mock Employee Database) へ線があるのはなぜ ?
        a. PayrollTest が Mock Employee Database オブジェクトを生成するため..

    モックオブジェクトの振舞い
        テストをするだけの機能 ( 本来の物を利用しない.. )
            本物を使えばよいのでは ?
                本物は、テストのためには、複雑すぎる

    モックオブジェクトの導入から分離が生れた
        「テストを先に」ということから出てきたという点がポイント

    q. パターンとしては前からあるが名前が付けたのが偉い ?
        # 前から、スタブとかドライバなどのテスト時の概念があった

    q. テストの為にインターフェースが増える
        インターフェースの保守も大変では ?
            不要なインターフェースが増えるのは、望ましくない
        インタフェースなしで利用できない ?
            本物と同じ Class 名でもよいのでは ?
            # 同じ Class 名で、Source Code を切り換える

    q. なぜ本物じゃだめ ?
        a. モック側も開発中なので、信頼性にかける
            # どっちをテストしているのか判らない
            ## テスト済モジュールを利用して、新しいモジュールをテストすれば..
            ##   => モックは不要だが、開発手順が制限されるので望ましくない

        テストコードの量も大変
            Refactoring では、Test の対象を、Public Interface に限定
            # 本当にそれだけでよいのかも疑問だが..

        q. 正しいモックが必要だけど、その「正しさ」はどうするの ?
            a. 明らかな機能だけを実現する形で記述すれば..

        q. テストコード ( モック ) は動く必要があるよね ?
            手で書くのは大変では ?
                機械的に生成するツールが欲しい

        q. モック維持の問題
            a. インターフェースを変えなければ、モックを変える必要がない

    q. Class 名にわざわざ Mock と付けるのは ? ( 本物はいけない理由は ? )
        a. Tool 問題 ?

        名前を別にすることによって、本物とモックを区別する(機
        械的な..)手段が得られる

        # 4.1.2 に関連記載

        大きい機能を持つものは、(本物を作るのが大変なので..) モックを作る
        値を変更するだけなら、モック ( cf. p.385 ) にしなくても..
            モックを作るかどうかの判断はどこで ?

        # モックにするかどうかの判断基準は難しい..
        #    D.B. は、実装が大変なのでモック
        #    employee は、本物にする ?
        #        実際のものとモックの差によってどちらにするか判断 ?

    q. トランザクションの確認がしたい
        モックではチェックできないのでは ?
            q. (トランザクションの) 失敗例の処理は ?
                a. 確実な例外を起すモックを提供すればよい

    q. モック作成のコストが大きいのでは ?
        a. モック作成ツールもある ( シーサーの一部 : テストフレームワーク )
            リフレクション API を利用しているので使い辛い

        # cf. モックオブジェクト.com

        Function test / unit test 用 ( レイショナルツールにある.. )

        モックを自動生成するツールが今後増える

p. 38 4.2 受入テスト

    unit test だけでは、System 全体の test ができない
        => 受入テストが必要

        unit test : white box 型, 開発者
        受入テスト : black box 型, 仕様作成者, 顧客, QC グループ

    受入テスト
        究極の仕様 ( コンパイル, 実行が可能 )

    受入テストの自動を行う努力をすると、その結果として、モジュールの分離が促進される
        アーキテクチャへの影響

        unit test : 小さな部分への影響
        受入テスト : 大きな部分への影響

p.39 4.2.1 受入テストの例

    最初の受入テストでは、固定給だけを考える
        # 他のパターンは、次のイテレーションで考える
        意図的プログラミング
            => 自分が、「こうあるべきだ」と考えることから始める..

        受入テスト : 保守の対象になる ???
            => (スクリプト言語を利用して) Text で書くことが望ましい

    # unit test は、変更されないが、受け入れテストは、変更される.. ?

    受入テストの中にある記述
        テスト対象の仕様を表現する部分
        スクリプト自身の固有 (Test の為) の表現 ( verify とか.. )
            フレームワークがこれらを区別し処理できる必要がある

        (受入テストの)フレームワーク
            入力先を、スクリプトでも、人手からも受けられる事が必要
                => フレームワークへの圧力
                # XML を利用する ?
            # 最初は、ファイルから, 次は、ソケット.. etc..

            出力のチェックは ?
                アプリケーションの出力を XML で出せばよい
                フレームワークが XML から内容をチェックできる
        # データを XML でやりとりすることが重要 ?

アーキテクチャへの影響
    Test をしたいので ..
        I/O を XML にすることになった ( UI をビジネスモデルから分離する )
        分離が促進された
            # いずれもアーキテクチャへの良い影響

[まとめ]
    動作検証のメリット
        安心して開発を進めることができる
        テストで問題をすぐに発見できる
        # 一旦高めた、レベルを落さないという仕組
    ドキュメントとしてのメリット
        unit はプログラマ用の言語
            # 本来、プログラミング言語はモジュールの内部仕様
            # [実装]を記述する言語..
            #    => Test は、モジュールの外部仕様を記述する形に..
        受入テストは顧客用の言語
            # 言語の分離 ?
    アーキテクチャへのインパクト
        テストを実施するための工夫を行うことが
            (間接的に..) モジュール設計を良くするための工夫になっている

    q. スクリプト : この人が勝手に考えたもの ?
        q. これから作るってこと ?
        q. XML も必要ってこと ?

    q. 受け入れテストは抽象的 ?
        q. UI のテストはどうするの ?
            a. 日本は UI へ要求が大きい
                # アメリカは UI に重点を持たない.. ?
            UI のテストは自動化が難しい
                自動化できないところはさけてよい ( 割切り )
                # 最終的に人間が必要な部分は別と考える

        q. XML は困る ( User さんが XML を触るのは.. )
            a. XML を利用しているのは Module 間
                => User は XML を知らなくても Okey

    q. 最初にスクリプトを作らないと始まらないのが大変
        a. XP では、UI から Logic というアプローチだが..
        UI が分離できれば、 Model と View の分離できるので設計的に嬉しい

        # Sun の JFS は UI のことを考えているが、そのテストは... ?

    q. logic level の検証段階で ( unit test で.. ) コストを下げればよい ?
        単体テストが足りない為に、受入テストで悲惨なことに..

    a. 受入テストは重要
        自動的にできるスクリプテイングができるのは羨ましい
            # QC 部門にいた。開発中のパッケージのテストで、
            # 以前に問題だった点が改良されているかどうかを
            # チェックするのに、手動でテストを行っていたの
            # で、うんざりした..

==

p.43 5. リファクタリング

    人間の注意力だけが不足している..

    リファクタリングの定義
        外面の振舞いをかえずに内部構造を変えること

    変更は必要なのだろうか ?
        「うごいているのならば、そのままにしておけ」

    モジュール三つの側面
        機能すること ( これだけでは不十分 )
        変化を許容する
        意図を他の開発者に伝える
            # 後の二つが、リファクタリングの目的

        # リファクタリングに必要なのは、注意力と情熱

5.1 リファクタリングの例 ( 素数の生成 )
    エラトステネスの篩法 ( 5.1 )

    q. コメントを読んで、感激してしまった。
        a. コメントを読んで、怒ることが良くある (豆蔵のコード?)

        # 特化とか、極小化という言葉を利用していて分けわからない ?
        #    特別な概念や用語を利用している場合が..

    q. この位の長さなら普通じゃないの ?
        どのような部分にリファクタリングが入るの ?

    q. コメントの JavaDoc の @variable tag が 「@変数」に超訳されている !!

    # プログラム ( 5.1 ) で気になる点を各自考えてみよう..

    ##   - マジックナンバー
    ##   - 意味不明の変数名
    ##   - モジュールの分解

    list 5.2 は test method

    q. 素数に 1 は含まれない
        a. Yes 2 から
    q. 平方根までで良い理由は ?
        a. \sqrt{N} より大きいものは、既に篩いがすんでいるから
        # cf. 後で説明がある

    # リファクタリング tool IntelliJ のIdea を使う

    [1] モジュールを三つに分けたい (list 5.3)
        初期化
        篩
        素数リストの作成

    [2] 初期化も複雑、名前を変更した (list 5.4)
        論理の二重否定を消す
            変数名前を変更することにより否定表現を無くす
        表現に対して意味を付ける ( ために、関数を作成する )
            # コメントを付けるより、関数を分離して名前を付ける
            q. 英語圏の人の場合は、それでも良いが、日本語の人はやはりコメントが..


    [3] 最終結果 (List 5.5)
        # 実は、claclMaxPrimeFactor() のコメントは間違っていて..

p. 5.1.1 最後にもう一度..

    読みやすくなったかどうかのチェックを行う

    変更を気楽にやっているようだが..
        ツールを使えば簡単
        テストをしているので、安心してもよい

    # +1 問題 : この変更は正しいのか ? 不安..
    #    => チェックプログラムを追加した..
    #        # Logic ではなく、Test でチェックしているのは気持が悪い

    list 5-8 (最終案)

    効率より読みやすさを重視する
        後から、この判断に間違いだとわかったら元に戻す

    リファクタリングを必ず行う !!
        # 食後のキッチンの後片付けのようなもの..

    q. member 変数を class 変数にするのはあり ?
        q. test に通っているならば Okey

        Multi thread の時には問題になるのでは ?
            # 「The Refactoring」 では、 「Multi thread は考慮しない」という前提だと、予め断ってあった。

    q. 二重 Lopp の構造がみえなくなるのが気に入らない
        Order が判らないが気になる ( 解りにくくなった.. )
            Test が通っていれば Okey ?
            # 最初のプログラムでは、Order が判っているので、それと同じだから.. ?
        Symbol を見易くすることが目的なので..
        Order は不要な情報ならば、納得できる..
            Order は重要なんだけど..
            # Order は外[外部仕様]にだすべき ? ( Program から解る必要もない )

    q. p.45 のコメントがなかったら判らないのでは ?
        a. コメントを付けるくらいなら、関数名でカバーしよう..
        # 本当にそうなの ? (英語だと解りにくい..)

        q. コメントは自分で解りにくい所につけるので..

p.57 プログラミングエピソード
    p.102 にボーリングのルールがある
    q. ストライクの記号が違う

    # ペア=リーディングをやってみた
        # 楽しい

    p.61 テストケースを作る場合に、signature だけを作って、中身は実装しない
        (成功する場合もあるが..) 確実に失敗することになる
        Test を作ってから、コンパイルを通し、次に(通らないなら..)通るようにする

    # 依存グラフの下から..

==

p.63
    # 途中で、他のモジュールに移る
        Linked List の必要性
            コードが要求するまで、それを実現しない

        プログラムの改良によって、完成されてゆく
            改良の終了は、Test 終了の時点
                Test の完成がプログラムの完成の前提条件
            # Test を通して、プログラムを理解/制御する

    # p. 67 誤殖 「必要」が「必用」になっている

        テストもリファクタリングする.. ?
        # junit 問題 ?
        #    setUp の作成

        仕様を満足していないことが明らかなコードを作ってもよい ?
            => 「偶然によるプログラミング」
                動く保証のある unit を追加したり削除するという作業をゆきあたりばったりにを進める

    ストライク機能の追加は、プログラムのあちらこちらに挿入されている..

    q. (p.72) firstThrow は、local と、private の二つで利用されている。
        a. Compiler は Warning をださない
        a. lint 系の tool や gcc -WALL なら出す.

    テストに網羅性を持たせるために、相談だけで決めてよいの ?

==

p.82 からリファクタリングが始まる

    q. getCurrentFrame が必要な利用は ?
        # それ単体は意味がないのでは ?
        a. テストメソッド (scoreForFrame に必要) を作るために必要
        # cf. p.94 : つまり、結局、「本当にはいらない」という結論でした..

    # p.82 からの作業はリファクタリングのツールで自動的にできるのかな ?

    # instance 変数 ( ball ) が class 変数になっているのは、気持が悪い

    ペアプログラミング :: 一方が、他方を監視している

    q. p.90 の「これ」とは何を表している
        a. Top Down テスト主導設計

    q. これらのリファクタリング作業は tool で一発 ?
        a. 一発とはいえなくても、それほど大変じゃない。
        # Class 全体としては、簡単じゃなさそう..
        # 生成された Class の不完全さは、チェックしてくれる。

    q. 使っていない変数もチェックしてくれる ?
        a. C# はいう。javac はいわない

    # コードが望んでいるものは ?

    # p.100 誤殖 : 「どういたしまて」

    q. これで Okey ? 最初の要件を満していないのでは ?
        a. これは、最初のイテレーション ( ストーリィ )
            # 残りの部分は、次ぎ以降のイテレーションで実装

    q. コメントが少い
        a. コメントを書かないというポリシィ
        a. テストケースにコメントを入れるのでは ?

    q. 日本語を入れれば ..
        a. junit を Localize して「テスト」で Okey にする

    q. thorows, pins, ball 等の名前がしっくりしない
        ネイティブの人には自然 ?
        throws は元々 class 名として扱っており、最後に変数になったので変になったのでは ?

    q. 最終結果が行うサービスは何 ?
        score は不完全な場合 ( ストライクの直後.. ) は ?
        Test Case が不完全
        そうしないってという前提じゃなかったかな ?

    q. もし、「ストライクの個数を知りたい」という追加がでたらどうする ?
        プロセス志向 ?
            不必要な要求は実現しない
        q. オブジェクト志向 ( 改良が容易 ) が反映されているの ?
            リファクタリングしているから ?

    q. 実際に当て嵌めてどうなるかが知りたい
        パンチが弱い
            本というメディアの限界
        業務に当て嵌めるとすると ?
            本当にこうするの ?

        問題が小さいのでは ?
            大きいものでも小さいもの繰り返しで ?

p.101 6.2 結論
    テストを最初に用意し、小さなステップを繰り返すことで展開すること !!
    # p.101 誤殖 : 「繰り返す」 => 「返す」

    q. 設計とコーディングは不可分では ?
        概要設計と、詳細設計は担当者が違うので..
            概要設計は値段を决めるまで
            詳細設計はコーディングと同じ ?

        SE は設計, PG はコーディングという仕組は失敗 ?
            # 給料も違うし..

        要件定義、設計、コーディングを分離することに意味があるか ?

    テストコードは、要件定義 ?

    q. 「設計」とは ?
        外部設計と内部設計の分離
        外部設計は要件定義 ?
            System を中心に考える
            # WF モデルでは..

    非プログラマからみると設計とは、ハードウェアの設計図の事
        設計と製造のイメージをそのままソフトウェアに導入しても上手く行かない

    製造 ?
        CD-ROM への焼きこみのこと ?
            パッケージの場合ならそう
            特注ならば、存在しない

        特殊な用語 ?
            コーディングは製造 ?

    設計とコーディング
        巨大企業では、完全に「コード作成」を行う場合もある
            => 本当にコーダーとして振舞う
                将来は、人件費用の安い所にコーダを求める動きも
                    失敗しているのでは ?

        巨大システムの作成と、この本が想定しているシステムでは方法論が異るのでは ?

        大きな規模システムへは
            分割統治が必要
                cell モデル ?

    現状がアジャイルを要求している ?
        今の受注形態は最終まで仕様が決らない
            ウォーターフォールモデルではだめ

==

p.103 アジャイル設計
    細かい繰り返しを行っても、全体ができるとは限らない

貧弱な設計の兆候と原則

    q. 不必要な繰り返し -- マウスの使いすぎ ?
        a. Cut&Past の使いすぎということでは ?

p.107 7. アジャイル設計とは ?

    Software System 設計の主要なドキュメントは、Source Code そのもの
        ダイアグラム等は、設計そのものではなく設計 (の理解 ?) を補助するもの

    ソースコードそのものが設計

p.108 7.1 ソフトウェアの何が狂うのか ?
p.108 7.2 設計の悪臭

7 つの悪臭
    堅さ
    もろさ
    移植性のなさ
    扱いにくさ
    不必要な複雑さ
    不必要な繰り返し
    不透明さ

堅さ ( 表の依存性 : Compile Error によってチェック可能 )
    一つのモジュールへ変更が他のモジュールの変更に影響を及ぼす
    # 変更の量が問題

もろさ ( 裏の依存性 : Runtime Error )
    一つのモジュールへ変更が他のモジュールを壊す
    # 変更の数は少くても、無視できない..

    ?? モジュールと設計

移植性
    有用な部分が切離せない

扱い難くさ
    設計構造を維持しながらの変更ができない
    # プロジェクトの扱い難さ

不必要な複雑さ
    将来の変更を見越した準備がされている ( が、これは良くない.. )
        # 一度も利用しないコードが散財している
        ##   「設計」が、そのコードを抱えてしまう

不必要な繰り返し
    Cut&Past を行ってしまうとおきる
    # 抽象化を行う必要がある ( 理解、保守が容易.. )

不透明なモジュール
    解りにくいモジュール
        # 読み手の立場に立つ

    q. モジュール自身が変だと、設計のまずさが解るってこと ?
        a. そんな感じ

    q. Cut&Past ではなく Copy&Past では ?


p.111 7.2.1 何がソフトウェアを腐敗させるのか ?

仕様変更の繰り返しによって、腐敗する
    しかし、本来ならば、仕様の変更によって、設計が劣化するというのは、良くない
        (元々..)仕様は変更されるものなのだから

p.112 7.2.2 アジャイルチームは腐敗を許さない
    # 初期の設計を捨てる ?

==

次回 p.112 7.2 から

-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --


[ 戻る ]