银行办理业务观察者模式解析

Posted yangkae

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了银行办理业务观察者模式解析相关的知识,希望对你有一定的参考价值。

项目链接:https://github.com/stackisok/Design-Pattern/tree/master/src/observer

项目背景:去银行办理业务,当人多的时候,我们要按顺序取号等待。直到银行叫到自己的号时,才轮到自己去进行办理。


观察者模式

  观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

  简单来说,观察者模式就是定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。 

 



 

结构 

观察者模式结构中通常包括观察目标和观察者两个继承层次结构,其结构如图所示:

 

技术分享图片

 

 观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。

 Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。 
ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。 
Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。 
ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。 

 


 

模式解析

 在这个项目中定义了抽象观察者接口(Observer),点击查看Github源码

package observer;

/***
 *
 *@Author ChenjunWang
 *@Description: 观察者接口
 *@Date: Created in 16:10 2018/4/11
 *@Modified By:
 *
 */
public interface Observer {
    void update(String msg);
}

 

 

具体观察者类(Client)如下,点击查看Github源码

 

 

public class Client implements Observer {

    String callNo;
    public Client(String callNo) {
        this.callNo = callNo;
    }

    @Override
    public void update(String msg) {

        if (msg.equals(this.callNo)){
            System.out.println("我是" + callNo + "号客户,现在到我了!");


        } else {
            System.out.println("我是" + callNo + "号客户,现在还没到我了!");
        }
    }
}

 

 

定义抽象主题接口(Subject),点击查看Github源码

 

public interface Subject {
    //注册观察者
    void registerObserver(Observer observer);
    //移除观察者
    void removeObserver(Observer observer);
    //提醒观察者
    void notifyObserver(String msg);
}

 

定义具体主题(BankCallCenter)类,点击查看Github源码

 

public class BankCallCenter implements Subject {
    List<Observer> list = new ArrayList<>();
    @Override
    public void registerObserver(Observer observer) {

        list.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {

        list.remove(observer);
    }

    @Override
    public void notifyObserver(String msg) {


        for (Observer item : list)
            item.update(msg);
    }
}

 

运行结果测试,点击查看源码

 

public class Test {
    public static void main(String[] args) {
        BankCallCenter bankCallCenter = new BankCallCenter();
        Client client = new Client("1");
        bankCallCenter.registerObserver(client);
        Client client2 = new Client("2");
        bankCallCenter.registerObserver(client2);
        Client client3 = new Client("3");
        bankCallCenter.registerObserver(client3);
        System.out.println("----------中心叫一号去办理业务------------");
        bankCallCenter.notifyObserver("1");
        System.out.println("----------从观察者列表中移除一号------------");
        bankCallCenter.removeObserver(client);
        System.out.println("-----------中心叫二号去办理业务-------------");
        bankCallCenter.notifyObserver("2");
        System.out.println("------------从观察者列表中移除二号-----------");

    }

 

银行呼叫项目一共建4个类,其中2个是观察者接口,和被观察者接口,另外2个是实现类,一个银行呼叫中心和取了号的客户。作出银行呼叫项目的UML图,更能看出观察者模式的结构:

技术分享图片

 

 



优缺点

好处:

1.被观察者利用notifyObserver群发消息,银行呼叫项目在update方法中对接受到的消息进行了处理,若收到有用的消息则进行操作。

 2.观察者模式适合一个软件系统要求在某一个对象状态发生变化的时候,某些其他的对象作出相应的改变。观察者模式减少对象之间的耦合有利于系统的复用。

 3.银行项目主体在发送呼叫通知的时候,无须指定具体的客户,Observer可以自己决定是否要订阅Bankcallcenter Subject的通知。

不足:

1.如果一个Bankcenter Subject被大量Client的Observer订阅的话,在呼叫通知的时候可能会有效率问题。 
2.不得不说使用了观察者模式使得银行呼叫项目代码关系变得复杂。





以上是关于银行办理业务观察者模式解析的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之模板方法模式(Template)

c++队列银行业务模拟

Linux下同步模式异步模式阻塞调用非阻塞调用总结

为啥不管多少客户在排队银行总是一两个窗口办业务?

设计模式-模板方法模式

java之命令模式