« [C#]デザインパターン再考 Chain of Responsibility Pattern | トップページ | 日本は今後20年以内に戦争をするだろうな »

[C#]デザインパターン再考 Strategy Pattern(デリゲートタイプ)

※ ここに書かれていることは、間違っているかもしれないので、ご注意ください

■ なぜ、このパターンを使うのか?

 switchやif - elseで処理の切り替え(アルゴリズムの変更)を記述すると・・・

1.どの処理を適用するかを示す引数や変数が必要になる

  • ほとんどの場合、名前の付け方がいい加減で、コードが読み難い
  • 数が多くなると、さらに読みづらくなる

2.毎回、上記の引数や変数の判定が必要になる

  • 同じ引数や変数なのに、同じ結果を得るための判定処理を行うのはムダだ
  • ひとつひとつの処理時間は短いが、回数が増えると無視できない時がある

 私の少ない経験から思うに、繰り返し処理されるコードで毎回判定を行っていると、処理時間がもったいないことがある。特に、画像表示を行う場合は。

■ 何をしているのか?

 簡単に言うと、処理を選択する箇所と、それを実行する箇所を分けているのだ。

 switchやif - elseで処理を切り替えるコードでは、条件式で処理の選択を記述し、それに続いて実行する箇所を記述している。したがって、処理を適用したい場合は毎回、判定を行うことになる。何度も同じ判定を繰り返すのはもったいない。同じ処理を行う状態なら、判定は状態の遷移時に行えばいいだけだ。

 そう、これは状態遷移で使うパターンだ。(といって、いいと思うのだけれど)

 画像表示のツールを作った際には、表示の更新/停止の切り替えに使った。カメラから画像データを取得し、処理して、表示するという流れを繰り返すのだが、この流れを停止したい場合もある。その2つの状態の切り替えに使用した。

■ デメリットは?

 引数で状態を指定されて、それに応じて行う処理が簡単であって、処理時間が少々かかっても問題ない場合は、このパターンを適用しなくていいと思う。適用した方が煩雑になるからだ。

 処理時間の短さが重要視される場合や、処理のコードが長くなる場合、このパターンを適用してもいいと思う。

 状態の指定をフィールドで行う(フラグってヤツ)場合も、このパターンを使っていいと思う。フィールドを記述するのと同じ手間で書けるからだ。

■ コード例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace StrategyPatternByDelegate
{
    class Program
    {
        static void Main(string[] args)
        {
            var program = new Program();
            program.StartImageView();
            program.StartUserInput();
        }

        private static Action ShowImage = () => Console.WriteLine("Show a new image.");

        private static Action StopImage = () => Console.WriteLine("Now stopping ...");

        private Action NowAction = StopImage;

        private Thread thread = null;

        private void StartImageView()
        {
            this.thread = new Thread(() =>
            {
                foreach (var i in Enumerable.Range(0, 100))
                {
                    this.NowAction();
                    Thread.Sleep(100);
                }
            });
            thread.Start();
        }

        private void SelectAction(ConsoleKeyInfo keyInfo)
        {
            if (keyInfo.Key == ConsoleKey.Enter)
                this.NowAction = (this.NowAction == ShowImage) ? StopImage : ShowImage;
        }

        private void StartUserInput()
        {
            if (this.thread == null) return;

            while (thread.IsAlive)
                this.SelectAction(Console.ReadKey());
        }
    }
}

以上

« [C#]デザインパターン再考 Chain of Responsibility Pattern | トップページ | 日本は今後20年以内に戦争をするだろうな »

C# メモ書き」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: [C#]デザインパターン再考 Strategy Pattern(デリゲートタイプ):

« [C#]デザインパターン再考 Chain of Responsibility Pattern | トップページ | 日本は今後20年以内に戦争をするだろうな »

2019年10月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
無料ブログはココログ