观察者模式

2.2 观察者模式

public class BoilWater
{
public int waterTemperature = 0;

public IList Observers = new List();

public void Boil()
{
    for (int i = 0; i < 100; i++)
    {
        waterTemperature = i;
        Thread.Sleep(100);
        if (waterTemperature == 100)
        {
            CallAllObserve();
        }
    }
}

public void CallAllObserve()
{
    foreach (var item in Observers)
    {
        item.Run();
    }
}

public void AddObserver(RunInter runner)
{
    Observers.Add(runner);
}

public void RemoveObserver(RunInter runner)
{
    Observers.Remove(runner);
}

}

public interface RunInter
{
    void Run();
}

public class Call : RunInter
{
    public void Run()
    {
        Console.Write("The Water is Boiled!");
    }
}

public class DoOtherThing : RunInter
{
    public void Run()
    {
        Console.Write("Do Other Things");
    }
}

复制代码
这里我们在被观察的类中放一个存储接口的列表,然后在事件满足的时候,将列表中的每一个接口都执行一遍,而且因为有AddObserver和RemoveObserver方法,因此在程序运行的过程中我们也可以动态的添加新的处理代码,或删除已有的处理代码。

但是这样做确实是有一点繁琐,要定义接口,还要再检测类中加上对应的列表,还好.NET已经为我们设计了完美的替代方案,那就是使用委托和事件;

2.3 使用委托和事件来实现观察者模式
复制代码
public class BoilWater
{
public int waterTemperature = 0;

private event Action actions;

public void Boil()
{
    for (int i = 0; i < 100; i++)
    {
        waterTemperature = i;
        Thread.Sleep(100);
        if (waterTemperature == 100)
        {
            actions();
        }
    }
}

public void AddObserver(Action runner)
{
    actions += runner;
}

public void RemoveObserver(Action runner)
{
    actions -= runner;
}

}
复制代码
调用的时候只需要:

复制代码
var boilWater = new BoilWater();
boilWater.AddObserver(() =>
{
Console.WriteLine(“Water is Boiled”);
});
boilWater.AddObserver(() =>
{
Console.WriteLine(“Do Other Things”);
});
复制代码
这样当水开的时候,两个控制台打印的方法,都会被执行了。

其实在这里的Action就是.Net自带的委托对象,其实委托我们在和上面的代码对比后,就可以认为他是一系列相似方法的集合列表,当执行委托之后,这个集合中的每一个方法就会依次被执行(有先后顺序,并不是并发执行);

但这种方式就为我们实现观察者模式的逻辑提供的很大的方便。

2.4 委托和事件的区别
2.3中的代码我使用了event关键字,就是讲委托声明为事件了,很多人区分不出委托和事件的区别,其实很简单,事件是一种特殊的委托;

既然是委托,其实说到底他还是方法的集合,当执行事件后,这个集合中的所有方法都会被执行;

区别在于,委托可以在委托所属的类外面进行添加和删除操作;但是事件不行,事件只能在事件所属的类内部进行添加和删除操作。

你可能感兴趣的:(观察者模式)