デザインパターン入門

Observerパターン

状態の変化を通知する

どんな場合に使うのか

  • 状態の変化を,関係のある他のオブジェクトにも通知することによって,状態に矛盾が生じないように,同期を取ることが目的です.
  • Observerという言葉の本来の意味は「観察者」ですが,実際にはObserver役は能動的に「観察」するのではなく,Subject役から「通知」されるのを受動的に待っていることになります
  • Observer役の行為がSubject役に影響を与える場合,メソッド呼び出しが永遠に続く可能性があるので,注意深く設計する.具体的には,Observer役に「現在Subject役から通知されているかどうか」を表すフラグ変数を1つもたせる.

クラス図

サンプルプログラム

// 01_Observer.cs
namespace chap17 {
  public interface Observer {
    void update(NumberGenerator generator);
  }
}

// 02_NumberGenerator.cs
using System.Collections;

namespace chap17 {
  public abstract class NumberGenerator {
    private ArrayList observers = new ArrayList();
    public void addObserver(Observer observer) {
      observers.Add(observer);
    }
    public void deleteObserver(Observer observer) {
      observers.Remove(observer);
    }
    public void notifyObservers() {
      foreach (object ob in observers) {
        ((Observer)ob).update(this);
      }
    }
    public abstract int getNumber();
    public abstract void execute();
  }
}

// 03_RandomNumberGenerator.cs
namespace chap17 {
  public class RandomNumberGenerator : NumberGenerator {
    private System.Random random = new System.Random();
    private int number;
    public override int getNumber() {
      return number;
    }
    public override void execute() {
      for (int i = 0; i < 20; i++) {
        number = random.Next(0, 50);
        notifyObservers();
      }
    }
  }
}

// 04_DigitObserver.cs
using System;

namespace chap17 {
  public class DigitObserver : Observer {
    public void update(NumberGenerator generator) {
      Console.WriteLine("DigitObserver:" + generator.getNumber());
      try {
        System.Threading.Thread.Sleep(100);
      } catch (Exception) {
      }
    }
  }
}



// 05_GraphObserver.cs
using System;

namespace chap17 {
  public class GraphObserver : Observer {
    public void update(NumberGenerator generator) {
      Console.WriteLine("GraphObserver:");
      int count = generator.getNumber();
      for (int i = 0; i < count; i++) {
        Console.Write("*");
      }
      Console.WriteLine("");
      try {
        System.Threading.Thread.Sleep(100);
      } catch (Exception) {
      }
    }
  }
}

// 06_Program.cs
using System;

namespace chap17 {
  class Program {
    static void Main(string[] args) {
      NumberGenerator generator = new RandomNumberGenerator();
      Observer ob1 = new DigitObserver();
      Observer ob2 = new GraphObserver();
      generator.addObserver(ob1);
      generator.addObserver(ob2);
      generator.execute();
      Console.Read();
    }
  }
}
デザインパターン入門

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

管理人/副管理人のみ編集できます