求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
 
IOC,观察者模式,项目的实际应用

2010-07-12 出处:网络

 

一、概述:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。[GOF 《设计模式》]

看了Terrylee的.NET设计模式(19):观察者模式(Observer Pattern),个人认为其模式的推导比较清晰,但感觉举的例子不是很好,和实际项目还是有些脱离。正好手上有一小项目应用了此模式,不知应用的是否正确,如果理解的不到位,请大家指正。此文算是对.NET设计模式(19):观察者模式(Observer Pattern)的一个补充吧,不知Terrylee是否允许。

二、观察者模式结构图:

三、实际列子:

一监控系统,需要根据系统某些变化报警,报警方式有Email、短信等多种,以后可能会变化。怎么演绎到观察者模式就不再多说了(如果需要的话再补充,一般参考Terrylee的文章即可明白)。

IAlarm是报警接口。当我们的系统需要添加报警方式的时候只需实现IAlarm的Warn方法即可。Email类是Email报警的实现,SMS类是短信报警的实现。

MonitorContainer是监视器(抽象类)相当于观察者。只负责通知变化,当子类调用Notify方法它即会通知报警模块报警,如Email和SMS(短信)。

NetMonitor是其中的具体的监控模块,继承于MonitorContainer。当发现系统网络有问题时会调用父类的Notify方法。

MonitorContainer里的AddAlarm这里就省略了(把报警模块对象加入到ArraryList中)

Notify方法就是foreach下报警模块对象集合。(可参考.NET设计模式(19):观察者模式(Observer Pattern)文章里的代码)

NetMonitor的调用代码:

Pulbic class NetMonitor
  
{
  
  Public void Monitor()
  
  {
  
    MonitorContaniner netMonitor = new NetMonitor();
    IAlarm mailAlarm = new EmailAlarm();
    netMonitor. AddAlarm (mailAlarm);//增加Eamil报警模块
    IAlarm smsAlarm = new SMSAlarm();
    netMonitor. AddAlarm (smsAlarm);//增加SMS报警模块
    base.Notify();
  }
}
 

个人感觉各个模块间藕合的还是比较厉害。怎么办?于是我加入了IOC。我使用的是Castle的IOC容器。

MonitorContainer具体代码:

/**//// <summary>
   /// 监控模块容器
   /// </summary>
  
   public abstract class MontiorContainer
  
   {
     private statci IWindsorContainer container = null;
     private string _alarmMessage;
  
     statci MontiorContainer ()
     {
         container = new WindsorContainer("Alarm.xml");//报警器的设置文件
       }
     }
     public void Notify()
  
     {
  
       if (container != null)
  
       {
  
          IConfiguration[] configuration = container.Kernel.ConfigurationStore.GetComponents();         
  
          foreach (IConfiguration item in configuration)//依次调用报警模块
  
          {
  
//framework 1.1           
IAlarm alarm = container.Resolve(item.Attributes["id"].ToString()) as IAlarm ;
//framework2可以使用
//IAlarm alarm = container.Resolve<IAlarm >(item.Attributes["id"].ToString());
            alarm.Warn(_alarmMessage);
          }
       }
     }
  
//扩展:如果需要根据监控情况而采取不同的报警方式,对应的需要修改Instance
  
/**//*public void RemoveAlarm()
     {
     }
     public void AddAlarm(string alarmType)
     {
     }*/
     //报警内容
     public string AlarmMessage
  
     {
  
       set{ _alarmMessage = value;}
  
     }

Alarm.xml(Castle的标准配置)

<?xml version="1.0" encoding="utf-8" ?>
  
<configuration>
  
  <components>
  
    <component id="EmailAlarm" service="Alarm.IAlarm,IAlarm" type="Alarm.EMailAlarm,EMailAlarm"/>
  
    <component id="SMSIAlarm" service="Alarm.IAlarm,IAlarm" type="Alarm.SMSAlarm,SMSAlarm"/>
  
  </components>
  
</configuration>

现在NetMonitor的调用代码:

Pulbic class NetMonitor
{
  Public void Monitor()
  {
    base.Notify();
  
  }
}


如何向妻子解释OOD
OOAD与UML笔记
UML类图与类的关系详解
UML统一建模语言初学
总结一下领域模型的验证
基于 UML 的业务建模


面向对象的分析设计
基于UML的面向对象分析设计
UML + 嵌入式系统分析设计
关系数据库面向OOAD设计
业务建模与业务架构
使用用例进行需求管理


某航空IT部门 业务分析与业务建模
联想 业务需求分析与建模
北京航管科技 EA工具与架构设计
使用EA和UML进行嵌入式系统分析
全球最大的茶业集团 UML系统分析
华为 基于EA的嵌入式系统建模
水资源服务商 基于EA进行UML建模
更多...