fc2ブログ

初心者のためのC#プログラミング本格入門69 - メソッドを追加したら即テスト

 この記事は、初心者のためのC#プログラミング本格入門68の続きです。前回は、ユーザーストーリーを発展させ、テストとプログラムを発展させる技法について解説しました。今回は、新しいテストファーストの心得を解説します。
 前回サンプルプログラムのMultiAnalyzerに、RemoveErrorExpressionメソッドを追加しました。この様に新しいメソッドを追加した場合、すぐさま新しいテストを作成します。何故ならば、前回のテストはあくまでも「間違った式を指定した後、正しい式を分析する。」テストなので、他の状況を考慮していないからです。ErrorAndSuccessテストは、AnalyzeExpressionメソッドが主なテスト対象なので、このままでは安心できません。
 RemoveErrorExpressionメソッドを使用する状況(ストーリー)は、「複数の間違った式を指定した後に実行する」です。ErrorAndSuccessテストは1つの間違った式を直後に取り除いていましたが、複数の式の場合はチェックしていません。そこで、全ての間違った式が取り除けるのかテストします。

class MultiAnalyzerTest
{
    //全ての間違った式が削除できているかチェック。
    public void AllErrorExpressionDelete()
    {
        //間違った式と正しい式を複数指定
        this.target = new MultiAnalyzer();
        string inputValue1 = "1 + 2";
        this.target.AnalyzeExpression( inputValue1 );
        string errorValue1 = "0 $ 20";
        this.target.AnalyzeExpression( errorValue1 );
        string errorValue2 = "1 @ 2";
        this.target.AnalyzeExpression( errorValue2 );
        string inputValue2 = "1 * 2";
        this.target.AnalyzeExpression( inputValue2 );

        //全ての間違った式を取り除いているか?
        this.target.RemoveErrorExpression();
        if ( this.target.Success == false )
        {
            System.Console.WriteLine(
                "全ての間違った式を取り除けていません。" );
        }
    }
}

//新しいテストを追加
class TestProgram
{
    static void Main()
    {
        MultiAnalyzerTest multiTests = 
            new MultiAnalyzerTest();
        multiTests.AnalyzeSimpleExpression();
        multiTests.ErrorExpressionCheck();
        multiTests.ErrorAndSuccess();
        multiTests.AllErrorExpressionDelete(); //ここに追加
    }
}

テストを実行してみましょう。エラーが表示された筈です。原因を探ってみましょう。
 幸いマイクロソフト社が作った開発ソフトは、間違った所を探す機能が備わっています。先ずは、「//全ての間違った式を取り除いているか?」のコメントの下にあるプログラム「this.target.RemoveErrorExpression();」がある場所にカーソルを持って行って下さい。次に、「デバッグ」メニューの「ブレークポイントの設定/解除」を選択して下さい。すると、画面左に赤丸がついてプログラムの色も変わります。これで準備万端です。「デバッグ」メニューの「デバッグ開始」を選択して下さい。プログラムが実行された後、黄色い矢印が表示され、先ほど設定したプログラムでストップされます。この状態でF11ボタンを押すと、プログラムが1行ずつ実行されます。
 さて、ストップしてどうするのかと言いますと、この状態で表示できる便利なウィンドウがあります。デバッグ→ウィンドウ→ローカルを順番に選びクリックすると、ローカルウィンドウが表示されます。ローカルウィンドウは、オブジェクトの状態が確認できます。この画面を見て、RemoveErrorExpressionメソッドの動きを観察しましょう。すると、間違った式を1つしか取り除いていない事が分かると思います。実際に確認してみて下さい。
 複数の間違った式を取り除くにはどうしたらよいのでしょうか?一度考えて下さい。考え方としては、「1つの式を取り除けるプログラムを、全ての間違った式を取り除くまでループすればよい。」です。この考え方を元にすれば分かると思います。
 模範解答を発表します。今まで学習してきた事を合わすと次の様になります。

//間違った式を取り除く
public void RemoveErrorExpression()
{
    //間違った式を1つずつ取り除く
    bool loopFlag = true;
    while ( loopFlag == true )
    {
        //間違った式を1つ取り除く
        int index = -1;
        for ( int i = 0; i < this.analyzers.Count; ++i )
        {
            if ( this.analyzers[ i ].Success == false )
            {
                this.analyzers.RemoveAt( i );
                index = i;
                break;
            }
        }
        //間違った式が1つも見つからない時処理終了
        if ( index == -1 )
        {
            loopFlag = false;
        }
    }
}

これで複数の間違った式を取り除けます。テストを再度実行しましょう。すると・・・またエラーが表示されます。それは何故でしょうか?
 答えは「Successプロパティの値が変更されていないから」です。Successプロパティの値を変更するメソッドは、ValidityExpressionメソッドなので最後に呼び出しておきましょう。

//間違った式を取り除く
public void RemoveErrorExpression()
{
    //先ほど書いたので省略
    
    //改めて式全体を検証
    this.ValidityExpression();
}

やったね♪今度こそテストが成功します。
 今回解説したように、新しいメソッドを追加したら直ぐに、新しいテストを作ってチェックします。また、テストをパスする最低限のプログラムしか書いていない事に注意して下さい。テストファーストのプログラミングでは、基本的に余計なプログラムを書きません。何故ならば、あれこれ考えてプログラムを作ろうとすると、思考が乱れてそこにバグが生まれるからです。それに余分なプログラムは贅肉です。プログラムの贅肉も極力無い方がいいです。特に初心者の方は慣れていないので混乱しやすいと思います。贅肉を作るためにプログラミングが進まないなんて損だと思いませんか?プロと初心者の違いがそこにあります。
 ちょっとプログラミングに慣れてくると、あれこれ考えがちですが、プロは余計な動きをしません。黙々とテストを追加して、そのテストをパスするプログラムを作るだけです。この様に書くと「楽しくないんじゃないか?」という疑問が湧くかと思います。ですが、それはむしろ逆です。テストファーストで開発すると、進行状況が見えてプログラミングがより一層楽しくなります。誰しも目的地が分からないよりも、目的地に向かって進んでクリアする方が楽しいと思います。
 「楽しくプログラミングして楽しく学ぶ」それが私のポリシーです。プログラミング上達のコツは、プログラミングをどれだけ楽しいものに出来るかだと言っても過言ではありません。楽しくなければ長続きしませんから上達しません。学習を耐えて努力をするものと考えず、楽しんだ結果上達するものだと考えて下さい。一緒にプログラミングを楽しみましょう。次回はさらなるテクニックを解説します。お楽しみに。
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

真正性をつつく5 - アクセスポイントを決定しよう

 この記事は、真正性をつつく4の続きです。前回は、アクセス経路の特定について解説しました。今回は、アクセスポイントの決定について解説します。
 アクセス経路を考えると、非常に多くの組み合わせがある事に気付くと思います。ですが、真正性は経路の組み合わせで判定しません。この点に注意が必要です。分かり難いと思いますので例を挙げます。
 自称・営業部長山田太郎氏が受付で「俺は社長の許可を得てここにきている。早く通せ!」と言いだしたとします。この場合、受付嬢はそのまま通すべきなのでしょうか?答えは否です。たとえそれが本当であったとしても、誰かが認証しているのだから大丈夫だと考えるのは早計です。何故ならば、嘘の場合は真正性をチェックしていない状態になってしまうからです。この場合、受付嬢は理由に関わらず真正性をチェックするべきです。
 では、どこで真正性をチェックするのでしょうか?それを考えるのが、今回解説するアクセスポイントの決定作業です。アクセス経路には複数の組み合わせが考えられますが、認証をするオブジェクトは自ずと決まります。例えば、ガードマン、受付嬢、指紋認証端末などです。これらの認証オブジェクトを、どの様なアクセス経路を通ろうとも真正性をチェックできるように配置します。この配置した場所がアクセスポイントとなります。アクセスポイントは多ければ多いほど真正性が高くなりますが、それに比例して真正性をチェックされる側のストレスが増加します。また、アクセスポイントの増加に伴いコストも増加します。従って、保護対象となる情報資産の価値に見合ったアクセスポイントを設定するべきです。
 アクセスポイントを設定したら、アクセス経路と照らし合わして、真正性のチェック漏れがないか慎重に確認しましょう。クラッカーは一番弱い場所を選びます。真正性を逃れるルートがあるのならば、絶対にそこからクラック(情報資産の破壊/窃盗などの犯罪行為)されると考えましょう。クラッカーは自分よりも賢いと考えて、セキュリティ対策を練りましょう。

テーマ : プログラミング
ジャンル : コンピュータ

初心者のためのC#プログラミング本格入門68 - ユーザーストーリーとプログラムを発展させよう

 この記事は、初心者のためのC#プログラミング本格入門67の続きです。前回は、ユーザーストーリーに沿ったテストを行い、複数のプロパティとメソッドから生じる論理的なエラーを検出するテスト技法を解説しました。今回は、エラーを如何にして修正していくのかについて解説します。
 前回サンプルプログラムに、「誤った式を解析後、正しい式をエラーとみなしてしまう。」という問題がある事が分かりました。その問題を一緒に解決していきましょう。
 先ず考えるべき事は問題の発生源です。解析処理の問題を発見するには、やはりAnalyzeExpressionメソッドのプログラムを見る必要があります。早速見てみましょう。

public void AnalyzeExpression( string inputValue )
{
    //式を分割
    DivisionAnalyzer( inputValue );

    //式の有効性をチェック
    ValidityExpression();
}

ここで今回解決する問題を思い返すと、「式の有効性をチェック」が重要です。どの様に式の有効性をチェックしているのかが分かれば問題を解決できます。

private void ValidityExpression()
{
    foreach ( Analyzer obj in this.analyzers )
    {
        if ( obj.Success == false )
        {
            this.success = false;
            return;
        }
    }
    this.success = true;
}

ValidityExpressionメソッドのプログラムを読めば、「全ての式が有効である場合のみ有効な式」だと判定している事が分かります。複数の式を計算するためには、個々の式が正しくなければなりません。従って、ValidityExpressionメソッド単体からしてみれば、これは妥当なプログラムだと言えます。しかしながら、今のままでは一つの誤りだけで全てが台無しになってしまいます。どうすればいいのでしょうか?読者の皆様は、一度考えてみて下さい。
 考えましたか?この問題の解決方法はいくつか方法が考えられます。ですが、注意が必要です。初心者の人は、色々考え過ぎてしまい、既存のプログラムを変更してしまう傾向がありますが、無闇に仕様を変更しては駄目です。何故ならば、問題が起こる都度、プログラムを大幅に変えてしまうと、新しい問題が発生する確率が高くなるからです。また、実務で仕様を頻繁に変更すると、集団作業では混乱が生じます。
 ではどうすればいいのかと言いますと、最低限の変更を行うのがベストです。今回の場合、一番簡単かつ自然な解決法は「誤った式を取り除く」事です。プログラムを使う人は大概、誤った式を入力すれば修正しようと考えます。ですから、これは理にかなっていると言えます。
 解決方法が決まったので、ユーザーストーリーに沿ったテストにプログラムを追加します。

//間違った式を指定した後、正しい式を分析する。
public void ErrorAndSuccess()
{
    //間違った式を指定
    string errorValue = "1 @ 2";
    this.target = new MultiAnalyzer();
    this.target.AnalyzeExpression( errorValue );
    if ( target.Success == true )
    {
        System.Console.WriteLine(
            "誤った式を解析できていません。" ); 
    }

    //間違った式を取り除く
    this.target.RemoveErrorExpression();

    //正しい式を受け入れるか?
    string value = "1 + 2";
    this.target.AnalyzeExpression( value );
    if ( target.Success == false )
    {
        System.Console.WriteLine(
           "誤った式後に指定した正しい式を解析できていません。" ); 
    }
}

「間違った式を取り除く」動作をつけて加えています。現段階では、RemoveErrorExpressionメソッドを定義していませんので文法エラーになります。この様なとき便利な機能が開発ソフトに備わっています。プログラム下に赤い波線が出た状態で、マウスを移動させると「メソッドスタブを作るオプション」が表示されます。それをクリックしたら、ひとまずメソッドが定義されます。非常に便利なので是非使ってみて下さい。
 テストが完成したので実行すると・・・エラーが発生した旨が表示されます。この原因は、まだRemoveErrorExpressionメソッド内のプログラムを作っていないからです。テストが実行できる事を確認したので、RemoveErrorExpressionメソッドのプログラムを作りましょう。プログラムの内容は、「間違った式を取り除く」です。RemoveAtメソッドを使えば作れます。一度考えてみて下さい。
 それでは、模範解答を発表します。今まで学習した文法を使えば以下のようになります。

//間違った式を取り除く
//internalからpublicに変えるのを忘れずに
public void RemoveErrorExpression()
{
    for ( int i = 0; i < this.analyzers.Count; ++i )
    {
        if ( this.analyzers[ i ].Success == false )
        {
            this.analyzers.RemoveAt( i );
        }
    }
}

簡単ですよね?forループとif分を使えば、このプログラムは作れます。これで、ErrorAndSuccessテストが成功します。
 この様に、ユーザーストーリーに沿ってテストとプログラムを発展させていけば、プログラミングが簡単になります。初心者がプログラミングを難しく感じる原因は「難しく考えるから」です。難しい事を考えれば、誰でも難しく感じてしまいます。ならば、初めから難しく考えなければいいのです。無理に背伸びせず、一歩々着実にプログラムを発展させていきましょう。この方法ならば、初心者でも無理なく実用的なプログラミングの学習が出来ます。

テーマ : プログラミング
ジャンル : コンピュータ

実践的オブジェクト指向設計入門8

 この記事は、実践的オブジェクト指向設計入門7の続きです。前回は、境界条件の扱いについて解説しました。今回は、トレードオフ順位の設定を解説します。
 システムの設計にはトレードオフがつきものです。例えば、メモリなどのハードウェアにお金をかければ、より速いシステムが出来上がりますが、その分費用が高くつきます。他にも、冗長な構造にして耐久性を高める、セキュリティレベルを上げる、信頼性を高くする・・・など色々な場面で設計者は選択をしなくてはなりません。
 それらの選択を基準もなしに個別に考え決定してしまうと、偶然の産物が出来上がってしまいます。従って、何らかの基準が必要となります。オブジェクト指向方法論OMTは、その選択基準としてトレードオフの優先順位の設定を挙げています。
 トレードオフ優先順の決定とは、1・移植性、2・効率性・・・というふうに優先順位を設定するものです。この優先順位は、「効率性の優先順位は全体の32.2%」という具合に厳密に数値化するものではなく、ある種漫然としたものですが、大変有効なものです。具体的には、複数の設計者が議論する時間を減らせますし、特定の設計者に対する依存度が減ります。他にも色々な利点があります。
 地味な作業ですが、集団作業ではこういった作業が明暗を分けます。

テーマ : ソフトウェア開発
ジャンル : コンピュータ

真正性をつつく4 - アクセス経路の特定をしよう

 この記事は、真正性をつつく3の続きです。前回は、デジタルの認証技術について解説しました。今回は、次の手順であるアクセス経路の特定について解説します。
 おさらいします。真正性を保証するシステムを設計するには、対象となるオブジェクトを明確化し、認証技術の決定を行います。次にするべき手順は、アクセス経路の特定です。真正性を保証するオブジェクトを定め、対象に使用する認証技術を決定しても、アクセス経路を特定しない内には役に立ちません。何故ならば、人の認証とデジタルなオブジェクトの認証は違うように、対象となるオブジェクトによって認証方法が異なるからです。ちょっと分かり難いので、毎度おなじみの例を使用して解説します。
 営業部長山田太郎(仮名)が、直接会社を訪問する事もあれば、会社のシステムへアクセスしてくる場合もあります。この2つの状況を考えると、受付嬢などの人間が対応する場合と、サーバーが対処する場合がある事が分かります。人間と機械の対応は自ずと違いますので、アクセス経路ごとに対象(プロセスなど)と認証手段を考える必要があります。また、会社訪問の場合も、掃除婦の方が話しかけられる場合もあります。さらには、受付嬢の場合も契約状況(派遣、正社員、アルバイト、パート)により権限と責任が違いますので、取りうる認証手段が異なります。こうした状況も考えなくては、真正性を保証するシステムを提供できません。
 ここで一つの疑問が浮かぶ人がいるかと思います。「何故、アクセス経路の特定を先に考えないのか」。その疑問については、セキュリティレベルをあげるためです。認証技術は日々進歩しています。過去につくったシステムの認証技術をそのまま使うのではなく、現在の認証技術を検討しなくてはなりません。先にアクセス経路を決めてしまうと、先入観により「前に採用した認証技術をそのまま使用しよう」という流れが起きてしまいます。システムを作る人の中にも保守的な人が多く、既存の知識の範囲だけで物事を判断してしまう人が沢山います。そうした人達がシステムの選択肢を減らしてしまうと、既存の技術の弱点を知り尽くしたクラッカーの餌食になります。セキュリティを考慮したシステム開発とは、ただ単にセキュリティ技術を採用する事ではなく、開発工程で起こる人間の盲点にも対処するという事なのです。
 アクセス経路は、物理的な物と論理的な物(システムと非システム)の2種類あります。物理的なアクセス経路は、会社の構造に対する経路(情報システム外の経路)です。論理的なアクセス経路は、システムにログインすると言った非物理的な情報システム内の経路の事です。直感的に分かりやすいように、論理的/物理的と表現しましたが、物理的アクセス経路と言っても、建物内だけのルートではなく、電話でアクセスしてくるなどといった経路もあり得るので注意しましょう。また、論理的アクセス(情報システムでのアクセス)内にも、ネットワーク外からアクセスされる場合と、ネットワーク内からアクセスされる場合などといった複数のパターンがありえます。こうした細かな事まで考える事がセキュリティ対策では必要です。
 

テーマ : ソフトウェア開発
ジャンル : コンピュータ

初心者のためのC#プログラミング本格入門67 - ユーザーストーリーもチェック!

 この記事は、初心者のためのC#プログラミング本格入門66の続きです。前回は、最低限用意するべきテストデータについて解説しました。今回は、より高度なテストを解説します。
 今のところエラー処理のテストと成功時のテストの2つを解説しています。これでプログラミングがサクサク進むかというと、そうでもありません。今は最低限のテストしか行っていないので、誤りが無い事をチェックしているだけです。もっと役に立つテストを行いたいと思うのが人情です。
 もちろん、そうしたテストを行う方法はあります。それが、ユーザーストーリーに沿ったテストを行う方法です。ユーザーストーリーを簡潔に言うと、オブジェクトの利用者が取る行為(ストーリー)です。つまり、貴方が作ったオブジェクトがどの様に使われるのかを考えます。
 こういうものは文章では分かり難いので実際に行ってみましょう。

class MultiAnalyzerTest
{
    //間違った式を指定した後、正しい式を分析する。
    public void ErrorAndSuccess()
    {
        //間違った式を指定
        string errorValue = "1 @ 2";
        this.target = new MultiAnalyzer();
        this.target.AnalyzeExpression( errorValue );
        if ( target.Success == true )
        {
            System.Console.WriteLine(
                "誤った式を解析できていません。" ); 
        }

        //正しい式を受け入れるか?
        string value = "1 + 2";
        this.target.AnalyzeExpression( value );
        if ( target.Success == false )
        {
            System.Console.WriteLine(
               "誤った式後に指定した正しい式を解析できていません。" ); 
        }
    }
    
    //他のプログラムは省略・・・
}

//作ったテストを呼び出す事を忘れないように
class TestProgram
{
    static void Main()
    {
        MultiAnalyzerTest multiTests = 
            new MultiAnalyzerTest();
        multiTests.AnalyzeSimpleExpression();
        multiTests.ErrorExpressionCheck();
        multiTests.ErrorAndSuccess();
    }
}

このテストは、利用者が間違った式を指定した後、正しい式を入力する場面(ストーリー)を想定しています。人間はだれしも間入力ミスをします。そして、ミスをしたら正しい式を入力しなおす事も考えられます。さて、このテストはどうなるでしょうか?
 実行すると分かると確認できますが、エラーメッセージが表示されます。現在のMultiAnalyzerオブジェクトは、一度間違ったら二度と式を正しいとみなしません。これでは不便ではないでしょうか?ユーザーストーリーに沿ったテストは、こうしたオブジェクトの扱いやすさを考えるきっかけを与えてくれます。
 私が先にテストを行う(テストファースト)とプログラミングが素早くできると言ったのはこういうテストがあるからです。ユーザーストーリーに沿ったテストを行わないと、オブジェクトがどの様に使用されるのか判明せず、扱いにくいオブジェクトが出来上がってしまいます。また、複数のメソッドやプロパティを実行した結果が分からないので、複数の処理から生まれるエラーを見過ごしてしまいます
 以上のようにユーザーストーリーに沿ったテストを行うと、自分の考えを検証できるようになるので悩む時間が減り、プログラミングがサクサク進むようになります。作りたいプログラムが思い浮かんだらテストを先ず作り、そのテストに合格するプログラムを作りましょう。その流れを途切れることなく行えば、ストレスなしに素早くプログラミングを行えます。

テーマ : プログラミング
ジャンル : コンピュータ

真正性をつつく3 - デジタルの認証技術もあるよ

 この記事は、真正性をつつく2の続きです。前回は、識別子と認証方法について解説しました。今回はその続きで、デジタル系の認証技術について解説します。
 前回は主に対人的な認証技術(本人認証)でした。しかしながら、オブジェクトは常に人だとは限りません。PCのプロセスなどと言ったデジタルなものもありえます。例えば、営業部長山田太郎氏が、会社のシステムにログインしてきた場合、デジタル系の認証技術を使用する必要があります。
 デジタル系の認証技術も発想としては同じなのですが、デジタルなオブジェクトが相手なので詳細が違います。具体的には、時間認証・デジタル署名・認証サーバーを用いて同時の認証をする方式などがあります。これらを順に解説していきます。
 時間認証は、その名の通り時間を用いた認証方式です。代表例がワンタイムパスワードです。パスワードをネットワーク越しに送ると、傍聴されてしまう危険性が常にあります。一度盗聴されてしまうと、なりすましが様に行われてしまいますので、これはなんとしても避けなくてはなりません。そこで、パスワードをある一定の時間だけ有効にする方式が考えだされました。
 ワンタイムパスワードの方式は色々ありますが、主な方式は時刻同期方式チャレンジレスポンス方式の2つです。時刻同期方式は簡単に言うと、クライアントがトークンと呼ばれるワンタイムパスワードを生成する為の装置を使用して、入力された暗号と時刻を元に、その都度パスワードを生成して使用する方式です。そして、チャレンジレスポンス形式は、認証サーバーとクライアントの双方が、ユーザIDとそれに対応した各種情報(シーケンス番号、シード、前回使用したパスワード)をやり取りして認証する方式です。一見両方式とも完璧に見えるでしょうが、クライアントから送る情報が盗聴されると破られる恐れがあるので注意が必要です。
 デジタル認証方式は電子署名を使用して認証する方式です。この方式は、公開鍵暗号方式を利用します。具体的には、送信者は送信データをハッシュ関数で圧縮し、送信者だけが持つ秘密鍵で暗号化し、データと署名されたデータを相手へと送ります。受信者は、受信データをハッシュ関数で圧縮しダイジェストメッセージを作ります。それと同時に、署名入りデータを送信者の公開鍵で複合します。その両者が一致すれば、ある特定の送信者が送った正しいデータだと看做せます。
 デジタル認証方式は、信頼できる第三者の存在が前提となります。何故ならば、公開鍵の所有者が保障されなければ、悪意を持った偽名を名乗る人物かもしれないからです。犯罪者が一定期間の犯罪をもくろみ、鍵を公開しているかもしれません。また、認証を行う機関がクラッキングされたらお終いです。従って、認証局が信頼できなければ意味がなくなってしまうのです。
 それに加えて、鍵をどうやって配送するのかという問題があります。鍵そのものが盗まれれば、容易に他人になり済ます事が出来てしまいます。鍵をどの様にして送るのか、また認証局がどの様にして本人を特定し、その身分を保障するのか、認証局の信頼性をどのように判定するのかといった色々な課題があります。完璧な方式は存在しないのです。
 そういった既存の認証方式の問題を解決するべく、自前で認証サーバーを用意し、独自の認証方式を提供することもあり得ます。ただし、その独自の方式が他の方式に比べて安全だとは必ずしも言い切れません。独自認証だと言っても、クラッカーはインターネットに流れるデータを分析したり、ソーシャルエンジニアリングのテクニックを使用したりして、認証方式を特定する事が可能です。認証方式が分かれば、悪意ある人は必ずクラックする方法を思いつきます。つまり、どの様な認証方式を使用してもいつかクラックされると思った方が賢明です。
 多要素認証を採用し、定期的に認証方法を見直しましょう。

テーマ : ソフトウェア開発
ジャンル : コンピュータ

実践的オブジェクト指向設計入門7

 この記事は、実践的オブジェクト指向設計入門6の続きです。前回は、大域資源の扱いについて解説しました。今回は、境界条件の扱いについて解説します。
 システムの状態を大別すると、初期化・終了・異常・安定の4つあります。安定状態は一番よく考えられているのですが、他の状態、特に障害におけるシステムについてよく考えなくてはなりません。障害を想定外の一言で済ませられません。これから、OMTで提唱されている事を解説します。
 初期化状態は、システムに於いて不安定な状態です。初期化状態の間はサブシステムも動作しておらず、システムとしての機能が不完全なので、順番や並列性についてよく考えなくては、思わぬトラブルを生みます。ソフトウェアと違いサブシステムは、違うハードウェア上で動作している事が多いです。従って、並列的にサブシステムを立ち上げる可能性が高くなります。並列的な起動をサポートしない場合、どの様な手順でシステムを立ち上げるのかを熟慮し、それを説明書などの形でユーザーに知らせなくてはなりません。
 終了状態は処理の大半がオブジェクトの破棄なので、初期化状態よりも簡単です。しかしながら、ログと終了を知らせる方法について熟慮する必要があります。大概のシステムは、サブシステムの連携で成り立っていますから、サブシステムが予告もなしに終了しては正常な処理を出来ません。また、異常時に備えてログをちゃんと取っておかないと、システムの復旧が出来なくなります。
 異常時は特に熟慮しなくてはなりません。異常状態になる原因の多くは、システムの思わぬ扱い方や災害に起因します。従って、普通に設計をしていれば「想定外」になってしまいます。人災、自然災害、ヒューマンエラーなど、あらゆる可能性を視野に入れてシステムを設計しなくてはなりません。ですが現実的には、全ての災害に対処するのは不可能です。その想定外の状況も想定し、システム異常に対してどのように対処するのか、そしてどの様なデータが役に立つのかを考え、システム異常時の対策を考えます。
 以上、オブジェクト指向方法論OMTに自分の考えを付け加えたものを簡潔に解説しました。簡潔に解説していますが、個々の状態は奥深いものです。この4つの状態に拘らず、システムのあらゆる状況を想定し、頑強で使いやすいシステムを設計を目指して下さい。ただし、設計中毒には十分に注意して下さい。設計に熱中し過ぎて、実装の時間が足りなくなる事例もあります。私の経験から言いますと、全てを設計できると思わず、現状でベストを尽くすという謙虚な姿勢で臨めば、設計中毒にならなくて済みます。

テーマ : ソフトウェア開発
ジャンル : コンピュータ

初心者のためのC#プログラミング本格入門66 - 必要なテストデータを知ろう

 この記事は、初心者のためのC#プログラミング本格入門65の続きです。前回は、プログラミングにおける数値の扱いについて解説しました。今回は、最低限用意するべきテストデータについて解説します。
 数値の様な膨大な値があるテストデータを全て用意して、テストを実施するのは実用的な観点から言って好ましくありません。しかしながら、1と2の様なありきたりな値をテストデータとして用意しても十分にエラーを発見できません。そこで、特徴のあるデータを使用します。
 ここで言う特徴とは、最小値と最大値の事です。プログラミングのエラーはその多くが、最大値と最小値の処理を間違う事により発生します。それに加えて、前後と中央でも間違う事が多いので、それらの値も忘れずにテストデータにします。この事を踏まえて、実際にテストを作ってみましょう。

//簡単な式が指定された場合の解析処理をテストする
public void AnalyzeSimpleExpression()
{
    //テストデータを準備
    char[] signs = new char[] { '+', '-', '*', '/', '%' };
    int[] values = new int[] 
    { 
        int.MinValue, int.MinValue + 1, int.MinValue / 2, 
        0, int.MaxValue / 2, int.MaxValue - 1, int.MaxValue
    };

    //全演算子と主要な数値の組み合わせをチェック
    foreach ( char sign in signs )
    {
        foreach ( int v1 in values )
        {
            foreach ( int v2 in values ) 
            {
                this.AnalyzeTest( sign + " " + v1 + " " + v2 );
                this.AnalyzeTest( " " + v1 + " " + sign + " " + v2 );
                this.AnalyzeTest( " " + v1 + " " + v2 + " " + sign );
            }
        }    
    }
}

以上の様に対象となるオブジェクトが取りうる範囲の境界となる値を使用すると、多くのエラーを見つけ出してくれるテストになります。
 初心者の方はまだピンと来ないかもしれませんが、プログラミングで発生するエラーの多くは簡単なものです。何故ならば、
//本当は0を含むつもりのプログラム
//実際は0を含んでいない
if x > 0 then ...
の様な、ちょっとしたことでエラーとなるからです。もちろん、プログラムの仕様が間違っているなどといった、より発見が難しいエラーもありますが、どんな人でもケアレスミスをおかします。特に実務では、数十万行のプログラムなんてざらにありますから、誰もが間違う可能性があります。簡単なエラーは発見できれば直ぐに修正できますし、実務では自分以外の人の事も考えなくてはならないので、こんな単純なチェックをするテストプログラムでも大切なのです。
 今回解説した事はほんの些細な事です。ですが、知っているのと知らないのとでは天と地の差が出ます。ぜひ覚えて、快適なプログラミングライフを満喫して下さい。

テーマ : プログラミング
ジャンル : コンピュータ

F#とアクセス制御

 先に断っておきますが、この文章はただの感想です。F#は非常に優れた好きな言語です。ただし、他の言語同様思わぬ仕様があります。それはアクセス制御です。F#は今のところprotectedを指定できませんし、抽象メンバーにも指定できません。アクセス制御は、オブジェクトをデザインするのに当たって重要な要素なので改善して欲しいです。F#が好きなだけに非常に残念です。
 いわゆる仮想メソッドを外部に公開したくない場合があるので、もしアクセス制御指定子を指定出来たら、F#本来の強力さもあって非常に表現力がアップします。もちろん、protectedも指定したいな。やはり、どんな言語でも弱点?がありますね。

テーマ : プログラミング
ジャンル : コンピュータ

プロフィール

インドリ

Author:インドリ
みなさん、はじめまして、
コンニチハ。

ボクは、無限の夢(infinity dream)を持つネタ好きな虹色の鳥インドリ(in dre)です。
色々な情報処理技術を啄ばむから楽しみにしてね。

http://twitter.com/indori
は別人による嫌がらせ行為です。
私とは関係ないので注意して下さい。
次はなりすましブログなどをするかもしれませんが、ここ以外でブログをするつもりがないので、ここ以外にインドリのブログがあったとしても無視してください。


何度言っても分からない人がいるので、ここにコメント欄へ書き込むときの注意事項を書きます。


一、社会人としてのマナーをわきまえましょう。
一、妄想に基づく書き込みを止めてください。
一、暴言の類は書かないで下さい。
一、某誹謗中傷サイトの書き込みは彼らの妄想に基づく書き込みですから無視して、ここへ書き込まないで下さい。
一、コメント書く前に他のコメントよく読んでから行って下さい。
一、言いがかかり等の行為を禁止します。
一、その他常識的に考えて迷惑なコメントはしないで下さい。


以上のルールを守れない人のコメントは削除します。



利用上の注意
ここに紹介してある文章およびプログラムコードは正確であるように心がけておりますが、内容を保証するものではありません。当サイトの内容によって生じた損害については、一切の責任を負いませんので御了承ください。


執筆したCodeZineの記事


【VB.NETで仮想CPUを作ろう】

  1. VB.NETで仮想CPUを作ろう
  2. レジスタの実装
  3. 仮想CPUのGUI化
  4. テストドライバの改良
  5. CPUの基礎動作の実装
  6. MOV命令の実装
  7. ADD命令実装
  8. SUB命令実装
  9. INC命令&DEC命令の実装と命令長
  10. MLU命令の実装とModR/Mについて
  11. DIV命令の実装とイベント設計について
  12. 機械語駆動式 関数電卓を作ろう!
  13. 機械語駆動式 関数電卓を作ろう! 解答編(前半)
  14. 機械語駆動式 関数電卓を作ろう! 解答編(後半)


【仮想ネットワーク実装でTCP/IPを学ぼう】
  1. TCP/IPの基礎と勘所
  2. ネットワークアクセス層の勘所
  3. インターネット層の勘所
  4. トランスポート層の勘所
  5. アプリケーション層の勘所
  6. セキュリティの基礎と仮想ネットワークの仕様
  7. GDI+と独自プロトコルの定義



【並列化】
インテル Parallel Studioを使って並列化プログラミングを試してみた
並列プログラミングの効率的なデバッグを実現する「Parallel Inspector」


【TBBシリーズ】
  1. インテル スレッディング・ビルディング・ブロックの概要
  2. インテルTBBから学ぶループの並列化
  3. スレッドセーフとインテルTBBのコンテナ
  4. インテルTBBのスレッドクラス


【OpenMPシリーズ】
  1. OpenMPの基礎構文
  2. OpenMPの実行時ライブラリと並列ループ
  3. OpenMPのメモリモデルとfork- joinモデル

最近の記事
最近のコメント
月別アーカイブ
カテゴリ
Ada (9)
COBOL (5)
C (9)
C++ (11)
C# (370)
D (25)
Java (8)
Perl (1)
Ruby (14)
PHP (2)
Boo (2)
Cobra (2)
LISP (6)
F# (33)
HTML (0)
XHTML (0)
CSS (0)
XML (0)
XSLT (0)
Scala (4)
WPF (0)
WF (2)
WCF (0)
LINQ (4)
MONO (5)
Linux (0)
MySQL (0)
ブログ内検索
リンク
最近のトラックバック
RSSフィード
ブロとも申請フォーム

この人とブロともになる

QRコード
FC2カウンター