OO设计模式_观察者模式

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接口更为松耦合的设计。

时间: 2024-10-11 22:32:26

OO设计模式_观察者模式的相关文章

大话设计模式_观察者模式(Java代码)

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们自己能够自动更新自己.简单描述:1个Subject类(可以是抽象类可以是接口),可以有多个具体Subject类(继承抽象Subject),此具体Subject持有多个观察者的引用,在此具体Subject状态发生变化的时候调用这些观察者的相应方法.另外,这些持有的引用是抽象的,不是具体的,而这些引用所指向的对象时具体的观察者(即需要作出更新的具体观察者,这些具体

[设计模式]_[观察者模式在项目中实际使用例子]

场景: 1. 比如在界面开发中,多个窗口之间需要通讯,比较常见的方法就是各个窗口之间包含对其他窗口的引用,之后在需要时通过其他窗口的引用来调用相应的函数获取相应的值: 但是这个确定还是比较明显的,就是会造成窗口之间的依赖和耦合,想想测试或变异某个窗口时另一个窗口必须是没问题的,而另一个窗口编译又依赖它,这样成了反复依赖 导致编译不过或修改其中一个另一个就得相应的该.很麻烦,不好维护. 2. 还有的不切实际的解决办法是在窗口之间发送事件,比如qt得信号或win32的消息,但是这样会造成消息的泛滥,

OO设计模式_工厂方法模式

Motivation在软件系统中,经常面临着“某个对象”的创建工作:由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何应对这种变化?如果提供一种“封装机制”来隔离出“这个异变对象”的变化,从而保持系统中“其他依赖该对象的对象”不随着需求改变而改变. Intent定义一个用于创建对象的接口,让子类决定实例化哪个类.Factory Method使得一个类的实例化延迟到子类. Structure Code 不使用设计模式 class Car { Engine engine

设计模式_观察者模式

Observer Pattern Define a ont-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically.(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并被自动更新) ● Subject被观察者 定义被观察者必须实现的职责,它必须能够动

OO设计模式_抽象工厂模式

Motivation 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求变化,往往存在更多系列对象的创建工作. 如何对应这种变化?如果绕过常规的对象创建方法(New),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合. Intent 提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们的具体的类. Structure Code: abstract class FacilityFactory { abstract Road

OO设计模式_访问者模式

Motivation: 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有的设计. 如果在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题? Intent: 表示一个作用于某个对象结构中各个元素的操作.它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作. Main point: Visitor模式通过所谓双重分发(double

【GOF23设计模式】观察者模式

来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_观察者模式.广播机制.消息订阅.网络游戏对战原理 1 package com.test.observer; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class Subject { 7 protected List<Observer> list = new ArrayList<Observer>(); 8 9 p

设计模式之观察者模式(三)

又和大家见面了.首先,和大家说声抱歉,之前的几篇文章,可能条理清晰之类的做的不太好,每篇文章的篇幅也比较长,小编在收到读者的建议之后, 也是认真的思考了一番.之前的想法是尽量把一个模块介绍完,没想到一个模块写着写着就写长了.在之后的文章里,需要认真分段,做到能简洁就简洁,能分块就分块,在利用大家碎片化的时间里,力争短小精悍又能收获颇丰. 之前的观察者模式,介绍了自己动手编写一套观察者模式,以及使用Java内置的观察者模式来进行实现.分了两篇,并且知道了,观察者模式是基于发布和订阅的,主要由两种模

大话设计模式_备忘录模式(Java代码)

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 简单描述:一个Memento类,代表Originator中要备份的属性.Originator负责生成备份和还原备份,CareTaker负责存储备份 大话设计模式中的截图: 例子代码: Memento类: 1 package com.longsheng.memento; 2 3 public class Memento { 4 5 private String sta