zoukankan      html  css  js  c++  java
  • 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式)

    动机(Motivation)

    在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象)都将得到通知。如果这样的以来对象关系过于紧密,将使软件不能很好地抵御变化。

    使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

    意图(Intent)

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

    示例代码

    这是一个ATM取钱的例子:

        public class ATM
        {
            private BankAccount bankAccount;
         //...
            void Process(int data)
            {
                bankAccount.Widthdraw(data);
            }
        }
    
        public class BankAccount
        {
            private Emailer emailer;//强依赖关系
            private Mobile mobile;//强依赖关系
    
            public void Widthdraw(int data)
            {
            //...
                UserAccountArgs args=new UserAccountArgs();
                //...
                emailer.SendEmail(UserAccountArgs.UserEmail);
                mobile.SendNotification(UserAccountArgs.MobileNumber);
            }
        }
    
        public class Emailer
        {
            public void SendEmail(string userEmail)
            {
                //...
            }
        }
    
        public class Mobile
        {
            public void SendNotification(string mobileNumber)
            {
                //...
            }
        }
    public class UserAccountArgs { public string UserEmail { get; set; } public string MobileNumber { get; set; } }

    BankAccount和Emailer、Mobile是紧耦合的关系,需要解耦:

    public class BankAccount
        {
            IList<IAccountObserver> observerList=new List<IAccountObserver>();
    
            public void Widthdraw(int data)
            {
                //...
                UserAccountArgs args=new UserAccountArgs();
                //...
                foreach (var accountObserver in observerList)
                {
                    accountObserver.Update(args);
                }
            }
    
            public void AddObserver(IAccountObserver accountObserver)
            {
                observerList.Add(accountObserver);
            }
    
            public void RemoveObserver(IAccountObserver accountObserver)
            {
                observerList.Remove(accountObserver);
            }
        }
    
        public interface IAccountObserver
        {
            void Update(UserAccountArgs args);
        }
    
        public class Emailer : IAccountObserver
        {
            //public void SendEmail(string to)
            //{
            //    //...
            //}
    
            public void Update(UserAccountArgs args)
            {
                string userEmail = args.UserEmail;
                //...
            }
        }
    
        public class Mobile : IAccountObserver
        {
            //public void SendNotification(string to)
            //{
            //    //...
            //}
    
            public void Update(UserAccountArgs args)
            {
                string mobileNumber = args.MobileNumber;
                //...
            }
        }
    
        public class UserAccountArgs
        {
            public string UserEmail { get; set; }
            public string MobileNumber { get; set; }
        }

    如果BankAccount的变化比较多,可以继续抽象来解除与IAccountObserver的耦合:

        public class BankAccount : Subject
        {
            public void Widthdraw(int data)
            {
                //...
                UserAccountArgs args=new UserAccountArgs();
                //...
                Notify(args);
            }
        }
    
        public abstract class Subject
        {
            IList<IAccountObserver> observerList = new List<IAccountObserver>();
    
            public void Notify(UserAccountArgs args)
            {
                //...
                foreach (var accountObserver in observerList)
                {
                    accountObserver.Update(args);
                }
            }
    
            public void AddObserver(IAccountObserver accountObserver)
            {
                observerList.Add(accountObserver);
            }
    
            public void RemoveObserver(IAccountObserver accountObserver)
            {
                observerList.Remove(accountObserver);
            }
        }

    这时BankAccount就和IAccountObserver解除耦合了。

    演化过程

    当写软件的时候,不一定要套用某个设计模式。为了应对变化,在解耦合的过程中,自然而然就用到了某种模式。

    重要的是松耦合的设计思维。学习设计模式的意义在于深化设计思维。

    结构(Structure)

    Observer模式的几个要点

    • 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
    • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否要订阅通知,目标对象对此一无所知。
    • 在C#的event中,委托充当了Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。

    转载请注明出处:

    作者:JesseLZJ
    出处:http://jesselzj.cnblogs.com

  • 相关阅读:
    VSTS知识整理 荣
    扯淡 荣
    我安装了SQL Server2005后,为什么在IIS的默认站点下面并没有发现Reports? 荣
    ERROR 32000 错误 荣
    vs2012程序打包部署下载InstallShield2015LimitedEdition的下载及安装打包整套教程
    微信小程序之保持登录状态即session不改变
    微信小程序如何调用API实现数据请求wx.request()
    改版kingsmotor.cn用到的参考网站
    第一个css+div网页(太弱智了)
    超级搞笑的笑话
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4773695.html
Copyright © 2011-2022 走看看