码迷,mamicode.com
首页 > 其他好文 > 详细

OO设计模式_观察者模式

时间:2015-01-06 22:56:01      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:

Motivation:


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

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

Intent:

定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生变化,所有依赖于它的对象都得到通知并自动更新。

 

技术分享

 

技术分享

Code:

1.不使用设计模式编程。

    //不使用设计模式编程
    //AMT取钱并且通过终端通知用户账户信息。
    //每出现一个新的终端就需要在BankAccount类中添加一个新的终端类型字段并调用其方法。
    public class ATM
    {
        BankAccount bankAccount;
        void Process(int data)
        {
            bankAccount.Withdraw(data);
        }
    }

    public class BankAccount
    {
        Email emailer;//Strong Dependence
        Mobile mobile;//Strong Dependence
        string userEmail;
        string userPhoneNumber;
        public void Withdraw(int data)
        {
            emailer.SendEmail(userEmail);
            mobile.SendNotification(userPhoneNumber);
        }
    }

    public class Email
    {
        public void SendEmail(string userEmail)
        {
            //...Todo
        }
    }

    public class Mobile
    {
        public void SendNotification(string userPhoneNumber)
        {
            //...Todo
        }
    }

2.观察者模式

//*******************************************
    //观察者模式
    //按照依赖倒置原则
    //观察者抽象成一个interface基类,主题抽象成一个abstract基类,abstract主题基类依赖interface观察者基类,不依赖于具体的观察类。
    public class UserAccountArgs//用户参数:email,phone等terminal信息。
    {
        private string userEmail;

        public string UserEmail
        {
            get { return userEmail; }
            set { userEmail = value; }
        }
        private string userPhoneNumber;
            
        public string UserPhoneNumber
        {
            get { return userPhoneNumber; }
            set { userPhoneNumber = value; }
        }
        
    }
    public abstract class Subject
    {
        private IList<IObserver> observerList = new List<IObserver>();

        public void Attach(IObserver observer)
        {
            observerList.Add(observer);
        }
        public void Detach(IObserver observer)
        {
            observerList.Remove(observer);
        }
        public virtual void Notify(UserAccountArgs args)
        {
            foreach (IObserver observer in observerList)
            {
                observer.Update(args);
            }
        }
    }
    public class BankAccount : Subject
    {
        
        public void Withdraw(int data)
        {
            UserAccountArgs args = new UserAccountArgs();
            Notify(args);
        }
    }

    interface IObserver
    {
        public abstract void Update(UserAccountArgs args);
    }
    public class Emailer : IObserver
    {
        public override void Update(UserAccountArgs args)
        {
            string userEmail = args.UserEmail;
            //...
        }
    }
    public class Mobile : IObserver
    {
        public override void Update(UserAccountArgs args)
        {
            string userPhoneNumber=args.UserPhoneNumber;
            //...
        }
    }
    public class ATM
    {
        UserAccountArgs args = new UserAccountArgs();
        Subject bankAccount = new BankAccount();
        IObserver emailer = new Emailer();
        IObserver mobile = new Emailer();
        void Process()
        {
            bankAccount.Attach(emailer);
            bankAccount.Attach(mobile);
            bankAccount.Notify(args);
        } 
    }

3.事件模式

    //***************************
    //事件模式
    //委托AccountEventHandler方法来实现观察者的方法,主题类不需要依赖IObject类,也不需要知道观察者的方法名。
    public class Emailer
    {
        public void SendEmail(UserAccountArgs args)
        {
            string userEmail = args.UserEmail;
            //...
        }
    }
    public class Mobile 
    {
        public void SendMessage(UserAccountArgs args)
        {
            string userPhoneNumber = args.UserPhoneNumber;
            //...
        }
    }
    public interface Subject
    {
        void Notify(UserAccountArgs args);
    }
    public delegate void AccountEventHandler(UserAccountArgs args);

    public class BankAccount : Subject
    {
        public event AccountEventHandler Update;
        public void Notify(UserAccountArgs args)
        {
            Update(args);
        }
    }
    public class ATM
    {
        UserAccountArgs args = new UserAccountArgs();
        BankAccount bankAccount = new BankAccount();
        Emailer emailer = new Emailer();
        Mobile mobile = new Mobile();
        void Process()
        {
            bankAccount.Update += new AccountEventHandler(emailer.SendEmail);
            bankAccount.Update += new AccountEventHandler(mobile.SendMessage);
            bankAccount.Notify(args);
        }
    }

    public class UserAccountArgs//用户参数:email,phone等terminal信息。
    {
        private string userEmail;

        public string UserEmail
        {
            get { return userEmail; }
            set { userEmail = value; }
        }
        private string userPhoneNumber;

        public string UserPhoneNumber
        {
            get { return userPhoneNumber; }
            set { userPhoneNumber = value; }
        }
    }

Main Point:


使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合。


目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知,目标对象对此一无所知。

在C#的event中,委托充当了抽象的Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。

OO设计模式_观察者模式

标签:

原文地址:http://www.cnblogs.com/xanadu123/p/4207116.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!