IOC,观察者模式,项目的实际应用

一、概述

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

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

二、观察者模式结构图:

三、实际列子

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

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

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

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

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

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

NetMonitor的调用代码:

None.gif Pulbic  class  NetMonitor
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    Public 
void Monitor()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        MonitorContaniner netMonitor 
= new NetMonitor();
InBlock.gif        IAlarm mailAlarm 
= new EmailAlarm();
InBlock.gif        netMonitor. AddAlarm (mailAlarm);
//增加Eamil报警模块
InBlock.gif        IAlarm smsAlarm 
= new SMSAlarm();
InBlock.gif        netMonitor. AddAlarm (smsAlarm);
//增加SMS报警模块
InBlock.gif
        base.Notify();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

 

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

MonitorContainer具体代码:

ExpandedBlockStart.gif ContractedBlock.gif   /**/ /// <summary>
InBlock.gif      
/// 监控模块容器
ExpandedBlockEnd.gif     
/// </summary>

None.gif
None.gif     
public   abstract   class  MontiorContainer

ExpandedBlockStart.gifContractedBlock.gif     
dot.gif {
InBlock.gif         private statci 
IWindsorContainer container = null;
InBlock.gif         
private string _alarmMessage;
InBlock.gif
InBlock.gif         
statci MontiorContainer ()
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif                 container 
= new WindsorContainer("Alarm.xml");//报警器的设置文件

ExpandedSubBlockEnd.gif             }

ExpandedSubBlockEnd.gif         }

InBlock.gif         
public void Notify()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif
InBlock.gif              
if (container != null)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                   IConfiguration[] configuration 
= container.Kernel.ConfigurationStore.GetComponents();                  
InBlock.gif
InBlock.gif                   
foreach (IConfiguration item in configuration)//依次调用报警模块
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif                   
dot.gif{
InBlock.gif
InBlock.gif
//framework 1.1                      
InBlock.gif
IAlarm alarm = container.Resolve(item.Attributes["id"].ToString()) as IAlarm ;
InBlock.gif
//framework2可以使用
InBlock.gif
//IAlarm alarm = container.Resolve<IAlarm >(item.Attributes["id"].ToString());
InBlock.gif                       alarm.Warn(_alarmMessage);
ExpandedSubBlockEnd.gif                   }

ExpandedSubBlockEnd.gif              }

ExpandedSubBlockEnd.gif         }

InBlock.gif
InBlock.gif
//扩展:如果需要根据监控情况而采取不同的报警方式,对应的需要修改Instance
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif
/**//*public void RemoveAlarm()
InBlock.gif         {
InBlock.gif         }
InBlock.gif         public void AddAlarm(string alarmType)
InBlock.gif         {
ExpandedSubBlockEnd.gif         }
*/

InBlock.gif          
//报警内容
InBlock.gif         
public string AlarmMessage
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
setdot.gif{ _alarmMessage = value;}
InBlock.gif
ExpandedSubBlockEnd.gif         }


 

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的调用代码:

None.gif Pulbic  class  NetMonitor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Public 
void Monitor()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif       
base.Notify();
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif


怎么样,简单吧。把藕合度大大降低了。

四、总结

通过Observer模式结合IOC容器,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性。

扩展报警模块不需对现有系统代码修改即可增加,具体的监控模块都不需知道怎么调用报警模块。

转载于:https://www.cnblogs.com/try/archive/2006/11/30/577684.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值