c# 实现观察者模式
程序员文章站
2022-06-23 11:02:39
说明:主要参考《head first设计模式(中文版)》,使用c#代码实现。代码:github1、观察者模式uml图2、气象监测类图3、气象监测代码(书中c#版)3.1 observerpublic...
说明:主要参考《head first设计模式(中文版)》,使用c#代码实现。
代码:github
1、观察者模式uml图
2、气象监测类图
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# 观察者模式的资料请关注其它相关文章!
上一篇: Python列表删除的三种方法代码分享
下一篇: 大叔,你是谁啊?咱俩认识吗