观察者模式

发布订阅模型

  软件设计是一个动态变化的过程,一个对象的状态发生变化要通知给依赖他的其他对象,并使其他对象能够自动更新。如果这种依赖过于紧密,将使软件不能很好地抵御变化。


我们在取钱的时候,当银行账户里的金额发生变化的时候,需要通知给用户。及一个对象的状态发生变化的时候需要通知给其他对象,让其他的对象得到更新。这里我们应该是当账户金额变化的时候用户的email和手机应该得到通通知,从而更新。代码如下:

class BackAccunt
     {
         Email email = new Email();
         Mobile mobile=new Mobile();
         public void SetMoney(int data)
         {
             //存钱操作,
	     //....
            email.SendEmail();
            mobile.SendPhone();
             
         }
     }
    public class Email
    {
        public void SendEmail()
        {

        }
    }
    public class Mobile
    {
        public void SendPhone()
        {

        }
    }
这样写当然没错,当我们每次取完钱以后调用相应的方法,通知给其他对象,但是这种写法账户金额这个类与Email类、mobil类是紧耦合的关系,依赖性很强,这样的设计的软件是很不稳定的。并且如果我想增加一个qq,增加一个手机通知类,每次只能重新new,这样做很不利于后期的扩展。也就是说我们要通知的对象不是固定的,而是变化的,只是这些被通知者都有共同的行为,那就是发送相应的数据资源。这个时候我们可以考虑将通知对象提取成一个接口。让其他需要扩展的部分都依赖于该接口。

interface IAccountObserve
    {
        void SendData(UserAccountArgs args);
    }


观察者模式:

      观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。(此定义来自百度百科)。

 比方说当用户的界面发生变化的时候,那他的业务数据也应该显示在界面上。而且是一对多的关系,也就是说一个对象的变化应该通知给其他多个对象,(和状态模式有区别,状态模式是状态发生变化的时候引起自身行为的变化)。也就是说观察者模式必须有观察者和被观察者,在上面的栗子中,ATM机就是观察者,当他观察到银行的账户金额变化时,通知给其他被观察者对象,手机和邮箱就是被观察者。上面的代码我们可以将需要变化的部分提取成一个接口,让依赖对象都继承自该接口。

public class Email:IAccountObserve
    {
        public void SendEmail(UserAccountArgs args)
        {
            string email = args.email;
            //......拿到email对象进行操作
        }
    }
    public class Mobile : IAccountObserve
    {
        public void SendPhone(UserAccountArgs args)
        {
            string mobile = args.mobile;
            //.......拿到mobile对象进行操作
        }
    }
这样我们的email和mobile类都不在依赖于BackAccount而依赖于稳定的接口。我们建立一个UserAccountArgs类来管理被通知的对象

class UserAccountArgs
    {
        //需要通知的成员对象。
        public string email;
        public string mobile;
    
    }

这样,我们可以将BackAccount类改写为:

 class BackAccunt
     {

         List<IAccountObserve> observes = new List<IAccountObserve>();
         public void SetMoney(int data)
         {
             //存钱操作
             UserAccountArgs args = new UserAccountArgs();
             foreach(var item in observes)
             {
                 item.SendData(args);
             }
             
         }
         public void AddObserve(IAccountObserve observe)
         {
             observes.Add(observe);//添加需要通知的成员
         }
         public void RemoveObserve(IAccountObserve observe)
         {
             observes.Remove(observe);//移除需要通知的成员
         }
     }
在该类中,我们只需要用一个集合来管理(添加或者删除)被通知的对象。当需要扩展其他被观察者对象的时候,就可以直接继承该接口。在主函数中调用就只需要管理观察者和被观察者了。

 BackAccunt account = new BackAccunt();
            Email em = new Email();
            account.AddObserve(em);//添加要通知的成员
            account.SetMoney(5);//存完5元以后自动通知发送email;

简单的观察者模式已经实现了。当然根据业务需求,这段代码还可以再进行抽象,不断提取变化的部分,封装变化的部分。





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值