• 设计模式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

  • 相关阅读:
    【ABAP系列】SAP 系统的消息类型分析 MESSAGE TYPE
    【FICO系列】SAP FICO-模块 关于固定资产年结和折旧的问题
    【ABAP系列】SAP ABAP 刷新SCREEN的方法
    【ABAP系列】SAP ABAP 控制ALV单元格编辑后获取新的数值
    【ABAP系列】SAP ABAP系统变量及注释
    【EWM系列】SAP EWM凭证对象表概览
    【EWM系列】SAP EWM中仓库任务WT创建的函数
    教你快速录制gif动图
    阿里巴巴的26款超神Java开源项目!
    HTTP和HTTPS协议,看一篇就够了
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4773695.html
Copyright © 2020-2023  润新知