1)概念
观察者:指观察者对象,也是消息的订阅者
被观察者:指为观察的目标对象,也就是消息的发布者。
(2)观察者模式又称为发布—订阅(Publish/Subscribe)模式,观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听一个主题对象,而每当那一个主题对象发生变化的时候,它就会通知所有的观察对象,使它们能够自动更新自己。
(3)每一个模式描述了我们周围重复不断变化的问题,以及该问题的解决方案核心
(4)每一个特定的问题,他都会有自己的特定解决方法套路。
代码案例:
(1)老师订阅类
/// <summary>
/// 老师订阅类
/// </summary>
public class Teacher
{
/// <summary>
/// 订阅者:学生对象
/// </summary>
public Student Student { get; set; }
public string Symbol { get; set; }
public string Info { get; set; }
public void Updata()
{
if (Student != null)
{
//调用订阅者来通知订阅者
Student.ReceiveAndPintData(this);
}
}
}
(2)订阅者
//订阅者类
public class Student
{
public string Name { get; set; }
public Student(string name)
{
this.Name = name;
}
public void ReceiveAndPintData(Teacher teacher)
{
Console.WriteLine("我是{0}一个{1}:{2}",Name,teacher.Symbol,teacher.Info);
}
}
(3)客户端显示
//客户端显示
Student student = new Student("student");
Teacher teacher = new Teacher();
teacher.Student = student;
teacher.Info = "老师对我说:小子!别跑,代码还没有打完呢?你想溜............";
teacher.Updata();
Console.ReadLine();
Console.ReadKey();
(4)整体代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace testAopByDecorator
{
class Program
{
/// <summary>
/// 老师订阅类
/// </summary>
public class Teacher
{
/// <summary>
/// 订阅者:学生对象
/// </summary>
public Student Student { get; set; }
public string Symbol { get; set; }
public string Info { get; set; }
public void Updata()
{
if (Student != null)
{
//调用订阅者来通知订阅者
Student.ReceiveAndPintData(this);
}
}
}
//订阅者类
public class Student
{
public string Name { get; set; }
public Student(string name)
{
this.Name = name;
}
public void ReceiveAndPintData(Teacher teacher)
{
Console.WriteLine("我是{0}一个{1}:{2}",Name,teacher.Symbol,teacher.Info);
}
}
/// <summary>
/// 客户端显示
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Student student = new Student("student");
Teacher teacher = new Teacher();
teacher.Student = student;
teacher.Info = "老师对我说:小子!别跑,代码还没有打完呢?你想溜............";
teacher.Updata();
Console.ReadLine();
Console.ReadKey();
}
}
}
(5)运行效果
如果有细心观察的朋友就会发现,上面的代码是有一些错误的,想一想,如果上面的其中一个类发生了改变,那么另外的类也就发生了改变,那么这样子的话,就达不到开闭原则的要求,也就达不到我们想要让一个程序达到理想的效果,那么该什么样解决呢?请看如下的实例运用代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace testAopByDecorator
{
class Program
{
//委托订阅者接口类
public delegate void NotifyEventHandler(object sender);
//抽象订阅类
public class School
{
public NotifyEventHandler NotifyEvent;
public string Symbol { get; set; }
public string Info { get; set; }
public School(string symbol,string info)
{
this.Symbol = symbol;
this.Info = info;
}
public School()
{
}
//新增对订阅号列表的维护操作
public void AddObserver(NotifyEventHandler ob)
{
NotifyEvent += ob;
}
//减少对订阅号列表的维护操作
public void RemoveObserver(NotifyEventHandler ob)
{
NotifyEvent -= ob;
}
public void Update()
{
if (NotifyEvent != null)
{
NotifyEvent(this);
}
}
}
//具体订阅类
public class Student : School
{
public Student(string symbol, string info) : base(symbol, info)
{
}
}
//具体订阅者类
public class Subscriber
{
public string Name { get; set; }
public Subscriber(string name)
{
this.Name = name;
}
public void ReceiveAndPrint(object obj)
{
School school = obj as School;
if (school != null)
{
Console.WriteLine("我是{0}一个{1}:{2}", Name, school.Symbol, school.Info);
}
}
}
/// <summary>
/// 客户端显示
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
School school = new School();
Subscriber subscriber = new Subscriber("哈哈哈......");
Subscriber subscribers = new Subscriber("嘻嘻嘻.....");
school.AddObserver(new NotifyEventHandler(subscriber.ReceiveAndPrint));
school.AddObserver(new NotifyEventHandler(subscribers.ReceiveAndPrint));
school.Update();
Console.WriteLine("-------------------------------------");
Console.WriteLine("移除subscribers订阅者");
school.RemoveObserver(new NotifyEventHandler(subscriber.ReceiveAndPrint));
school.Update();
Console.ReadKey();
}
}
}
运行效果: