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

  • 相关阅读:
    <转>lua 调用 C函数
    <转>VC之获取CPU序列号
    <转> 求结构体偏移
    借助 FireBug 进行轻量级代码自动生成。
    内存盘配置IIS临时目录
    导出带有复合表头的Excel方案.
    左右互博之精简代码
    [转]JavaScript 秘密花园
    MVC中,Ajax Post 数组的实现方案
    Sql 存储过程 参数传递空字符串, 到SQL 端变成了 空格!!
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4773695.html
Copyright © 2020-2023  润新知