欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c# 实现观察者模式

程序员文章站 2022-06-23 11:02:39
说明:主要参考《head first设计模式(中文版)》,使用c#代码实现。代码:github1、观察者模式uml图2、气象监测类图3、气象监测代码(书中c#版)3.1 observerpublic...

说明:主要参考《head first设计模式(中文版)》,使用c#代码实现。

代码:github

1、观察者模式uml图

c# 实现观察者模式

2、气象监测类图

c# 实现观察者模式

3、气象监测代码(书中c#版)

3.1 observer

public interface iobserver
{
    void update(float temperature, float humidity, float pressure);
}
public interface idisplayelement
{
    void display();
}
public class currentconditiondisplay : iobserver, idisplayelement
{
    private readonly isubject _weatherdata;
 
    private float _temperature;
    private float _humidity;
 
    public currentconditiondisplay(isubject weatherdata)
    {
        _weatherdata = weatherdata;
        _weatherdata?.registerobserver(this);
    }
 
    public void update(float temperature, float humidity, float pressure)
    {
        _temperature = temperature;
        _humidity = humidity;
        display();
    }
 
    public void display()
    {
        console.writeline($"current conditions: {_temperature}f degress and {_humidity}% humidity");
    }
}

3.2 subject

public interface isubject
{
    void registerobserver(iobserver o);
    void removeobserver(iobserver o);
    void notifyobservers();
}
public class weatherdata : isubject
{
    //观察者列表
    private readonly list<iobserver> _observerlist;
 
    //天气数据
    private float _temperature;
    private float _humidity;
    private float _pressure;
 
    public weatherdata()
    {
        _observerlist = new list<iobserver>();
    }
 
    /// <summary>
    /// 订阅观察者
    /// </summary>
    /// <param name="o">观察者对象</param>
    public void registerobserver(iobserver o)
    {
        _observerlist.add(o);
    }
 
    /// <summary>
    /// 移除观察者
    /// </summary>
    /// <param name="o">观察者对象</param>
    public void removeobserver(iobserver o)
    {
        if (_observerlist.contains(o))
        {
            _observerlist.remove(o);
        }
    }
 
    /// <summary>
    /// 发布数据
    /// </summary>
    public void notifyobservers()
    {
        foreach (var observer in _observerlist)
        {
            observer.update(_temperature, _humidity, _pressure);
        }
    }
 
    /// <summary>
    /// 数据发生改变
    /// </summary>
    private void measurementchanged()
    {
        notifyobservers();
    }
 
    /// <summary>
    /// 更新数据
    /// </summary>
    /// <param name="temperature">温度</param>
    /// <param name="humidity">湿度</param>
    /// <param name="pressure">气压</param>
    public void setmeasurements(float temperature, float humidity, float pressure)
    {
        _temperature = temperature;
        _humidity = humidity;
        _pressure = pressure;
        measurementchanged();
    }
}

3.3 测试代码

private static void testweatherdata()
{
    var weatherdata = new weatherdata();
    var currentconditiondisplay = new currentconditiondisplay(weatherdata);
 
    weatherdata.setmeasurements(80, 65, 30.4f);
    weatherdata.setmeasurements(82, 70, 29.2f);
    weatherdata.setmeasurements(78, 90, 29.2f);
}

4、使用c#中iobservable接口实现气象监测

4.1 辅助类/结构体

public struct weathermessage
{
    public float temperature { get; set; }
    public float humidity { get; set; }
    public float pressure { get; set; }
}
 
public class messageunknownexception : exception
{
    internal messageunknownexception()
    {
 
    }
}

4.2 iobserver具体实现

class currentconditiondisplayx : iobserver<weathermessage>, idisplayelement
{
    private idisposable _unsubscribe;
 
    private float _temperature;
    private float _humidity;
 
    public void subscribe(iobservable<weathermessage> provider)
    {
        if (provider != null)
        {
            _unsubscribe = provider.subscribe(this);
        }
    }
 
    public void unsubscribe()
    {
        _unsubscribe?.dispose();
        _unsubscribe = null;
    }
 
    public void oncompleted()
    {
        console.writeline("currentconditiondisplayx: oncompleted");
        unsubscribe();
    }
 
    public void onerror(exception error)
    {
        console.writeline("currentconditiondisplayx: onerror");
    }
 
    public void onnext(weathermessage value)
    {
        _temperature = value.temperature;
        _humidity = value.humidity;
        display();
    }
 
    public void display()
    {
        console.writeline($"current conditions: {_temperature}f degress and {_humidity}% humidity");
    }
}

4.3 iobservable具体实现

public class weatherdatax : iobservable<weathermessage>
{
    private readonly list<iobserver<weathermessage>> _observerlist;
 
    public weatherdatax()
    {
        _observerlist = new list<iobserver<weathermessage>>();
    }
 
    /// <summary>
    /// 通知提供程序:某观察程序将要接收通知。
    /// </summary>
    /// <param name="observer">要接收通知的对象。</param>
    /// <returns>使资源释放的观察程序的接口。</returns>
    public idisposable subscribe(iobserver<weathermessage> observer)
    {
        if(!_observerlist.contains(observer))
        {
            _observerlist.add(observer);
        }
        return new unsubcriber(_observerlist, observer);
    }
 
    public void setmeasurements(nullable<weathermessage> message)
    {
        foreach (var observer in _observerlist)
        {
            if (!message.hasvalue)
            {
                observer.onerror(new messageunknownexception());
            }
            else
            {
                observer.onnext(message.value);
            }
        }
    }
 
    public void endtransmission()
    {
        foreach (var observer in _observerlist.toarray())
        {
            if (_observerlist.contains(observer))
            {
                observer.oncompleted();
            }
        }
        _observerlist.clear();
    }
 
    private class unsubcriber : idisposable
    {
        private list<iobserver<weathermessage>> _observerlist;
        private iobserver<weathermessage> _observer;
 
        public unsubcriber(list<iobserver<weathermessage>> observerlist, iobserver<weathermessage> observer)
        {
            _observerlist = observerlist;
            _observer = observer;
        }
 
        public void dispose()
        {
            if (_observerlist != null && _observerlist.contains(_observer))
            {
                _observerlist.remove(_observer);
            }
        }
    }
}

4.4 测试代码

private static void testweatherdatax()
{
    var weatherdata = new weatherdatax();
    var currentconditiondisplay = new currentconditiondisplayx();
 
    currentconditiondisplay.subscribe(weatherdata);
 
    weatherdata.setmeasurements(new weathermessage()
    {
        temperature = 80,
        humidity = 65,
        pressure = 30.4f
    });
    weatherdata.setmeasurements(new weathermessage()
    {
        temperature = 82,
        humidity = 70,
        pressure = 29.2f
    });
    weatherdata.setmeasurements(new weathermessage()
    {
        temperature = 78,
        humidity = 90,
        pressure = 29.2f
    });
    weatherdata.endtransmission();
}

以上就是c# 实现观察者模式的详细内容,更多关于c# 观察者模式的资料请关注其它相关文章!