双向耦合的例子
class Subject
{
private List<Observer> observerList = new List<Observer>();
private string notifyContent;
public void AddObserver(Observer o)
{
observerList.Add(o);
}
public void RemoveObserver(Observer o)
{
observerList.Remove(o);
}
public void Notify()
{
foreach (var item in observerList)
item.Update();
}
public string NotifyContent
{
set { notifyContent = value; }
get { return notifyContent; }
}
}
class Observer
{
private string name;
private Subject subject;
public Observer(string name, Subject sub)
{
this.name = name;
this.subject = sub;
}
public void Update()
{
Console.WriteLine(subject.NotifyContent+name);
}
}
class Program
{
static void Main(string[] args)
{
Subject sub = new Subject();
sub.NotifyContent = "Notify";
Observer obs = new Observer("obs", sub);
sub.AddObserver(obs);
sub.Notify();
Console.Read();
}
}
方法一:委托事件方法处理松耦合
delegate void EventHandler();
class Subject
{
public event EventHandler Update;
private string notifyContent;
public void Notify()
{
Update();
}
public string NotifyContent
{
set { notifyContent = value; }
get { return notifyContent; }
}
}
class Observer
{
private string name;
private Subject subject;
public Observer(string name, Subject sub)
{
this.name = name;
this.subject = sub;
}
public void Update()
{
Console.WriteLine(subject.NotifyContent+name);
}
}
class Program
{
static void Main(string[] args)
{
Subject sub = new Subject();
sub.NotifyContent = "Notify";
Observer obs = new Observer("obs", sub);
sub.Update += obs.Update;
sub.Notify();
Console.Read();
}
}
方法二:观察者模式(发布订阅模式)让耦合的双方依赖于抽象 不依赖于具体
/// <summary>
/// 把所有观察者对象的引用保存在list中
/// 每个主题可以有任意数量的观察者。
/// 抽象主题提供增加删除观察者的接口
/// </summary>
abstract class AbstractSubject
{
private List<AbstractObsrever> observerList = new List<AbstractObsrever>();
public void AddObserver(AbstractObsrever o)
{
observerList.Add(o);
}
public void RemoveObserver(AbstractObsrever o)
{
observerList.Remove(o);
}
public void Notify()
{
foreach (var item in observerList)
item.Update();
}
}
/// <summary>
/// 抽象观察者
/// 为所有观察者定义一个接口
/// 得到主题的通知时更新自己
/// </summary>
abstract class AbstractObsrever
{
public abstract void Update();
}
/// <summary>
/// 具体主题
/// 将有关状态存入观察者对象
/// 在具体主题内部状态改变时
/// 给所有登记过的观察者发出通知
/// </summary>
class Subject : AbstractSubject
{
private string notifyContent;
public string NotifyContent
{
set { notifyContent = value; }
get { return notifyContent; }
}
}
/// <summary>
/// 具体的观察者
/// 实现抽象观察者角色所要求的更新接口
/// 以便使本身的状态与主题的状态相协调
/// </summary>
class Observer:AbstractObsrever
{
private string name;
private Subject subject;
public Observer(string name, Subject sub)
{
this.name = name;
this.subject = sub;
}
public override void Update()
{
Console.WriteLine(subject.NotifyContent+name);
}
}
/// <summary>
/// 测试类
/// </summary>
class Program
{
static void Main(string[] args)
{
Subject sub = new Subject();
sub.NotifyContent = "Notify";
Observer obs = new Observer("obs", sub);
sub.AddObserver(obs);
sub.Notify();
Console.Read();
}
}
总结:委托事件方法好用,但是需要委托搭载的所有方法具有相同的参数和返回值
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题的对象。这个主题的对象在状态发生变化时,会通知所有观察者对象,让它们能够自动更新自己。