(观察者封装了观察者和观察方法这两个变化点,重要的还是观察方法。)
个人理解
针对软件构建过程中,某些对象存在的“通知依赖关系”(如果目标对象的状态发生改变将通知所有的依赖对象)。我们可以利用抽象类或者接口在消息发出对象中建立通知耦合关系,也可以通过事件与委托在被通知对象中建立通知这种藕和关系。效果及实现要点
1.使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合。
2.目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知。目标对象对此一无所知。
3.在C#中的Event。委托充当了抽象的Observer接口,而提供事件的对象充当了目标对象,委托是比抽象Observer接口更为松耦合的设计。
适用性
1.当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
总结
通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展
实例代码
public
class
Observer
{
(一般情况下该模式的实现)#region(一般情况下该模式的实现)
/**//// <summary>
/// 公司目标抽象类(本例子是用抽象类,当然可以用接口实现)
/// </summary>
public abstract class CompanyObject
{
#region
ArrayList observers = new ArrayList();
public void Attach(CustomerObserver observer)
{
observers.Add(observer);
}
public void Detach(CustomerObserver observer)
{
observers.Remove(observer);
}
public void Notify(string information)
{
foreach(CustomerObserver observer in observers)
{
observer.Update(information);
}
}
#endregion
}
/**//// <summary>
/// 具体的目标公司对象
/// </summary>
public class ConcreteCompanyObject : CompanyObject
{
#region
public void ChangeInformation(string info)
{
this.Notify(info);
}
#endregion
}
/**//// <summary>
/// 客户观察者抽象类
/// </summary>
public abstract class CustomerObserver
{
public abstract void Update(string information);
}
/**//// <summary>
/// 具体的客户观察对象
/// </summary>
public class ConcreteCustomerObserver : CustomerObserver
{
#region
string name = null;
public ConcreteCustomerObserver(string name)
{
this.name = name;
}
public override void Update(string info)
{
Console.WriteLine("名为{0}更新了合作公司的信息。信息内容为:{1}", name, info);
}
#endregion
}
#endregion
(以下利用委托和事件来实现该模式)#region(以下利用委托和事件来实现该模式)
public class Companys
{
public delegate void ReportChange(string info);
public event ReportChange changeInfo;
public Companys()
{ }
public void ChangeInfomation(string info)
{
changeInfo(info);
}
}
public class Customer
{
Companys company;
public Customer()
{ }
public void InitCompanyObject(Companys com)
{
this.company = com;
//定阅合作公司信息改变事件
com.changeInfo += new Companys.ReportChange(InfoChange);
}
void InfoChange(string info)
{
Console.WriteLine("合作公司更新了信息。信息内容为:{0}", info);
}
}
#endregion
}
{
(一般情况下该模式的实现)#region(一般情况下该模式的实现)
/**//// <summary>
/// 公司目标抽象类(本例子是用抽象类,当然可以用接口实现)
/// </summary>
public abstract class CompanyObject
{
#region
ArrayList observers = new ArrayList();
public void Attach(CustomerObserver observer)
{
observers.Add(observer);
}
public void Detach(CustomerObserver observer)
{
observers.Remove(observer);
}
public void Notify(string information)
{
foreach(CustomerObserver observer in observers)
{
observer.Update(information);
}
}
#endregion
}
/**//// <summary>
/// 具体的目标公司对象
/// </summary>
public class ConcreteCompanyObject : CompanyObject
{
#region
public void ChangeInformation(string info)
{
this.Notify(info);
}
#endregion
}
/**//// <summary>
/// 客户观察者抽象类
/// </summary>
public abstract class CustomerObserver
{
public abstract void Update(string information);
}
/**//// <summary>
/// 具体的客户观察对象
/// </summary>
public class ConcreteCustomerObserver : CustomerObserver
{
#region
string name = null;
public ConcreteCustomerObserver(string name)
{
this.name = name;
}
public override void Update(string info)
{
Console.WriteLine("名为{0}更新了合作公司的信息。信息内容为:{1}", name, info);
}
#endregion
}
#endregion
(以下利用委托和事件来实现该模式)#region(以下利用委托和事件来实现该模式)
public class Companys
{
public delegate void ReportChange(string info);
public event ReportChange changeInfo;
public Companys()
{ }
public void ChangeInfomation(string info)
{
changeInfo(info);
}
}
public class Customer
{
Companys company;
public Customer()
{ }
public void InitCompanyObject(Companys com)
{
this.company = com;
//定阅合作公司信息改变事件
com.changeInfo += new Companys.ReportChange(InfoChange);
}
void InfoChange(string info)
{
Console.WriteLine("合作公司更新了信息。信息内容为:{0}", info);
}
}
#endregion
}
调用
static
void
Main(
string
[] args)
{
#region
//创建一个公司实例
Observer.ConcreteCompanyObject company = new Observer.ConcreteCompanyObject();
//创建两个客户实例
Observer.ConcreteCustomerObserver customer1 = new Observer.ConcreteCustomerObserver("Liang");
Observer.ConcreteCustomerObserver customer2 = new Observer.ConcreteCustomerObserver("Dabing");
//给两个客户订阅信息
company.Attach(customer1);
company.Attach(customer2);
//更改公司信息
company.ChangeInformation("合作愉快");
//预测:两个客户将打印相关信息
#endregion
#region
Observer.Companys comp = new Observer.Companys();
Observer.Customer cust1 = new Observer.Customer();
Observer.Customer cust2 = new Observer.Customer();
cust1.InitCompanyObject(comp);
cust2.InitCompanyObject(comp);
comp.ChangeInfomation("合作愉快");
#endregion
Console.ReadLine();
}
{
#region
//创建一个公司实例
Observer.ConcreteCompanyObject company = new Observer.ConcreteCompanyObject();
//创建两个客户实例
Observer.ConcreteCustomerObserver customer1 = new Observer.ConcreteCustomerObserver("Liang");
Observer.ConcreteCustomerObserver customer2 = new Observer.ConcreteCustomerObserver("Dabing");
//给两个客户订阅信息
company.Attach(customer1);
company.Attach(customer2);
//更改公司信息
company.ChangeInformation("合作愉快");
//预测:两个客户将打印相关信息
#endregion
#region
Observer.Companys comp = new Observer.Companys();
Observer.Customer cust1 = new Observer.Customer();
Observer.Customer cust2 = new Observer.Customer();
cust1.InitCompanyObject(comp);
cust2.InitCompanyObject(comp);
comp.ChangeInfomation("合作愉快");
#endregion
Console.ReadLine();
}