こんにちは!
なかむぅです。
ずっとコピペプログラマーだった私は
って感じだったので、「オブジェクト指向」を学ぶために「Java言語で学ぶデザインパターン入門第3版」を購入しました。
そのデザインパターンの一つ「Observer Pattern(オブザーバパターン)」をC#で書いていこうと思います。
私が働く会社では、一緒に働いてくれるエンジニアを募集しています♪
- 未経験、第二新卒歓迎
- 学歴・転職回数・離職期間不問
- 残業は月15時間以下で残業代は全額支給
- 経験者は月給23万円以上
- 年収100万以上UP↑↑↑も可能
- 長く働いていても年収が全然上がらないから、一気に年収を上げたい
- 残業をしたくてしているわけではないので、残業代はしっかりと出して欲しい
- やりたいことに挑戦させてもらえないから、自分がしてみたいことに挑戦したい
- 通勤時間が長すぎるから、できるだけ短くしたい
- もっと勉強したいから、書籍代など負担してくれるところに入りたい
- 現場に駆り出されてからは放置プレイで、相談できる人も先輩も居ないので、自分の状況をちゃんと理解してくれるところで働きたい
上記内容に1つでも当てはまる場合は、ぜひご検討ください。
Observer Pattern(オブザーバパターン)
身近なもので言うとLINEのグループようなものです。
という方は、まず友達作りから始めてください。
ある人がLINEを送る(変更する)と、グループに所属している人たちにメッセージが送られて通知(変更を通知する)が来ます。
(どっちかというと公式LINEからの通知に近いかもしれない)
このように変更がされたことを然るべきところに通知するのがObserver Pattern(オブザーバパターン)です。
生成された数値を数字とグラフで通知するプログラム
ランダムな数を生成するクラスと偶数を生成するクラスがあり、それぞれの数値を数字とグラフで通知するObserverが存在しているプログラムです。
Observerを疎結合にするためにIObserverインタフェースを使ってObserverを実装します。
IObserver | Observer用のインタフェース |
---|---|
NumberGenerator | 数を生成する抽象クラス |
RandomNumberGenerator | ランダムな数を生成するクラス |
EvenNumberGenerator | 偶数を生成するクラス |
DigitObserver | 生成された数値をそのまま通知するクラス |
GraphObserver | 生成されてた数値をアスタリスクのグラフで通知するクラス |
IObserverインタフェース
//Observer用のインタフェースを作って疎結合できるようにしておく
public interface IObserver
{
public void Update(NumberGenerator generator);
}
NumberGeneratorクラス
//数を生成する抽象クラス
public abstract class NumberGenerator
{
//通知するObserverを保持するList
private List<IObserver> _observers = new List<IObserver>();
//ObserverをListに追加する
public void AddObserver(IObserver observer)
{
_observers.Add(observer);
}
//Listに保持されたObserverへ通知する
public void NotifyObservers()
{
foreach (IObserver o in _observers)
{
//Listに保持されている各ObserverのUpdateメソッドが呼ばれる
o.Update(this);
}
}
//数を取得するための抽象プロパティ
public abstract int Number { get; }
//実行するための抽象メソッド
public abstract void Execute();
}
RandomNumberGeneratorクラス
//ランダムな数を生成するクラス
public class RandomNumberGenerator : NumberGenerator
{
//生成した数を保持するフィールド
private int _number;
public override int Number => _number;
private Random _random = new Random();
//数を生成して通知する
public override void Execute()
{
for (int i = 0; i < 20; i++)
{
_number = _random.Next(50);
NotifyObservers();
}
}
}
EvenNumberGeneratorクラス
//偶数を生成するクラス
public class EvenNumberGenerator : NumberGenerator
{
//生成した数を保持するフィールド
private int _number;
public override int Number => _number;
private Random _random = new Random();
//数を生成して通知する
public override void Execute()
{
for (int i = 0; i < 20; i++)
{
_number = _random.Next(50);
//奇数だったら1を足して偶数にする
if (_number % 2 == 1)
{
_number++;
}
NotifyObservers();
}
}
}
DigitObserverクラス
//生成された数値をそのまま通知するクラス
public class DigitObserver : IObserver
{
private Random _random = new Random();
public void Update(NumberGenerator generator)
{
Console.WriteLine("DigitObserver:" + generator.Number);
try
{
//通知されていることをわかりやすくするために遅らせる
Thread.Sleep(_random.Next(100, 1000));
}
catch (Exception e)
{
}
}
}
GraphObserverクラス
//生成されてた数値をアスタリスクのグラフで通知するクラス
public class GraphObserver : IObserver
{
private Random _random = new Random();
public void Update(NumberGenerator generator)
{
//生成された数値分のアスタリスクを並べる
var asterisk = "";
for (int i = 0; i < generator.Number; i++)
{
asterisk += "*";
}
Console.WriteLine($"GraphObserver:{asterisk}");
try
{
//通知されていることをわかりやすくするために遅らせる
Thread.Sleep(_random.Next(100, 1000));
}
catch (Exception e)
{
}
}
}
使い方
class Program
{
static void Main(string[] args)
{
//Observerのインスタンスを生成
var observer1 = new DigitObserver();
var observer2 = new GraphObserver();
Console.WriteLine("ランダムな数を生成して通知する");
var randomNumberGenerator = new RandomNumberGenerator();
randomNumberGenerator.AddObserver(observer1);
randomNumberGenerator.AddObserver(observer2);
randomNumberGenerator.Execute();
Console.WriteLine();
Console.WriteLine("偶数を生成して通知する");
var evenNumberGenerator = new EvenNumberGenerator();
evenNumberGenerator.AddObserver(observer1);
evenNumberGenerator.AddObserver(observer2);
evenNumberGenerator.Execute();
}
}
ランダムな数を生成して通知する
DigitObserver:47
GraphObserver:***********************************************
DigitObserver:2
GraphObserver:**
DigitObserver:26
GraphObserver:**************************
DigitObserver:42
GraphObserver:******************************************
DigitObserver:3
GraphObserver:***
DigitObserver:6
GraphObserver:******
DigitObserver:5
GraphObserver:*****
DigitObserver:32
GraphObserver:********************************
DigitObserver:40
GraphObserver:****************************************
DigitObserver:31
GraphObserver:*******************************
DigitObserver:17
GraphObserver:*****************
DigitObserver:49
GraphObserver:*************************************************
DigitObserver:19
GraphObserver:*******************
DigitObserver:40
GraphObserver:****************************************
DigitObserver:40
GraphObserver:****************************************
DigitObserver:15
GraphObserver:***************
DigitObserver:47
GraphObserver:***********************************************
DigitObserver:18
GraphObserver:******************
DigitObserver:1
GraphObserver:*
DigitObserver:17
GraphObserver:*****************
偶数を生成して通知する
DigitObserver:30
GraphObserver:******************************
DigitObserver:28
GraphObserver:****************************
DigitObserver:16
GraphObserver:****************
DigitObserver:18
GraphObserver:******************
DigitObserver:26
GraphObserver:**************************
DigitObserver:14
GraphObserver:**************
DigitObserver:8
GraphObserver:********
DigitObserver:44
GraphObserver:********************************************
DigitObserver:14
GraphObserver:**************
DigitObserver:18
GraphObserver:******************
DigitObserver:10
GraphObserver:**********
DigitObserver:16
GraphObserver:****************
DigitObserver:22
GraphObserver:**********************
DigitObserver:40
GraphObserver:****************************************
DigitObserver:0
GraphObserver:
DigitObserver:48
GraphObserver:************************************************
DigitObserver:28
GraphObserver:****************************
DigitObserver:50
GraphObserver:**************************************************
DigitObserver:2
GraphObserver:**
DigitObserver:16
GraphObserver:****************
まとめ
今回はコンソールアプリで実装しましたが、グラフと表が連動したWebアプリやWPFで作った画面が連動するWindowsアプリなどで実装すると面白そうですね。
暇な時に作ってみようと思います。
と思った方はコメントいただけると嬉しいです。
最後までお読みいただきありがとうございました!
私が働く会社では、一緒に働いてくれるエンジニアを募集しています♪
- 未経験、第二新卒歓迎
- 学歴・転職回数・離職期間不問
- 残業は月15時間以下で残業代は全額支給
- 経験者は月給23万円以上
- 年収100万以上UP↑↑↑も可能
- 長く働いていても年収が全然上がらないから、一気に年収を上げたい
- 残業をしたくてしているわけではないので、残業代はしっかりと出して欲しい
- やりたいことに挑戦させてもらえないから、自分がしてみたいことに挑戦したい
- 通勤時間が長すぎるから、できるだけ短くしたい
- もっと勉強したいから、書籍代など負担してくれるところに入りたい
- 現場に駆り出されてからは放置プレイで、相談できる人も先輩も居ないので、自分の状況をちゃんと理解してくれるところで働きたい
上記内容に1つでも当てはまる場合は、ぜひご検討ください。